Merge "Fix NPE in onFgsTimeout()." into main
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java
index be4b720..d52c4ce 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java
@@ -36,10 +36,9 @@
 import com.android.server.job.JobSchedulerService;
 import com.android.server.job.StateControllerProto;
 
+import java.util.Comparator;
 import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
+import java.util.PriorityQueue;
 import java.util.function.Predicate;
 
 /**
@@ -64,8 +63,17 @@
     private volatile long mLastFiredDelayExpiredElapsedMillis;
 
     private AlarmManager mAlarmService = null;
-    /** List of tracked jobs, sorted asc. by deadline */
-    private final List<JobStatus> mTrackedJobs = new LinkedList<>();
+
+    /** List of tracked jobs, ordered by deadline (lowest i.e. earliest first) */
+    private final PriorityQueue<JobStatus> mTrackedJobs =
+            new PriorityQueue<>(
+                    new Comparator<JobStatus>() {
+                        public int compare(JobStatus left, JobStatus right) {
+                            return Long.compare(
+                                    left.getLatestRunTimeElapsed(),
+                                    right.getLatestRunTimeElapsed());
+                        }
+                    });
 
     public TimeController(JobSchedulerService service) {
         super(service);
@@ -102,20 +110,7 @@
                 }
             }
 
-            boolean isInsert = false;
-            ListIterator<JobStatus> it = mTrackedJobs.listIterator(mTrackedJobs.size());
-            while (it.hasPrevious()) {
-                JobStatus ts = it.previous();
-                if (ts.getLatestRunTimeElapsed() < job.getLatestRunTimeElapsed()) {
-                    // Insert
-                    isInsert = true;
-                    break;
-                }
-            }
-            if (isInsert) {
-                it.next();
-            }
-            it.add(job);
+            mTrackedJobs.add(job);
 
             job.setTrackingController(JobStatus.TRACKING_TIME);
             WorkSource ws =
@@ -226,7 +221,7 @@
             String nextExpiryPackageName = null;
             final long nowElapsedMillis = sElapsedRealtimeClock.millis();
 
-            ListIterator<JobStatus> it = mTrackedJobs.listIterator();
+            Iterator<JobStatus> it = mTrackedJobs.iterator();
             while (it.hasNext()) {
                 JobStatus job = it.next();
                 if (!job.hasDeadlineConstraint()) {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index dd6bc55..b9906bf 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -84,6 +84,7 @@
 import android.content.res.ApkAssets;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -118,9 +119,11 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.AttributeSet;
 import android.util.LauncherIcons;
 import android.util.Log;
 import android.util.Slog;
+import android.util.Xml;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.Immutable;
@@ -132,6 +135,9 @@
 
 import libcore.util.EmptyArray;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -4090,4 +4096,38 @@
             }
         }
     }
+
+    @Override
+    public TypedArray extractPackageItemInfoAttributes(PackageItemInfo info, String name,
+            String rootTag, int[] attributes) {
+        if (info == null || info.metaData == null) {
+            return null;
+        }
+
+        try (XmlResourceParser parser = info.loadXmlMetaData(this, name)) {
+            if (parser == null) {
+                Log.w(TAG, "No " + name + " metadata");
+                return null;
+            }
+
+            final AttributeSet attrs = Xml.asAttributeSet(parser);
+            while (true) {
+                final int type = parser.next();
+                if (type == XmlPullParser.END_DOCUMENT || type == XmlPullParser.START_TAG) {
+                    break;
+                }
+            }
+
+            if (!TextUtils.equals(parser.getName(), rootTag)) {
+                Log.w(TAG, "Metadata does not start with " + name + " tag");
+                return null;
+            }
+
+            return getResourcesForApplication(info.getApplicationInfo())
+                    .obtainAttributes(attrs, attributes);
+        } catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) {
+            Log.e(TAG, "Error parsing: " + info.packageName, e);
+            return null;
+        }
+    }
 }
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index e812d81..8fe5ae0 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -382,6 +382,10 @@
     @GuardedBy("mListeners")
     private final ArrayList<OnAssociationsChangedListenerProxy> mListeners = new ArrayList<>();
 
+    @GuardedBy("mTransportsChangedListeners")
+    private final ArrayList<OnTransportsChangedListenerProxy> mTransportsChangedListeners =
+            new ArrayList<>();
+
     @GuardedBy("mTransports")
     private final SparseArray<Transport> mTransports = new SparseArray<>();
 
@@ -998,12 +1002,15 @@
             return;
         }
 
-        final OnTransportsChangedListenerProxy proxy = new OnTransportsChangedListenerProxy(
-                executor, listener);
-        try {
-            mService.addOnTransportsChangedListener(proxy);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
+        synchronized (mTransportsChangedListeners) {
+            final OnTransportsChangedListenerProxy proxy = new OnTransportsChangedListenerProxy(
+                    executor, listener);
+            try {
+                mService.addOnTransportsChangedListener(proxy);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+            mTransportsChangedListeners.add(proxy);
         }
     }
 
@@ -1022,12 +1029,20 @@
             return;
         }
 
-        final OnTransportsChangedListenerProxy proxy = new OnTransportsChangedListenerProxy(
-                null, listener);
-        try {
-            mService.removeOnTransportsChangedListener(proxy);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
+        synchronized (mTransportsChangedListeners) {
+            final Iterator<OnTransportsChangedListenerProxy> iterator =
+                    mTransportsChangedListeners.iterator();
+            while (iterator.hasNext()) {
+                final OnTransportsChangedListenerProxy proxy = iterator.next();
+                if (proxy.mListener == listener) {
+                    try {
+                        mService.removeOnTransportsChangedListener(proxy);
+                    } catch (RemoteException e) {
+                        throw e.rethrowFromSystemServer();
+                    }
+                    iterator.remove();
+                }
+            }
         }
     }
 
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index cae4fab..495ae60 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -2700,7 +2700,7 @@
     /**
      * @hide
      */
-    @Override protected ApplicationInfo getApplicationInfo() {
+    @Override public ApplicationInfo getApplicationInfo() {
         return this;
     }
 
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index ff48ffa..4d9ecc4 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -284,7 +284,7 @@
     /**
      * @hide
      */
-    @Override protected ApplicationInfo getApplicationInfo() {
+    @Override public ApplicationInfo getApplicationInfo() {
         return applicationInfo;
     }
 }
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 1f821b9..51285de 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -511,7 +511,7 @@
      *
      * @hide
      */
-    protected ApplicationInfo getApplicationInfo() {
+    public ApplicationInfo getApplicationInfo() {
         return null;
     }
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index f5bff9d..83285e0 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -62,6 +62,7 @@
 import android.content.pm.verify.domain.DomainVerificationManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.Rect;
 import android.graphics.drawable.AdaptiveIconDrawable;
@@ -11743,4 +11744,17 @@
         throw new UnsupportedOperationException(
                 "parseAndroidManifest not implemented in subclass");
     }
+
+    /**
+     * @param info    The {@link ServiceInfo} to pull the attributes from.
+     * @param name    The name of the Xml metadata where the attributes are stored.
+     * @param rootTag The root tag of the attributes.
+     * @return A {@link TypedArray} of attributes if successful, {@code null} otherwise.
+     * @hide
+     */
+    public TypedArray extractPackageItemInfoAttributes(PackageItemInfo info, String name,
+            String rootTag, int[] attributes) {
+        throw new UnsupportedOperationException(
+                "parseServiceMetadata not implemented in subclass");
+    }
 }
diff --git a/core/java/android/hardware/biometrics/BiometricFaceConstants.java b/core/java/android/hardware/biometrics/BiometricFaceConstants.java
index 2ba1d89..ac47c8d 100644
--- a/core/java/android/hardware/biometrics/BiometricFaceConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFaceConstants.java
@@ -34,7 +34,7 @@
  *
  * @hide
  */
-public interface BiometricFaceConstants {
+public class BiometricFaceConstants {
     //
     // Accessibility constants
     //
@@ -43,12 +43,12 @@
      * authentication. Note this is to accommodate people who have limited
      * vision.
      */
-    int FEATURE_REQUIRE_ATTENTION = 1;
+    public static final int FEATURE_REQUIRE_ATTENTION = 1;
     /**
      * Require a diverse set of poses during enrollment. Note this is to
      * accommodate people with limited mobility.
      */
-    int FEATURE_REQUIRE_REQUIRE_DIVERSITY = 2;
+    public static final int FEATURE_REQUIRE_REQUIRE_DIVERSITY = 2;
 
     //
     // Error messages from face authentication hardware during initialization, enrollment,
@@ -75,49 +75,49 @@
             BIOMETRIC_ERROR_POWER_PRESSED,
     })
     @Retention(RetentionPolicy.SOURCE)
-    @interface FaceError {}
+    public @interface FaceError {}
 
     /**
      * The hardware is unavailable. Try again later.
      */
-    int FACE_ERROR_HW_UNAVAILABLE = 1;
+    public static final int FACE_ERROR_HW_UNAVAILABLE = 1;
 
     /**
      * Error state returned when the sensor was unable to process the current image.
      */
-    int FACE_ERROR_UNABLE_TO_PROCESS = 2;
+    public static final int FACE_ERROR_UNABLE_TO_PROCESS = 2;
 
     /**
      * Error state returned when the current request has been running too long. This is intended to
      * prevent programs from waiting for the face authentication sensor indefinitely. The timeout is
      * platform and sensor-specific, but is generally on the order of 30 seconds.
      */
-    int FACE_ERROR_TIMEOUT = 3;
+    public static final int FACE_ERROR_TIMEOUT = 3;
 
     /**
      * Error state returned for operations like enrollment; the operation cannot be completed
      * because there's not enough storage remaining to complete the operation.
      */
-    int FACE_ERROR_NO_SPACE = 4;
+    public static final int FACE_ERROR_NO_SPACE = 4;
 
     /**
      * The operation was canceled because the face authentication sensor is unavailable. For
      * example, this may happen when the user is switched, the device is locked or another pending
      * operation prevents or disables it.
      */
-    int FACE_ERROR_CANCELED = 5;
+    public static final int FACE_ERROR_CANCELED = 5;
 
     /**
      * The {@link FaceManager#remove} call failed. Typically this will happen when the
      * provided face id was incorrect.
      */
-    int FACE_ERROR_UNABLE_TO_REMOVE = 6;
+    public static final int FACE_ERROR_UNABLE_TO_REMOVE = 6;
 
     /**
      * The operation was canceled because the API is locked out due to too many attempts.
      * This occurs after 5 failed attempts, and lasts for 30 seconds.
      */
-    int FACE_ERROR_LOCKOUT = 7;
+    public static final int FACE_ERROR_LOCKOUT = 7;
 
     /**
      * Hardware vendors may extend this list if there are conditions that do not fall under one of
@@ -127,46 +127,46 @@
      * expected to show the error message string if they happen, but are advised not to rely on the
      * message id since they will be device and vendor-specific
      */
-    int FACE_ERROR_VENDOR = 8;
+    public static final int FACE_ERROR_VENDOR = 8;
 
     /**
      * The operation was canceled because FACE_ERROR_LOCKOUT occurred too many times.
      * Face authentication is disabled until the user unlocks with strong authentication
      * (PIN/Pattern/Password)
      */
-    int FACE_ERROR_LOCKOUT_PERMANENT = 9;
+    public static final int FACE_ERROR_LOCKOUT_PERMANENT = 9;
 
     /**
      * The user canceled the operation. Upon receiving this, applications should use alternate
      * authentication (e.g. a password). The application should also provide the means to return
      * to face authentication, such as a "use face authentication" button.
      */
-    int FACE_ERROR_USER_CANCELED = 10;
+    public static final int FACE_ERROR_USER_CANCELED = 10;
 
     /**
      * The user does not have a face enrolled.
      */
-    int FACE_ERROR_NOT_ENROLLED = 11;
+    public static final int FACE_ERROR_NOT_ENROLLED = 11;
 
     /**
      * The device does not have a face sensor. This message will propagate if the calling app
      * ignores the result from PackageManager.hasFeature(FEATURE_FACE) and calls
      * this API anyway. Apps should always check for the feature before calling this API.
      */
-    int FACE_ERROR_HW_NOT_PRESENT = 12;
+    public static final int FACE_ERROR_HW_NOT_PRESENT = 12;
 
     /**
      * The user pressed the negative button. This is a placeholder that is currently only used
      * by the support library.
      */
-    int FACE_ERROR_NEGATIVE_BUTTON = 13;
+    public static final int FACE_ERROR_NEGATIVE_BUTTON = 13;
 
     /**
      * The device does not have pin, pattern, or password set up. See
      * {@link BiometricPrompt.Builder#setDeviceCredentialAllowed(boolean)} and
      * {@link KeyguardManager#isDeviceSecure()}
      */
-    int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14;
+    public static final int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14;
 
     /**
      * A security vulnerability has been discovered and the sensor is unavailable until a
@@ -174,30 +174,30 @@
      * authentication was requested with {@link Authenticators#BIOMETRIC_STRONG}, but the
      * sensor's strength can currently only meet {@link Authenticators#BIOMETRIC_WEAK}.
      */
-    int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 15;
+    public static final int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 15;
 
     /**
      * Authentication cannot proceed because re-enrollment is required.
      */
-    int BIOMETRIC_ERROR_RE_ENROLL = 16;
+    public static final int BIOMETRIC_ERROR_RE_ENROLL = 16;
 
     /**
      * Unknown error received from the HAL.
      */
-    int FACE_ERROR_UNKNOWN = 17;
+    public static final int FACE_ERROR_UNKNOWN = 17;
 
     /**
      * A power press stopped this biometric operation.
      * @hide
      */
-    int BIOMETRIC_ERROR_POWER_PRESSED = 19;
+    public static final int BIOMETRIC_ERROR_POWER_PRESSED = 19;
 
     /**
      * Vendor codes received from the HAL start at 0. Codes that the framework exposes to keyguard
      * append this value for some reason. We should probably remove this and just send the actual
      * vendor code.
      */
-    int FACE_ERROR_VENDOR_BASE = 1000;
+    public static final int FACE_ERROR_VENDOR_BASE = 1000;
 
     //
     // Image acquisition messages. These will not be sent to the user, since they conflict with
@@ -232,18 +232,18 @@
             FACE_ACQUIRED_DARK_GLASSES_DETECTED,
             FACE_ACQUIRED_MOUTH_COVERING_DETECTED})
     @Retention(RetentionPolicy.SOURCE)
-    @interface FaceAcquired {}
+    public @interface FaceAcquired {}
 
     /**
      * The image acquired was good.
      */
-    int FACE_ACQUIRED_GOOD = 0;
+    public static final int FACE_ACQUIRED_GOOD = 0;
 
     /**
      * The face image was not good enough to process due to a detected condition.
      * (See {@link #FACE_ACQUIRED_TOO_BRIGHT or @link #FACE_ACQUIRED_TOO_DARK}).
      */
-    int FACE_ACQUIRED_INSUFFICIENT = 1;
+    public static final int FACE_ACQUIRED_INSUFFICIENT = 1;
 
     /**
      * The face image was too bright due to too much ambient light.
@@ -252,7 +252,7 @@
      * The user is expected to take action to retry in better lighting conditions
      * when this is returned.
      */
-    int FACE_ACQUIRED_TOO_BRIGHT = 2;
+    public static final int FACE_ACQUIRED_TOO_BRIGHT = 2;
 
     /**
      * The face image was too dark due to illumination light obscured.
@@ -261,65 +261,65 @@
      * The user is expected to take action to retry in better lighting conditions
      * when this is returned.
      */
-    int FACE_ACQUIRED_TOO_DARK = 3;
+    public static final int FACE_ACQUIRED_TOO_DARK = 3;
 
     /**
      * The detected face is too close to the sensor, and the image can't be processed.
      * The user should be informed to move farther from the sensor when this is returned.
      */
-    int FACE_ACQUIRED_TOO_CLOSE = 4;
+    public static final int FACE_ACQUIRED_TOO_CLOSE = 4;
 
     /**
      * The detected face is too small, as the user might be too far from the sensor.
      * The user should be informed to move closer to the sensor when this is returned.
      */
-    int FACE_ACQUIRED_TOO_FAR = 5;
+    public static final int FACE_ACQUIRED_TOO_FAR = 5;
 
     /**
      * Only the upper part of the face was detected. The sensor field of view is too high.
      * The user should be informed to move up with respect to the sensor when this is returned.
      */
-    int FACE_ACQUIRED_TOO_HIGH = 6;
+    public static final int FACE_ACQUIRED_TOO_HIGH = 6;
 
     /**
      * Only the lower part of the face was detected. The sensor field of view is too low.
      * The user should be informed to move down with respect to the sensor when this is returned.
      */
-    int FACE_ACQUIRED_TOO_LOW = 7;
+    public static final int FACE_ACQUIRED_TOO_LOW = 7;
 
     /**
      * Only the right part of the face was detected. The sensor field of view is too far right.
      * The user should be informed to move to the right with respect to the sensor
      * when this is returned.
      */
-    int FACE_ACQUIRED_TOO_RIGHT = 8;
+    public static final int FACE_ACQUIRED_TOO_RIGHT = 8;
 
     /**
      * Only the left part of the face was detected. The sensor field of view is too far left.
      * The user should be informed to move to the left with respect to the sensor
      * when this is returned.
      */
-    int FACE_ACQUIRED_TOO_LEFT = 9;
+    public static final int FACE_ACQUIRED_TOO_LEFT = 9;
 
     /**
      * The user's eyes have strayed away from the sensor. If this message is sent, the user should
      * be informed to look at the device. If the user can't be found in the frame, one of the other
      * acquisition messages should be sent, e.g. FACE_ACQUIRED_NOT_DETECTED.
      */
-    int FACE_ACQUIRED_POOR_GAZE = 10;
+    public static final int FACE_ACQUIRED_POOR_GAZE = 10;
 
     /**
      * No face was detected in front of the sensor.
      * The user should be informed to point the sensor to a face when this is returned.
      */
-    int FACE_ACQUIRED_NOT_DETECTED = 11;
+    public static final int FACE_ACQUIRED_NOT_DETECTED = 11;
 
     /**
      * Too much motion was detected.
      * The user should be informed to keep their face steady relative to the
      * sensor.
      */
-    int FACE_ACQUIRED_TOO_MUCH_MOTION = 12;
+    public static final int FACE_ACQUIRED_TOO_MUCH_MOTION = 12;
 
     /**
      * The sensor needs to be re-calibrated. This is an unexpected condition, and should only be
@@ -327,20 +327,20 @@
      * requires user intervention, e.g. re-enrolling. The expected response to this message is to
      * direct the user to re-enroll.
      */
-    int FACE_ACQUIRED_RECALIBRATE = 13;
+    public static final int FACE_ACQUIRED_RECALIBRATE = 13;
 
     /**
      * The face is too different from a previous acquisition. This condition
      * only applies to enrollment. This can happen if the user passes the
      * device to someone else in the middle of enrollment.
      */
-    int FACE_ACQUIRED_TOO_DIFFERENT = 14;
+    public static final int FACE_ACQUIRED_TOO_DIFFERENT = 14;
 
     /**
      * The face is too similar to a previous acquisition. This condition only
      * applies to enrollment. The user should change their pose.
      */
-    int FACE_ACQUIRED_TOO_SIMILAR = 15;
+    public static final int FACE_ACQUIRED_TOO_SIMILAR = 15;
 
     /**
      * The magnitude of the pan angle of the user’s face with respect to the sensor’s
@@ -352,7 +352,7 @@
      *
      * The user should be informed to look more directly at the camera.
      */
-    int FACE_ACQUIRED_PAN_TOO_EXTREME = 16;
+    public static final int FACE_ACQUIRED_PAN_TOO_EXTREME = 16;
 
     /**
      * The magnitude of the tilt angle of the user’s face with respect to the sensor’s
@@ -363,7 +363,7 @@
      *
      * The user should be informed to look more directly at the camera.
      */
-    int FACE_ACQUIRED_TILT_TOO_EXTREME = 17;
+    public static final int FACE_ACQUIRED_TILT_TOO_EXTREME = 17;
 
     /**
      * The magnitude of the roll angle of the user’s face with respect to the sensor’s
@@ -375,7 +375,7 @@
      *
      * The user should be informed to look more directly at the camera.
      */
-    int FACE_ACQUIRED_ROLL_TOO_EXTREME = 18;
+    public static final int FACE_ACQUIRED_ROLL_TOO_EXTREME = 18;
 
     /**
      * The user’s face has been obscured by some object.
@@ -383,7 +383,7 @@
      * The user should be informed to remove any objects from the line of sight from
      * the sensor to the user’s face.
      */
-    int FACE_ACQUIRED_FACE_OBSCURED = 19;
+    public static final int FACE_ACQUIRED_FACE_OBSCURED = 19;
 
     /**
      * This message represents the earliest message sent at the beginning of the authentication
@@ -393,47 +393,47 @@
      * The framework will measure latency based on the time between the last START message and the
      * onAuthenticated callback.
      */
-    int FACE_ACQUIRED_START = 20;
+    public static final int FACE_ACQUIRED_START = 20;
 
     /**
      * The sensor is dirty. The user should be informed to clean the sensor.
      */
-    int FACE_ACQUIRED_SENSOR_DIRTY = 21;
+    public static final int FACE_ACQUIRED_SENSOR_DIRTY = 21;
 
     /**
      * Hardware vendors may extend this list if there are conditions that do not fall under one of
      * the above categories. Vendors are responsible for providing error strings for these errors.
      */
-    int FACE_ACQUIRED_VENDOR = 22;
+    public static final int FACE_ACQUIRED_VENDOR = 22;
 
     /**
      * Unknown acquired code received from the HAL.
      */
-    int FACE_ACQUIRED_UNKNOWN = 23;
+    public static final int FACE_ACQUIRED_UNKNOWN = 23;
 
     /**
      * The first frame from the camera has been received.
      */
-    int FACE_ACQUIRED_FIRST_FRAME_RECEIVED = 24;
+    public static final int FACE_ACQUIRED_FIRST_FRAME_RECEIVED = 24;
 
     /**
      * Dark glasses detected. This can be useful for providing relevant feedback to the user and
      * enabling an alternative authentication logic if the implementation supports it.
      */
-    int FACE_ACQUIRED_DARK_GLASSES_DETECTED = 25;
+    public static final int FACE_ACQUIRED_DARK_GLASSES_DETECTED = 25;
 
     /**
      * A face mask or face covering detected. This can be useful for providing relevant feedback to
      * the user and enabling an alternative authentication logic if the implementation supports it.
      */
-    int FACE_ACQUIRED_MOUTH_COVERING_DETECTED = 26;
+    public static final int FACE_ACQUIRED_MOUTH_COVERING_DETECTED = 26;
 
     /**
      * Vendor codes received from the HAL start at 0. Codes that the framework exposes to keyguard
      * append this value for some reason. We should probably remove this and just send the actual
      * vendor code.
      */
-    int FACE_ACQUIRED_VENDOR_BASE = 1000;
+    public static final int FACE_ACQUIRED_VENDOR_BASE = 1000;
 
 
     /**
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 2592630..d340f3f 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -20,6 +20,44 @@
 import static android.Manifest.permission.MANAGE_BIOMETRIC;
 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_NONE;
+import static android.hardware.biometrics.BiometricFaceConstants.BIOMETRIC_ERROR_RE_ENROLL;
+import static android.hardware.biometrics.BiometricFaceConstants.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_FACE_OBSCURED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_GOOD;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_INSUFFICIENT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_MOUTH_COVERING_DETECTED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_NOT_DETECTED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_PAN_TOO_EXTREME;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_POOR_GAZE;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_RECALIBRATE;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_ROLL_TOO_EXTREME;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_SENSOR_DIRTY;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_START;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TILT_TOO_EXTREME;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_DIFFERENT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_FAR;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_HIGH;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_LEFT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_LOW;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_MUCH_MOTION;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGHT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_SIMILAR;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_VENDOR;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_CANCELED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_NOT_PRESENT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_NOT_ENROLLED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_NO_SPACE;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_USER_CANCELED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_VENDOR;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -29,7 +67,6 @@
 import android.content.pm.PackageManager;
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricConstants;
-import android.hardware.biometrics.BiometricFaceConstants;
 import android.hardware.biometrics.BiometricStateListener;
 import android.hardware.biometrics.CryptoObject;
 import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
@@ -58,7 +95,7 @@
  * @hide
  */
 @SystemService(Context.FACE_SERVICE)
-public class FaceManager implements BiometricAuthenticator, BiometricFaceConstants {
+public class FaceManager implements BiometricAuthenticator {
 
     private static final String TAG = "FaceManager";
 
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
index 02e787b..51758aa 100644
--- a/core/java/android/security/flags.aconfig
+++ b/core/java/android/security/flags.aconfig
@@ -43,6 +43,13 @@
 }
 
 flag {
+    name: "unlocked_storage_api"
+    namespace: "hardware_backed_security"
+    description: "Feature flag for unlocked-only storage API"
+    bug: "325129836"
+}
+
+flag {
     name: "deprecate_fsv_sig"
     namespace: "hardware_backed_security"
     description: "Feature flag for deprecating .fsv_sig"
diff --git a/core/java/android/service/dreams/DreamActivity.java b/core/java/android/service/dreams/DreamActivity.java
index a389223..7487d90 100644
--- a/core/java/android/service/dreams/DreamActivity.java
+++ b/core/java/android/service/dreams/DreamActivity.java
@@ -18,9 +18,12 @@
 
 import android.annotation.Nullable;
 import android.app.Activity;
+import android.content.Intent;
 import android.os.Bundle;
 import android.text.TextUtils;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  * The Activity used by the {@link DreamService} to draw screensaver content
  * on the screen. This activity runs in dream application's process, but is started by a
@@ -41,6 +44,7 @@
  *
  * @hide
  */
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
 public class DreamActivity extends Activity {
     static final String EXTRA_CALLBACK = "binder";
     static final String EXTRA_DREAM_TITLE = "title";
@@ -53,19 +57,55 @@
     public void onCreate(@Nullable Bundle bundle) {
         super.onCreate(bundle);
 
-        final String title = getIntent().getStringExtra(EXTRA_DREAM_TITLE);
+        final String title = getTitle(getIntent());
         if (!TextUtils.isEmpty(title)) {
             setTitle(title);
         }
 
-        final Object callback = getIntent().getExtras().getBinder(EXTRA_CALLBACK);
-        if (callback instanceof DreamService.DreamActivityCallbacks) {
-            mCallback = (DreamService.DreamActivityCallbacks) callback;
-            mCallback.onActivityCreated(this);
-        } else {
-            mCallback = null;
+        mCallback = getCallback(getIntent());
+
+        if (mCallback == null) {
             finishAndRemoveTask();
+            return;
         }
+
+        mCallback.onActivityCreated(this);
+    }
+
+    /**
+     * Sets the title of the dream in the intent for starting the {@link DreamActivity}.
+     */
+    public static void setTitle(Intent intent, CharSequence title) {
+        if (TextUtils.isEmpty(title)) {
+            return;
+        }
+
+        intent.putExtra(DreamActivity.EXTRA_DREAM_TITLE, title);
+    }
+
+    /**
+     * Gets the title of the dream from the intent used to start the {@link DreamActivity}.
+     */
+    public static String getTitle(Intent intent) {
+        return intent.getStringExtra(EXTRA_DREAM_TITLE);
+    }
+
+    /**
+     * Sets the dream callback in the intent for starting the {@link DreamActivity}.
+     */
+    public static void setCallback(Intent intent, DreamService.DreamActivityCallbacks callback) {
+        intent.putExtra(DreamActivity.EXTRA_CALLBACK, callback);
+    }
+
+    /**
+     * Retrieves the dream callback from the intent used to start the {@link DreamActivity}.
+     */
+    public static DreamService.DreamActivityCallbacks getCallback(Intent intent) {
+        final Object binder = intent.getExtras().getBinder(EXTRA_CALLBACK);
+
+        return (binder instanceof DreamService.DreamActivityCallbacks)
+                ? (DreamService.DreamActivityCallbacks) binder
+                : null;
     }
 
     @Override
diff --git a/core/java/android/service/dreams/DreamOverlayConnectionHandler.java b/core/java/android/service/dreams/DreamOverlayConnectionHandler.java
index cafe02a..85a13c7 100644
--- a/core/java/android/service/dreams/DreamOverlayConnectionHandler.java
+++ b/core/java/android/service/dreams/DreamOverlayConnectionHandler.java
@@ -39,7 +39,7 @@
  *
  * @hide
  */
-@VisibleForTesting
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
 public final class DreamOverlayConnectionHandler {
     private static final String TAG = "DreamOverlayConnection";
 
diff --git a/core/java/android/service/dreams/DreamOverlayService.java b/core/java/android/service/dreams/DreamOverlayService.java
index 5da0cb4..17d2790 100644
--- a/core/java/android/service/dreams/DreamOverlayService.java
+++ b/core/java/android/service/dreams/DreamOverlayService.java
@@ -16,6 +16,7 @@
 
 package android.service.dreams;
 
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
@@ -84,7 +85,14 @@
             mService.comeToFront(this);
         }
 
-        private void onExitRequested() {
+        @Override
+        public void onWakeRequested() {
+            if (Flags.dreamWakeRedirect()) {
+                mService.onWakeRequested();
+            }
+        }
+
+        private void requestExit() {
             try {
                 mDreamOverlayCallback.onExitRequested();
             } catch (RemoteException e) {
@@ -92,6 +100,14 @@
             }
         }
 
+        private void redirectWake(boolean redirect) {
+            try {
+                mDreamOverlayCallback.onRedirectWake(redirect);
+            } catch (RemoteException e) {
+                Log.e(TAG, "could not request redirect wake", e);
+            }
+        }
+
         private boolean shouldShowComplications() {
             return mShowComplications;
         }
@@ -229,7 +245,35 @@
             throw new IllegalStateException("requested exit with no dream present");
         }
 
-        mCurrentClient.onExitRequested();
+        mCurrentClient.requestExit();
+    }
+
+    /**
+     * Called to inform the dream to redirect waking to this overlay rather than exiting.
+     * @param redirect {@code true} if waking up should be redirected. {@code false} otherwise.
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_DREAM_WAKE_REDIRECT)
+    public final void redirectWake(boolean redirect) {
+        if (!Flags.dreamWakeRedirect()) {
+            return;
+        }
+
+        if (mCurrentClient == null) {
+            throw new IllegalStateException("redirected wake with no dream present");
+        }
+
+        mCurrentClient.redirectWake(redirect);
+    }
+
+    /**
+     * Invoked when the dream has requested to exit. This is only called if the dream overlay
+     * has explicitly requested exits to be redirected via {@link #redirectWake(boolean)}.
+     *
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_DREAM_WAKE_REDIRECT)
+    public void onWakeRequested() {
     }
 
     /**
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index c26d83c..997c9581 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -41,7 +41,6 @@
 import android.content.pm.ServiceInfo;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Drawable;
 import android.os.Binder;
 import android.os.Build;
@@ -54,11 +53,9 @@
 import android.os.ServiceManager;
 import android.service.controls.flags.Flags;
 import android.service.dreams.utils.DreamAccessibility;
-import android.util.AttributeSet;
 import android.util.Log;
 import android.util.MathUtils;
 import android.util.Slog;
-import android.util.Xml;
 import android.view.ActionMode;
 import android.view.Display;
 import android.view.KeyEvent;
@@ -75,13 +72,10 @@
 import android.view.accessibility.AccessibilityEvent;
 
 import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.DumpUtils;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
 import java.io.FileDescriptor;
-import java.io.IOException;
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -200,13 +194,6 @@
             "android.service.dreams.DreamService";
 
     /**
-     * The name of the extra where the dream overlay component is stored.
-     * @hide
-     */
-    public static final String EXTRA_DREAM_OVERLAY_COMPONENT =
-            "android.service.dream.DreamService.dream_overlay_component";
-
-    /**
      * Name under which a Dream publishes information about itself.
      * This meta-data must reference an XML resource containing
      * a <code>&lt;{@link android.R.styleable#Dream dream}&gt;</code>
@@ -230,6 +217,7 @@
      * The default value for dream category
      * @hide
      */
+    @VisibleForTesting
     public static final int DREAM_CATEGORY_DEFAULT = 0;
 
     /**
@@ -253,8 +241,14 @@
     @Retention(RetentionPolicy.SOURCE)
     @interface DreamCategory {}
 
+    /**
+     * The name of the extra where the dream overlay component is stored.
+     */
+    static final String EXTRA_DREAM_OVERLAY_COMPONENT =
+            "android.service.dream.DreamService.dream_overlay_component";
+
     private final IDreamManager mDreamManager;
-    private final Handler mHandler = new Handler(Looper.getMainLooper());
+    private final Handler mHandler;
     private IBinder mDreamToken;
     private Window mWindow;
     private Activity mActivity;
@@ -287,9 +281,128 @@
 
     private Integer mTrackingConfirmKey = null;
 
+    private boolean mRedirectWake;
+
+    private final Injector mInjector;
+
+    /**
+     * A helper object to inject dependencies into {@link DreamService}.
+     * @hide
+     */
+    @VisibleForTesting
+    public interface Injector {
+        /** Initializes the Injector */
+        void init(Context context);
+
+        /** Creates and returns the dream overlay connection */
+        DreamOverlayConnectionHandler createOverlayConnection(ComponentName overlayComponent);
+
+        /** Returns the {@link DreamActivity} component */
+        ComponentName getDreamActivityComponent();
+
+        /** Returns the dream component */
+        ComponentName getDreamComponent();
+
+        /** Returns the dream package name */
+        String getDreamPackageName();
+
+        /** Returns the {@link DreamManager} */
+        IDreamManager getDreamManager();
+
+        /** Returns the associated service info */
+        ServiceInfo getServiceInfo();
+
+        /** Returns the handler to be used for any posted operation */
+        Handler getHandler();
+
+        /** Returns the package manager */
+        PackageManager getPackageManager();
+
+        /** Returns the resources */
+        Resources getResources();
+    }
+
+    private static final class DefaultInjector implements Injector {
+        private Context mContext;
+        private Class<?> mClassName;
+
+        public void init(Context context) {
+            mContext = context;
+            mClassName = context.getClass();
+        }
+
+        @Override
+        public DreamOverlayConnectionHandler createOverlayConnection(
+                ComponentName overlayComponent) {
+            final Resources resources = mContext.getResources();
+
+            return new DreamOverlayConnectionHandler(
+                    /* context= */ mContext,
+                    Looper.getMainLooper(),
+                    new Intent().setComponent(overlayComponent),
+                    resources.getInteger(R.integer.config_minDreamOverlayDurationMs),
+                    resources.getInteger(R.integer.config_dreamOverlayMaxReconnectAttempts),
+                    resources.getInteger(R.integer.config_dreamOverlayReconnectTimeoutMs));
+        }
+
+        @Override
+        public ComponentName getDreamActivityComponent() {
+            return new ComponentName(mContext, DreamActivity.class);
+        }
+
+        @Override
+        public ComponentName getDreamComponent() {
+            return new ComponentName(mContext, mClassName);
+        }
+
+        @Override
+        public String getDreamPackageName() {
+            return mContext.getApplicationContext().getPackageName();
+        }
+
+        @Override
+        public IDreamManager getDreamManager() {
+            return IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE));
+        }
+
+        @Override
+        public ServiceInfo getServiceInfo() {
+            return fetchServiceInfo(mContext, getDreamComponent());
+        }
+
+        @Override
+        public Handler getHandler() {
+            return new Handler(Looper.getMainLooper());
+        }
+
+        @Override
+        public PackageManager getPackageManager() {
+            return mContext.getPackageManager();
+        }
+
+        @Override
+        public Resources getResources() {
+            return mContext.getResources();
+        }
+
+    }
 
     public DreamService() {
-        mDreamManager = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE));
+        this(new DefaultInjector());
+    }
+
+    /**
+     * Constructor for test purposes.
+     *
+     * @param injector used for providing dependencies
+     * @hide
+     */
+    @VisibleForTesting
+    public DreamService(Injector injector) {
+        mInjector = injector;
+        mInjector.init(this);
+        mDreamManager = mInjector.getDreamManager();
+        mHandler = mInjector.getHandler();
     }
 
     /**
@@ -997,15 +1110,20 @@
     public void onCreate() {
         if (mDebug) Slog.v(mTag, "onCreate()");
 
-        mDreamComponent = new ComponentName(this, getClass());
-        mShouldShowComplications = fetchShouldShowComplications(this /*context*/,
-                fetchServiceInfo(this /*context*/, mDreamComponent));
+        mDreamComponent = mInjector.getDreamComponent();
+        mShouldShowComplications = fetchShouldShowComplications(mInjector.getPackageManager(),
+                mInjector.getServiceInfo());
         mOverlayCallback = new IDreamOverlayCallback.Stub() {
             @Override
             public void onExitRequested() {
                 // Simply finish dream when exit is requested.
                 mHandler.post(() -> finish());
             }
+
+            @Override
+            public void onRedirectWake(boolean redirect) {
+                mRedirectWake = redirect;
+            }
         };
 
         super.onCreate();
@@ -1066,16 +1184,7 @@
 
         // Connect to the overlay service if present.
         if (!mWindowless && overlayComponent != null) {
-            final Resources resources = getResources();
-            final Intent overlayIntent = new Intent().setComponent(overlayComponent);
-
-            mOverlayConnection = new DreamOverlayConnectionHandler(
-                    /* context= */ this,
-                    Looper.getMainLooper(),
-                    overlayIntent,
-                    resources.getInteger(R.integer.config_minDreamOverlayDurationMs),
-                    resources.getInteger(R.integer.config_dreamOverlayMaxReconnectAttempts),
-                    resources.getInteger(R.integer.config_dreamOverlayReconnectTimeoutMs));
+            mOverlayConnection = mInjector.createOverlayConnection(overlayComponent);
 
             if (!mOverlayConnection.bind()) {
                 // Binding failed.
@@ -1181,6 +1290,18 @@
                     + ", mFinished=" + mFinished);
         }
 
+        if (!fromSystem && mOverlayConnection != null && mRedirectWake) {
+            mOverlayConnection.addConsumer(overlay -> {
+                try {
+                    overlay.onWakeRequested();
+                } catch (RemoteException e) {
+                    Log.e(mTag, "could not inform overlay of dream wakeup:" + e);
+                }
+            });
+
+            return;
+        }
+
         if (!mWaking && !mFinished) {
             mWaking = true;
 
@@ -1242,11 +1363,25 @@
     @TestApi
     public static DreamMetadata getDreamMetadata(@NonNull Context context,
             @Nullable ServiceInfo serviceInfo) {
+        return getDreamMetadata(context.getPackageManager(), serviceInfo);
+    }
+
+    /**
+     * Parses and returns metadata of the dream service indicated by the service info. Returns null
+     * if metadata cannot be found.
+     *
+     * Note that {@link ServiceInfo} must be fetched with {@link PackageManager#GET_META_DATA} flag.
+     *
+     * @hide
+     */
+    @Nullable
+    public static DreamMetadata getDreamMetadata(@NonNull PackageManager packageManager,
+            @Nullable ServiceInfo serviceInfo) {
         if (serviceInfo == null) return null;
 
-        final PackageManager pm = context.getPackageManager();
-
-        try (TypedArray rawMetadata = readMetadata(pm, serviceInfo)) {
+        try (TypedArray rawMetadata = packageManager.extractPackageItemInfoAttributes(serviceInfo,
+                DreamService.DREAM_META_DATA, DREAM_META_DATA_ROOT_TAG,
+                com.android.internal.R.styleable.Dream)) {
             if (rawMetadata == null) return null;
             return new DreamMetadata(
                     convertToComponentName(
@@ -1261,47 +1396,6 @@
         }
     }
 
-    /**
-     * Returns the raw XML metadata fetched from the {@link ServiceInfo}.
-     *
-     * Returns <code>null</code> if the {@link ServiceInfo} doesn't contain valid dream metadata.
-     */
-    @Nullable
-    private static TypedArray readMetadata(PackageManager pm, ServiceInfo serviceInfo) {
-        if (serviceInfo == null || serviceInfo.metaData == null) {
-            return null;
-        }
-
-        try (XmlResourceParser parser =
-                     serviceInfo.loadXmlMetaData(pm, DreamService.DREAM_META_DATA)) {
-            if (parser == null) {
-                if (DEBUG) Log.w(TAG, "No " + DreamService.DREAM_META_DATA + " metadata");
-                return null;
-            }
-
-            final AttributeSet attrs = Xml.asAttributeSet(parser);
-            while (true) {
-                final int type = parser.next();
-                if (type == XmlPullParser.END_DOCUMENT || type == XmlPullParser.START_TAG) {
-                    break;
-                }
-            }
-
-            if (!parser.getName().equals(DREAM_META_DATA_ROOT_TAG)) {
-                if (DEBUG) {
-                    Log.w(TAG, "Metadata does not start with " + DREAM_META_DATA_ROOT_TAG + " tag");
-                }
-                return null;
-            }
-
-            return pm.getResourcesForApplication(serviceInfo.applicationInfo).obtainAttributes(
-                    attrs, com.android.internal.R.styleable.Dream);
-        } catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) {
-            if (DEBUG) Log.e(TAG, "Error parsing: " + serviceInfo.packageName, e);
-            return null;
-        }
-    }
-
     @Nullable
     private static ComponentName convertToComponentName(@Nullable String flattenedString,
             ServiceInfo serviceInfo) {
@@ -1406,14 +1500,16 @@
         // for the DreamActivity to report onActivityCreated via
         // DreamServiceWrapper.onActivityCreated.
         if (!mWindowless) {
-            Intent i = new Intent(this, DreamActivity.class);
-            i.setPackage(getApplicationContext().getPackageName());
+            Intent i = new Intent();
+            i.setComponent(mInjector.getDreamActivityComponent());
+            i.setPackage(mInjector.getDreamPackageName());
             i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
-            i.putExtra(DreamActivity.EXTRA_CALLBACK, new DreamActivityCallbacks(mDreamToken));
-            final ServiceInfo serviceInfo = fetchServiceInfo(this,
-                    new ComponentName(this, getClass()));
-            i.putExtra(DreamActivity.EXTRA_DREAM_TITLE,
-                    fetchDreamLabel(this, serviceInfo, isPreviewMode));
+            DreamActivity.setCallback(i, new DreamActivityCallbacks(mDreamToken));
+            final ServiceInfo serviceInfo = mInjector.getServiceInfo();
+            final CharSequence title = fetchDreamLabel(mInjector.getPackageManager(),
+                    mInjector.getResources(), serviceInfo, isPreviewMode);
+
+            DreamActivity.setTitle(i, title);
 
             try {
                 mDreamManager.startDreamActivity(i);
@@ -1539,9 +1635,9 @@
      * the dream should show complications on the overlay. If not defined, returns
      * {@link DreamService#DEFAULT_SHOW_COMPLICATIONS}.
      */
-    private static boolean fetchShouldShowComplications(Context context,
+    private static boolean fetchShouldShowComplications(@NonNull PackageManager packageManager,
             @Nullable ServiceInfo serviceInfo) {
-        final DreamMetadata metadata = getDreamMetadata(context, serviceInfo);
+        final DreamMetadata metadata = getDreamMetadata(packageManager, serviceInfo);
         if (metadata != null) {
             return metadata.showComplications;
         }
@@ -1549,19 +1645,20 @@
     }
 
     @Nullable
-    private static CharSequence fetchDreamLabel(Context context,
+    private static CharSequence fetchDreamLabel(
+            PackageManager pm,
+            Resources resources,
             @Nullable ServiceInfo serviceInfo,
             boolean isPreviewMode) {
         if (serviceInfo == null) {
             return null;
         }
-        final PackageManager pm = context.getPackageManager();
         final CharSequence dreamLabel = serviceInfo.loadLabel(pm);
         if (!isPreviewMode || dreamLabel == null) {
             return dreamLabel;
         }
         // When in preview mode, return a special label indicating the dream is in preview.
-        return context.getResources().getString(R.string.dream_preview_title, dreamLabel);
+        return resources.getString(R.string.dream_preview_title, dreamLabel);
     }
 
     @Nullable
@@ -1643,14 +1740,16 @@
     }
 
     /** @hide */
-    final class DreamActivityCallbacks extends Binder {
+    @VisibleForTesting
+    public final class DreamActivityCallbacks extends Binder {
         private final IBinder mActivityDreamToken;
 
         DreamActivityCallbacks(IBinder token) {
             mActivityDreamToken = token;
         }
 
-        void onActivityCreated(DreamActivity activity) {
+        /** Callback when the {@link DreamActivity} has been created */
+        public void onActivityCreated(DreamActivity activity) {
             if (mActivityDreamToken != mDreamToken || mFinished) {
                 Slog.d(TAG, "DreamActivity was created after the dream was finished or "
                         + "a new dream started, finishing DreamActivity");
@@ -1672,8 +1771,8 @@
             onWindowCreated(activity.getWindow());
         }
 
-        // If DreamActivity is destroyed, wake up from Dream.
-        void onActivityDestroyed() {
+        /** Callback when the {@link DreamActivity} has been destroyed */
+        public void onActivityDestroyed() {
             mActivity = null;
             mWindow = null;
             detach();
@@ -1685,6 +1784,7 @@
      *
      * @hide
      */
+    @VisibleForTesting
     @TestApi
     public static final class DreamMetadata {
         @Nullable
@@ -1700,7 +1800,11 @@
         @FlaggedApi(Flags.FLAG_HOME_PANEL_DREAM)
         public final int dreamCategory;
 
-        DreamMetadata(
+        /**
+         * @hide
+         */
+        @VisibleForTesting
+        public DreamMetadata(
                 ComponentName settingsActivity,
                 Drawable previewImage,
                 boolean showComplications,
@@ -1715,4 +1819,14 @@
             }
         }
     }
+
+    /**
+     * Sets the dream overlay component to be used by the dream.
+     *
+     * @hide
+     */
+    @VisibleForTesting
+    public static void setDreamOverlayComponent(Intent intent, ComponentName component) {
+        intent.putExtra(DreamService.EXTRA_DREAM_OVERLAY_COMPONENT, component);
+    }
 }
diff --git a/core/java/android/service/dreams/IDreamOverlayCallback.aidl b/core/java/android/service/dreams/IDreamOverlayCallback.aidl
index ec76a33..fae4780 100644
--- a/core/java/android/service/dreams/IDreamOverlayCallback.aidl
+++ b/core/java/android/service/dreams/IDreamOverlayCallback.aidl
@@ -23,9 +23,14 @@
 *
 * @hide
 */
-interface IDreamOverlayCallback {
+oneway interface IDreamOverlayCallback {
     /**
     * Invoked to request the dream exit.
     */
     void onExitRequested();
+
+    /**
+    * Invoked to redirect wake requests to overlay instead.
+    */
+    void onRedirectWake(boolean redirect);
 }
\ No newline at end of file
diff --git a/core/java/android/service/dreams/IDreamOverlayClient.aidl b/core/java/android/service/dreams/IDreamOverlayClient.aidl
index 5054d4d..0eb15a0 100644
--- a/core/java/android/service/dreams/IDreamOverlayClient.aidl
+++ b/core/java/android/service/dreams/IDreamOverlayClient.aidl
@@ -43,6 +43,9 @@
     /** Called when the dream has ended. */
     void endDream();
 
+    /** Called when wake up has been redirected to the overlay. */
+    void onWakeRequested();
+
     /** Called when the dream is coming to the front. */
     void comeToFront();
 }
diff --git a/core/java/android/service/dreams/flags.aconfig b/core/java/android/service/dreams/flags.aconfig
index 0a458bc..f87cb85 100644
--- a/core/java/android/service/dreams/flags.aconfig
+++ b/core/java/android/service/dreams/flags.aconfig
@@ -21,6 +21,14 @@
 }
 
 flag {
+  name: "dream_wake_redirect"
+  namespace: "systemui"
+  description: "This flag enables using a host to handle displaying a dream's overlay rather than "
+      "relying on the dream's window"
+  bug: "334083490"
+}
+
+flag {
   name: "dream_tracks_focus"
   namespace: "communal"
   description: "This flag enables the ability for dreams to track whether or not they have focus"
diff --git a/core/java/android/view/IRecentsAnimationController.aidl b/core/java/android/view/IRecentsAnimationController.aidl
index a150187..55ad4ae 100644
--- a/core/java/android/view/IRecentsAnimationController.aidl
+++ b/core/java/android/view/IRecentsAnimationController.aidl
@@ -17,11 +17,13 @@
 package android.view;
 
 import android.app.ActivityManager;
-import android.view.IRemoteAnimationFinishedCallback;
-import android.view.SurfaceControl;
 import android.graphics.GraphicBuffer;
+import android.view.IRemoteAnimationFinishedCallback;
+import android.view.RemoteAnimationTarget;
+import android.view.SurfaceControl;
 import android.window.PictureInPictureSurfaceTransaction;
 import android.window.TaskSnapshot;
+import android.window.WindowAnimationState;
 
 import com.android.internal.os.IResultReceiver;
 
@@ -160,4 +162,17 @@
      * @param duration the duration of the app launch animation
      */
     void animateNavigationBarToApp(long duration);
+
+    /**
+     * Hand off the ongoing animation of a set of remote targets, to be run by another handler using
+     * the given starting parameters.
+     *
+     * Once the handoff is complete, operations on the old leashes for the given targets as well as
+     * callbacks will become no-ops.
+     *
+     * The number of targets MUST match the number of states, and each state MUST match the target
+     * at the same index.
+     */
+    oneway void handOffAnimation(in RemoteAnimationTarget[] targets,
+                    in WindowAnimationState[] states);
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 510a4a3..e7c1885 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2430,12 +2430,6 @@
     public static final int FRAME_RATE_CATEGORY_REASON_VELOCITY = 0x0600_0000;
 
     /**
-     * This indicates that the frame rate category was chosen because it is idle.
-     * @hide
-     */
-    public static final int FRAME_RATE_CATEGORY_REASON_IDLE = 0x0700_0000;
-
-    /**
      * This indicates that the frame rate category was chosen because it is currently boosting.
      * @hide
      */
@@ -4745,6 +4739,11 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     protected int mLeft;
     /**
+     * The mLeft from the previous frame. Used for detecting movement for purposes of variable
+     * refresh rate.
+     */
+    private int mLastFrameLeft;
+    /**
      * The distance in pixels from the left edge of this view's parent
      * to the right edge of this view.
      * {@hide}
@@ -4761,6 +4760,11 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     protected int mTop;
     /**
+     * The mTop from the previous frame. Used for detecting movement for purposes of variable
+     * refresh rate.
+     */
+    private int mLastFrameTop;
+    /**
      * The distance in pixels from the top edge of this view's parent
      * to the bottom edge of this view.
      * {@hide}
@@ -19535,7 +19539,6 @@
      */
     public final void setTop(int top) {
         if (top != mTop) {
-            mPrivateFlags4 |= PFLAG4_HAS_MOVED;
             final boolean matrixIsIdentity = hasIdentityMatrix();
             if (matrixIsIdentity) {
                 if (mAttachInfo != null) {
@@ -20427,7 +20430,6 @@
      */
     public void offsetTopAndBottom(int offset) {
         if (offset != 0) {
-            mPrivateFlags4 |= PFLAG4_HAS_MOVED;
             final boolean matrixIsIdentity = hasIdentityMatrix();
             if (matrixIsIdentity) {
                 if (isHardwareAccelerated()) {
@@ -20479,7 +20481,6 @@
      */
     public void offsetLeftAndRight(int offset) {
         if (offset != 0) {
-            mPrivateFlags4 |= PFLAG4_HAS_MOVED;
             final boolean matrixIsIdentity = hasIdentityMatrix();
             if (matrixIsIdentity) {
                 if (isHardwareAccelerated()) {
@@ -25523,7 +25524,6 @@
         }
 
         if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {
-            mPrivateFlags4 |= PFLAG4_HAS_MOVED;
             changed = true;
 
             // Remember our drawn bit
@@ -33976,8 +33976,9 @@
             // The most common case is when nothing is set, so this special case is called
             // often.
             if (mAttachInfo.mViewVelocityApi
-                    && (mPrivateFlags4 & (PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)) == (
-                    PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)
+                    && ((mPrivateFlags4 & (PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)) == (
+                    PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN) || mLastFrameLeft != mLeft
+                    || mLastFrameTop != mTop)
                     && viewRootImpl.shouldCheckFrameRate(false)
                     && parent instanceof View
                     && ((View) parent).mFrameContentVelocity <= 0) {
@@ -33990,14 +33991,17 @@
                 viewRootImpl.votePreferredFrameRateCategory(category, reason, this);
                 mLastFrameRateCategory = frameRateCategory;
             }
+            mLastFrameLeft = mLeft;
+            mLastFrameTop = mTop;
             return;
         }
         if (viewRootImpl.shouldCheckFrameRate(frameRate > 0f)) {
             float velocityFrameRate = 0f;
             if (mAttachInfo.mViewVelocityApi) {
                 if (velocity < 0f
-                        && (mPrivateFlags4 & (PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)) == (
-                        PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)
+                        && ((mPrivateFlags4 & (PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)) == (
+                        PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN) || mLastFrameLeft != mLeft
+                        || mLastFrameTop != mTop)
                         && mParent instanceof View
                         && ((View) mParent).mFrameContentVelocity <= 0
                 ) {
@@ -34062,6 +34066,8 @@
             viewRootImpl.votePreferredFrameRateCategory(category, reason, this);
             mLastFrameRateCategory = frameRateCategory;
         }
+        mLastFrameLeft = mLeft;
+        mLastFrameTop = mTop;
     }
 
     private float convertVelocityToFrameRate(float velocityPps) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 701b2d3..2cb862c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -37,7 +37,6 @@
 import static android.view.Surface.FRAME_RATE_COMPATIBILITY_GTE;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_BOOST;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_CONFLICTED;
-import static android.view.View.FRAME_RATE_CATEGORY_REASON_IDLE;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_INTERMITTENT;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_INVALID;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_LARGE;
@@ -1088,16 +1087,10 @@
     // The last preferred frame rate of the view that is mainly used to
     // track the difference between the current preferred frame rate and the previous value.
     private float mLastPreferredFrameRate = 0;
-    // Used to check if there were any view invalidations in
-    // the previous time frame (FRAME_RATE_IDLENESS_REEVALUATE_TIME).
-    private boolean mHasInvalidation = false;
     // Used to check if it is in the frame rate boosting period.
     private boolean mIsFrameRateBoosting = false;
     // Used to check if it is in touch boosting period.
     private boolean mIsTouchBoosting = false;
-    // Used to check if there is a message in the message queue
-    // for idleness handling.
-    private boolean mHasIdledMessage = false;
     private boolean mDrawnThisFrame = false;
     // Used to check if there is a conflict between different frame rate voting.
     // Take 24 and 30 as an example, 24 is not a divisor of 30.
@@ -1108,10 +1101,6 @@
             FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
     // time for touch boost period.
     private static final int FRAME_RATE_TOUCH_BOOST_TIME = 3000;
-    // time for checking idle status periodically.
-    private static final int FRAME_RATE_IDLENESS_CHECK_TIME_MILLIS = 500;
-    // time for revaluating the idle status before lowering the frame rate.
-    private static final int FRAME_RATE_IDLENESS_REEVALUATE_TIME = 1000;
     // time for evaluating the interval between current time and
     // the time when frame rate was set previously.
     private static final int FRAME_RATE_SETTING_REEVALUATE_TIME = 100;
@@ -4263,7 +4252,6 @@
                 mHandler.sendEmptyMessageDelayed(MSG_FRAME_RATE_SETTING,
                         FRAME_RATE_SETTING_REEVALUATE_TIME);
             }
-            checkIdleness();
             mFrameRateCategoryHighCount = mFrameRateCategoryHighCount > 0
                     ? mFrameRateCategoryHighCount - 1 : mFrameRateCategoryHighCount;
             mFrameRateCategoryNormalCount = mFrameRateCategoryNormalCount > 0
@@ -6445,8 +6433,6 @@
                     return "MSG_REFRESH_POINTER_ICON";
                 case MSG_TOUCH_BOOST_TIMEOUT:
                     return "MSG_TOUCH_BOOST_TIMEOUT";
-                case MSG_CHECK_INVALIDATION_IDLE:
-                    return "MSG_CHECK_INVALIDATION_IDLE";
                 case MSG_FRAME_RATE_SETTING:
                     return "MSG_FRAME_RATE_SETTING";
             }
@@ -6714,27 +6700,6 @@
                     mIsFrameRateBoosting = false;
                     mIsTouchBoosting = false;
                     break;
-                case MSG_CHECK_INVALIDATION_IDLE:
-                    if (!mHasInvalidation && !mIsFrameRateBoosting && !mIsTouchBoosting) {
-                        mPreferredFrameRateCategory = FRAME_RATE_CATEGORY_NO_PREFERENCE;
-                        mFrameRateCategoryChangeReason = FRAME_RATE_CATEGORY_REASON_IDLE;
-                        mFrameRateCategoryView = null;
-                        setPreferredFrameRateCategory(mPreferredFrameRateCategory);
-                        mHasIdledMessage = false;
-                    } else {
-                        /**
-                         * If there is no invalidation within a certain period,
-                         * we consider the display is idled.
-                         * We then set the frame rate catetogry to NO_PREFERENCE.
-                         * Note that SurfaceFlinger also has a mechanism to lower the refresh rate
-                         * if there is no updates of the buffer.
-                         */
-                        mHasInvalidation = false;
-                        mHandler.sendEmptyMessageDelayed(MSG_CHECK_INVALIDATION_IDLE,
-                                FRAME_RATE_IDLENESS_REEVALUATE_TIME);
-                        mHasIdledMessage = true;
-                    }
-                    break;
                 case MSG_REFRESH_POINTER_ICON:
                     if (mPointerIconEvent == null) {
                         break;
@@ -6744,7 +6709,6 @@
                 case MSG_FRAME_RATE_SETTING:
                     mPreferredFrameRate = 0;
                     mFrameRateCompatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
-                    setPreferredFrameRate(mPreferredFrameRate);
                     break;
             }
         }
@@ -12649,7 +12613,6 @@
             case FRAME_RATE_CATEGORY_REASON_REQUESTED -> str = "requested";
             case FRAME_RATE_CATEGORY_REASON_INVALID -> str = "invalid frame rate";
             case FRAME_RATE_CATEGORY_REASON_VELOCITY -> str = "velocity";
-            case FRAME_RATE_CATEGORY_REASON_IDLE -> str = "idle";
             case FRAME_RATE_CATEGORY_REASON_UNKNOWN -> str = "unknown";
             case FRAME_RATE_CATEGORY_REASON_BOOST -> str = "boost";
             case FRAME_RATE_CATEGORY_REASON_TOUCH -> str = "touch";
@@ -12718,7 +12681,6 @@
             mFrameRateCategoryChangeReason = reason;
             // mFrameRateCategoryView = view == null ? "-" : view.getClass().getSimpleName();
         }
-        mHasInvalidation = true;
         mDrawnThisFrame = true;
     }
 
@@ -12792,7 +12754,6 @@
                 mFrameRateCategoryHighCount = FRAME_RATE_CATEGORY_COUNT;
                 mFrameRateCategoryChangeReason = FRAME_RATE_CATEGORY_REASON_VELOCITY;
                 mFrameRateCategoryView = null;
-                mHasInvalidation = true;
                 mDrawnThisFrame = true;
                 return;
             }
@@ -12824,7 +12785,6 @@
 
         mPreferredFrameRate = nextFrameRate;
         mFrameRateCompatibility = nextFrameRateCompatibility;
-        mHasInvalidation = true;
         mDrawnThisFrame = true;
     }
 
@@ -12944,19 +12904,8 @@
         return false;
     }
 
-    private void checkIdleness() {
-        if (!mHasIdledMessage) {
-            // Check where the display is idled periodically.
-            // If so, set the frame rate category to NO_PREFERENCE
-            mHandler.sendEmptyMessageDelayed(MSG_CHECK_INVALIDATION_IDLE,
-                    FRAME_RATE_IDLENESS_CHECK_TIME_MILLIS);
-            mHasIdledMessage = true;
-        }
-    }
-
     private void removeVrrMessages() {
         mHandler.removeMessages(MSG_TOUCH_BOOST_TIMEOUT);
-        mHandler.removeMessages(MSG_CHECK_INVALIDATION_IDLE);
         mHandler.removeMessages(MSG_FRAME_RATE_SETTING);
     }
 
@@ -12976,7 +12925,8 @@
         mMinusOneFrameIntervalMillis = timeIntervalMillis;
 
         mLastUpdateTimeMillis = currentTimeMillis;
-        if (timeIntervalMillis >= INFREQUENT_UPDATE_INTERVAL_MILLIS) {
+        if (timeIntervalMillis + mMinusTwoFrameIntervalMillis
+                >= INFREQUENT_UPDATE_INTERVAL_MILLIS) {
             int infrequentUpdateCount = mInfrequentUpdateCount;
             mInfrequentUpdateCount = infrequentUpdateCount == INFREQUENT_UPDATE_COUNTS
                     ? infrequentUpdateCount : infrequentUpdateCount + 1;
diff --git a/core/java/android/window/BackNavigationInfo.java b/core/java/android/window/BackNavigationInfo.java
index b1cf834..f24bc74 100644
--- a/core/java/android/window/BackNavigationInfo.java
+++ b/core/java/android/window/BackNavigationInfo.java
@@ -22,6 +22,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
+import android.graphics.Color;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -111,6 +112,8 @@
     @Nullable
     private final CustomAnimationInfo mCustomAnimationInfo;
 
+    private final int mLetterboxColor;
+
     /**
      * Create a new {@link BackNavigationInfo} instance.
      *
@@ -124,13 +127,15 @@
             @Nullable IOnBackInvokedCallback onBackInvokedCallback,
             boolean isPrepareRemoteAnimation,
             boolean isAnimationCallback,
-            @Nullable CustomAnimationInfo customAnimationInfo) {
+            @Nullable CustomAnimationInfo customAnimationInfo,
+            int letterboxColor) {
         mType = type;
         mOnBackNavigationDone = onBackNavigationDone;
         mOnBackInvokedCallback = onBackInvokedCallback;
         mPrepareRemoteAnimation = isPrepareRemoteAnimation;
         mAnimationCallback = isAnimationCallback;
         mCustomAnimationInfo = customAnimationInfo;
+        mLetterboxColor = letterboxColor;
     }
 
     private BackNavigationInfo(@NonNull Parcel in) {
@@ -140,6 +145,7 @@
         mPrepareRemoteAnimation = in.readBoolean();
         mAnimationCallback = in.readBoolean();
         mCustomAnimationInfo = in.readTypedObject(CustomAnimationInfo.CREATOR);
+        mLetterboxColor = in.readInt();
     }
 
     /** @hide */
@@ -151,6 +157,7 @@
         dest.writeBoolean(mPrepareRemoteAnimation);
         dest.writeBoolean(mAnimationCallback);
         dest.writeTypedObject(mCustomAnimationInfo, flags);
+        dest.writeInt(mLetterboxColor);
     }
 
     /**
@@ -193,6 +200,13 @@
     }
 
     /**
+     * @return Letterbox color
+     * @hide
+     */
+    public int getLetterboxColor() {
+        return mLetterboxColor;
+    }
+    /**
      * Callback to be called when the back preview is finished in order to notify the server that
      * it can clean up the resources created for the animation.
      * @hide
@@ -387,6 +401,8 @@
         private CustomAnimationInfo mCustomAnimationInfo;
         private boolean mAnimationCallback = false;
 
+        private int mLetterboxColor = Color.TRANSPARENT;
+
         /**
          * @see BackNavigationInfo#getType()
          */
@@ -454,6 +470,14 @@
         }
 
         /**
+         * @param color Non-transparent if there contain letterbox color.
+         */
+        public Builder setLetterboxColor(int color) {
+            mLetterboxColor = color;
+            return this;
+        }
+
+        /**
          * Builds and returns an instance of {@link BackNavigationInfo}
          */
         public BackNavigationInfo build() {
@@ -461,7 +485,8 @@
                     mOnBackInvokedCallback,
                     mPrepareRemoteAnimation,
                     mAnimationCallback,
-                    mCustomAnimationInfo);
+                    mCustomAnimationInfo,
+                    mLetterboxColor);
         }
     }
 }
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 87c47da..ee3e34f 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -152,4 +152,15 @@
   metadata {
       purpose: PURPOSE_BUGFIX
   }
+}
+
+flag {
+  name: "get_dimmer_on_closing"
+  namespace: "windowing_frontend"
+  description: "Change check for when to ignore a closing task's dim"
+  bug: "329233513"
+  is_fixed_read_only: true
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
 }
\ No newline at end of file
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 4f55441..d72207d 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -272,6 +272,7 @@
                 getOpenInWorkMessage(launchIntent, target.loadLabel(packageManagerForTargetUser)),
                 packageManagerForTargetUser);
 
+        ((Button) findViewById(R.id.button_open)).setText(getOpenInWorkButtonString(launchIntent));
 
         View telephonyInfo = findViewById(R.id.miniresolver_info_section);
 
@@ -310,7 +311,15 @@
                 packageManagerForTargetUser);
 
         View telephonyInfo = findViewById(R.id.miniresolver_info_section);
-        telephonyInfo.setVisibility(View.GONE);
+        telephonyInfo.setVisibility(View.VISIBLE);
+
+        if (isTextMessageIntent(launchIntent)) {
+            ((TextView) findViewById(R.id.miniresolver_info_section_text)).setText(
+                    R.string.miniresolver_private_space_messages_information);
+        } else {
+            ((TextView) findViewById(R.id.miniresolver_info_section_text)).setText(
+                    R.string.miniresolver_private_space_phone_information);
+        }
     }
 
     private void buildMiniResolver(ResolveInfo target, Intent launchIntent, int targetUserId,
@@ -334,7 +343,6 @@
         ((Button) findViewById(R.id.use_same_profile_browser)).setText(R.string.cancel);
         findViewById(R.id.use_same_profile_browser).setOnClickListener(v -> finish());
 
-        ((Button) findViewById(R.id.button_open)).setText(getOpenInWorkButtonString(launchIntent));
         findViewById(R.id.button_open).setOnClickListener(v -> {
             startActivityAsCaller(
                     launchIntent,
diff --git a/core/java/com/android/internal/compat/ChangeReporter.java b/core/java/com/android/internal/compat/ChangeReporter.java
index 6ff546f..ded142c 100644
--- a/core/java/com/android/internal/compat/ChangeReporter.java
+++ b/core/java/com/android/internal/compat/ChangeReporter.java
@@ -18,22 +18,24 @@
 
 import static android.text.TextUtils.formatSimple;
 
+import static java.util.Collections.EMPTY_SET;
+
 import android.annotation.IntDef;
 import android.util.Log;
 import android.util.Slog;
 
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.compat.flags.Flags;
 import com.android.internal.util.FrameworkStatsLog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.HashMap;
+import java.util.Collections;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
 
 /**
  * A helper class to report changes to stats log.
@@ -42,6 +44,8 @@
  */
 public final class ChangeReporter {
     private static final String TAG = "CompatChangeReporter";
+    private static final Function<Integer, Set<ChangeReport>> NEW_CHANGE_REPORT_SET =
+            uid -> Collections.synchronizedSet(new HashSet<>());
     private int mSource;
 
     private static final class ChangeReport {
@@ -69,15 +73,14 @@
     }
 
     // Maps uid to a set of ChangeReports (that were reported for that uid).
-    @GuardedBy("mReportedChanges")
-    private final Map<Integer, Set<ChangeReport>> mReportedChanges;
+    private final ConcurrentHashMap<Integer, Set<ChangeReport>> mReportedChanges;
 
     // When true will of every time to debug (logcat).
     private boolean mDebugLogAll;
 
     public ChangeReporter(@Source int source) {
         mSource = source;
-        mReportedChanges =  new HashMap<>();
+        mReportedChanges =  new ConcurrentHashMap<>();
         mDebugLogAll = false;
     }
 
@@ -93,14 +96,15 @@
      *                        actually log. If the sdk version does not matter, should be true.
      */
     public void reportChange(int uid, long changeId, int state, boolean isLoggableBySdk) {
-        if (shouldWriteToStatsLog(uid, changeId, state)) {
+        boolean isAlreadyReported =
+                checkAndSetIsAlreadyReported(uid, new ChangeReport(changeId, state));
+        if (!isAlreadyReported) {
             FrameworkStatsLog.write(FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid,
                     changeId, state, mSource);
         }
-        if (shouldWriteToDebug(uid, changeId, state, isLoggableBySdk)) {
+        if (shouldWriteToDebug(isAlreadyReported, state, isLoggableBySdk)) {
             debugLog(uid, changeId, state);
         }
-        markAsReported(uid, new ChangeReport(changeId, state));
     }
 
     /**
@@ -129,7 +133,6 @@
         mDebugLogAll = false;
     }
 
-
     /**
      * Returns whether the next report should be logged to FrameworkStatsLog.
      *
@@ -139,28 +142,26 @@
      * @return true if the report should be logged
      */
     @VisibleForTesting
-    public boolean shouldWriteToStatsLog(int uid, long changeId, int state) {
+    boolean shouldWriteToStatsLog(int uid, long changeId, int state) {
         return !isAlreadyReported(uid, new ChangeReport(changeId, state));
     }
 
     /**
      * Returns whether the next report should be logged to logcat.
      *
-     * @param uid             affected by the change
-     * @param changeId        the reported change id
-     * @param state           of the reported change - enabled/disabled/only logged
-     * @param isLoggableBySdk whether debug logging is allowed for this change based on target
-     *                        SDK version. This is combined with other logic to determine whether to
-     *                        actually log. If the sdk version does not matter, should be true.
+     * @param isAlreadyReported is the change already reported
+     * @param state             of the reported change - enabled/disabled/only logged
+     * @param isLoggableBySdk   whether debug logging is allowed for this change based on target SDK
+     *                          version. This is combined with other logic to determine whether to
+     *                          actually log. If the sdk version does not matter, should be true.
      * @return true if the report should be logged
      */
-    @VisibleForTesting
-    public boolean shouldWriteToDebug(
-            int uid, long changeId, int state, boolean isLoggableBySdk) {
+    private boolean shouldWriteToDebug(
+            boolean isAlreadyReported, int state, boolean isLoggableBySdk) {
         // If log all bit is on, always return true.
         if (mDebugLogAll) return true;
         // If the change has already been reported, do not write.
-        if (isAlreadyReported(uid, new ChangeReport(changeId, state))) return false;
+        if (isAlreadyReported) return false;
 
         // If the flag is turned off or the TAG's logging is forced to debug level with
         // `adb setprop log.tag.CompatChangeReporter=DEBUG`, write to debug since the above checks
@@ -178,33 +179,53 @@
      * @param uid         affected by the change
      * @param changeId    the reported change id
      * @param state       of the reported change - enabled/disabled/only logged
+     *
      * @return true if the report should be logged
      */
     @VisibleForTesting
-    public boolean shouldWriteToDebug(int uid, long changeId, int state) {
+    boolean shouldWriteToDebug(int uid, long changeId, int state) {
         return shouldWriteToDebug(uid, changeId, state, true);
     }
 
-    private boolean isAlreadyReported(int uid, ChangeReport report) {
-        synchronized (mReportedChanges) {
-            Set<ChangeReport> reportedChangesForUid = mReportedChanges.get(uid);
-            if (reportedChangesForUid == null) {
-                return false;
-            } else {
-                return reportedChangesForUid.contains(report);
-            }
+    /**
+     * Returns whether the next report should be logged to logcat.
+     *
+     * @param uid               affected by the change
+     * @param changeId          the reported change id
+     * @param state             of the reported change - enabled/disabled/only logged
+     * @param isLoggableBySdk   whether debug logging is allowed for this change based on target SDK
+     *                          version. This is combined with other logic to determine whether to
+     *                          actually log. If the sdk version does not matter, should be true.
+     * @return true if the report should be logged
+     */
+    @VisibleForTesting
+    boolean shouldWriteToDebug(int uid, long changeId, int state, boolean isLoggableBySdk) {
+        return shouldWriteToDebug(
+                isAlreadyReported(uid, new ChangeReport(changeId, state)), state, isLoggableBySdk);
+    }
+
+    /**
+     * Return if change has been reported. Also mark change as reported if not.
+     *
+     * @param uid affected by the change
+     * @param changeReport change reported to be checked and marked as reported.
+     *
+     * @return true if change has been reported, and vice versa.
+     */
+    private boolean checkAndSetIsAlreadyReported(int uid, ChangeReport changeReport) {
+        boolean isAlreadyReported = isAlreadyReported(uid, changeReport);
+        if (!isAlreadyReported) {
+            markAsReported(uid, changeReport);
         }
+        return isAlreadyReported;
+    }
+
+    private boolean isAlreadyReported(int uid, ChangeReport report) {
+        return mReportedChanges.getOrDefault(uid, EMPTY_SET).contains(report);
     }
 
     private void markAsReported(int uid, ChangeReport report) {
-        synchronized (mReportedChanges) {
-            Set<ChangeReport> reportedChangesForUid = mReportedChanges.get(uid);
-            if (reportedChangesForUid == null) {
-                mReportedChanges.put(uid, new HashSet<ChangeReport>());
-                reportedChangesForUid = mReportedChanges.get(uid);
-            }
-            reportedChangesForUid.add(report);
-        }
+        mReportedChanges.computeIfAbsent(uid, NEW_CHANGE_REPORT_SET).add(report);
     }
 
     /**
@@ -216,9 +237,7 @@
      * @param uid to reset
      */
     public void resetReportedChanges(int uid) {
-        synchronized (mReportedChanges) {
-            mReportedChanges.remove(uid);
-        }
+        mReportedChanges.remove(uid);
     }
 
     private void debugLog(int uid, long changeId, int state) {
@@ -229,7 +248,6 @@
         } else {
             Log.d(TAG, message);
         }
-
     }
 
     /**
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index 5705b7e..7ac553c 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -48,8 +48,6 @@
 public abstract class PackageMonitor extends android.content.BroadcastReceiver {
     static final String TAG = "PackageMonitor";
 
-    final IntentFilter mPackageFilt;
-
     Context mRegisteredContext;
     Handler mRegisteredHandler;
     String[] mDisappearingPackages;
@@ -66,17 +64,32 @@
 
     private Executor mExecutor;
 
+    final boolean mSupportsPackageRestartQuery;
+
     @UnsupportedAppUsage
     public PackageMonitor() {
+        this(true);
+    }
+
+    /**
+     * The constructor of PackageMonitor whose parameters clearly indicate whether support
+     * querying package restart event.
+     */
+    public PackageMonitor(boolean supportsPackageRestartQuery) {
+        mSupportsPackageRestartQuery = supportsPackageRestartQuery;
+    }
+
+    private IntentFilter getPackageFilter() {
         final boolean isCore = UserHandle.isCore(android.os.Process.myUid());
 
-        mPackageFilt = new IntentFilter();
+        IntentFilter filter = new IntentFilter();
         // Settings app sends the broadcast
-        mPackageFilt.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
-        mPackageFilt.addDataScheme("package");
+        filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
+        filter.addDataScheme("package");
         if (isCore) {
-            mPackageFilt.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+            filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
         }
+        return filter;
     }
 
     @UnsupportedAppUsage
@@ -91,7 +104,6 @@
                 (thread == null) ? BackgroundThread.getHandler() : new Handler(thread));
     }
 
-
     /**
      * Register for notifications of package changes such as install, removal and other events.
      */
@@ -101,10 +113,13 @@
         }
         mRegisteredContext = context;
         mRegisteredHandler = Objects.requireNonNull(handler);
-        if (user != null) {
-            context.registerReceiverAsUser(this, user, mPackageFilt, null, mRegisteredHandler);
-        } else {
-            context.registerReceiver(this, mPackageFilt, null, mRegisteredHandler);
+        if (mSupportsPackageRestartQuery) {
+            final IntentFilter filter = getPackageFilter();
+            if (user != null) {
+                context.registerReceiverAsUser(this, user, filter, null, mRegisteredHandler);
+            } else {
+                context.registerReceiver(this, filter, null, mRegisteredHandler);
+            }
         }
         if (mPackageMonitorCallback == null) {
             PackageManager pm = mRegisteredContext.getPackageManager();
@@ -126,7 +141,9 @@
         if (mRegisteredContext == null) {
             throw new IllegalStateException("Not registered");
         }
-        mRegisteredContext.unregisterReceiver(this);
+        if (mSupportsPackageRestartQuery) {
+            mRegisteredContext.unregisterReceiver(this);
+        }
 
         PackageManager pm = mRegisteredContext.getPackageManager();
         if (pm != null && mPackageMonitorCallback != null) {
@@ -378,7 +395,7 @@
      * @param intent the intent that contains package related event information
      */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    public void doHandlePackageEvent(Intent intent) {
+    public final void doHandlePackageEvent(Intent intent) {
         mChangeUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
                 UserHandle.USER_NULL);
         if (mChangeUserId == UserHandle.USER_NULL) {
diff --git a/core/java/com/android/internal/widget/LockscreenCredential.java b/core/java/com/android/internal/widget/LockscreenCredential.java
index 18d5f6d..54b9a22 100644
--- a/core/java/com/android/internal/widget/LockscreenCredential.java
+++ b/core/java/com/android/internal/widget/LockscreenCredential.java
@@ -386,6 +386,11 @@
     }
 
     @Override
+    public void finalize() {
+        zeroize();
+    }
+
+    @Override
     public int hashCode() {
         // Effective Java — Always override hashCode when you override equals
         return Objects.hash(mType, Arrays.hashCode(mCredential), mHasInvalidChars);
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index d31baf3..e3a438d 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -1059,6 +1059,7 @@
 
             optional int32 uid = 1;
             repeated .android.app.ApplicationStartInfoProto app_start_info = 2;
+            optional bool monitoring_enabled = 3;
         }
         repeated User users = 2;
     }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 389e087..e2106c5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -298,9 +298,6 @@
 
     <protected-broadcast android:name="android.hardware.display.action.WIFI_DISPLAY_STATUS_CHANGED" />
 
-    <protected-broadcast android:name="android.hardware.hdmi.action.OSD_MESSAGE" />
-    <protected-broadcast android:name="android.hardware.hdmi.action.ON_ACTIVE_SOURCE_RECOVERED_DISMISS_UI" />
-
     <protected-broadcast android:name="android.hardware.usb.action.USB_STATE" />
     <protected-broadcast android:name="android.hardware.usb.action.USB_PORT_CHANGED" />
     <protected-broadcast android:name="android.hardware.usb.action.USB_PORT_COMPLIANCE_CHANGED" />
@@ -6203,7 +6200,7 @@
           @hide
           @removed -->
     <permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"
-        android:protectionLevel="signature" />
+        android:protectionLevel="signature|role" />
 
     <!-- Allows an application to know what content is playing and control its playback.
          <p>Not for use by third-party applications due to privacy of media consumption</p>  -->
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 8218ff1..dbf09ee 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -830,7 +830,7 @@
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Stel wagwoordreëls"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Beheer die lengte en die karakters wat in skermslotwagwoorde en -PIN\'e toegelaat word."</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"Monitor pogings om skerm te ontsluit"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Monitor die aantal keer wat \'n verkeerde wagwoorde ingevoer is wanneer die skerm ontsluit word. Sluit die tablet of vee al die data uit as die wagwoord te veel keer verkeerd ingevoer word."</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Monitor die aantal keer wat \'n verkeerde wagwoord ingevoer word wanneer die skerm ontsluit word. Sluit die tablet of vee al die data uit as die wagwoord te veel keer verkeerd ingevoer word."</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Monitor die aantal verkeerde wagwoorde wat ingetik word wanneer die skerm ontsluit word, en sluit jou Android TV-toestel of vee al jou Android TV-toestel se data uit as te veel verkeerde wagwoorde ingetik word."</string>
     <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Monitor die aantal verkeerde wagwoorde wat ingevoer word wanneer die skerm ontsluit word, en sluit die inligtingvermaakstelsel of vee al die inligtingvermaakstelsel se data uit as te veel verkeerde wagwoorde ingevoer word."</string>
     <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Monitor die aantal keer wat \'n verkeerde wagwoorde ingevoer is wanneer die skerm ontsluit word. Sluit die foon of vee al die data uit as die wagwoord te veel keer verkeerd ingevoer word."</string>
@@ -843,7 +843,7 @@
     <string name="policylab_forceLock" msgid="7360335502968476434">"Om die skerm te sluit"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"Beheer hoe en wanneer die skerm sluit."</string>
     <string name="policylab_wipeData" msgid="1359485247727537311">"Om alle data uit te vee"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Vee die tablet se data uit sonder waarskuwing, deur \'n fabrieksterugstelling uit te voer."</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Vee die tablet se data uit sonder waarskuwing, deur \'n fabriekterugstelling uit te voer."</string>
     <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Vee jou Android TV-toestel se data sonder waarskuwing uit deur \'n fabrieksterugstelling uit te voer."</string>
     <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Vee die inligtingvermaakstelsel se data sonder waarskuwing uit deur \'n fabriekterugstelling te doen."</string>
     <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Vee die foon se data uit sonder waarskuwing, deur \'n fabrieksterugstelling uit te voer."</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 5a79197..8a2fb4a 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1899,8 +1899,7 @@
     <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>
-    <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
-    <skip />
+    <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalirao je administrator.\nIdite u podešavanja da biste videli odobrene dozvole"</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>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 0ee66fc..484e6f0 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -2179,7 +2179,7 @@
     <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Obavještenja"</string>
     <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Brze postavke"</string>
     <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dijaloški okvir za napajanje"</string>
-    <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaključavanje ekrana"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaključani ekran"</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>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 48ebcad..aafbb39 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -831,14 +831,14 @@
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Definir les normes de contrasenya"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Permet controlar la longitud i el nombre de caràcters permesos a les contrasenyes i als PIN del bloqueig de pantalla."</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"Supervisar els intents de desbloqueig de la pantalla"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja la tauleta o n\'esborra totes les dades si s\'introdueixen massa contrasenyes incorrectes."</string>
-    <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Fa un seguiment del nombre de contrasenyes incorrectes que s\'han introduït en intentar desbloquejar la pantalla i bloqueja el dispositiu Android TV o esborra totes les dades del dispositiu si s\'introdueixen massa contrasenyes incorrectes."</string>
-    <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Supervisa el nombre de contrasenyes incorrectes introduïdes en desbloquejar la pantalla, i bloqueja el sistema d\'informació i entreteniment o n\'esborra totes les dades si s\'introdueixen massa contrasenyes incorrectes."</string>
-    <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Supervisa el nombre de contrasenyes incorrectes introduïdes en desbloquejar la pantalla, i bloqueja el telèfon o esborra totes les dades del telèfon si s\'introdueixen massa contrasenyes incorrectes."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Fa un seguiment del nombre de contrasenyes incorrectes que s\'han escrit en intentar desbloquejar la pantalla i bloqueja la tauleta o n\'esborra totes les dades de l\'usuari si s\'escriuen massa contrasenyes incorrectes."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Fa un seguiment del nombre de contrasenyes incorrectes que s\'han introduït en intentar desbloquejar la pantalla i bloqueja el dispositiu Android TV o n\'esborra totes les dades de l\'usuari si s\'introdueixen massa contrasenyes incorrectes."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Supervisa el nombre de contrasenyes incorrectes introduïdes en desbloquejar la pantalla, i bloqueja el sistema d\'informació i entreteniment o esborra totes les dades d\'aquest perfil si s\'introdueixen massa contrasenyes incorrectes."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Fa un seguiment del nombre de contrasenyes incorrectes que s\'han escrit en intentar desbloquejar la pantalla i bloqueja el telèfon o n\'esborra totes les dades de l\'usuari si s\'escriuen massa contrasenyes incorrectes."</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja la tauleta o esborra\'n totes les dades si s\'introdueixen massa contrasenyes incorrectes."</string>
+    <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja el dispositiu Android TV o esborra\'n totes les dades si s\'introdueixen massa contrasenyes incorrectes."</string>
+    <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja el sistema d\'informació i entreteniment o esborra\'n totes les dades si s\'introdueixen massa contrasenyes incorrectes."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja el telèfon o esborra\'n totes les dades si s\'introdueixen massa contrasenyes incorrectes."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja la tauleta o esborra totes les dades d\'aquest usuari si s\'introdueixen massa contrasenyes incorrectes."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja el dispositiu Android TV o esborra totes les dades d\'aquest usuari si s\'introdueixen massa contrasenyes incorrectes."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja el sistema d\'informació i entreteniment o esborra totes les dades d\'aquest perfil si s\'introdueixen massa contrasenyes incorrectes."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Supervisa el nombre de contrasenyes incorrectes introduïdes per desbloquejar la pantalla i bloqueja el telèfon o esborra totes les dades d\'aquest usuari si s\'introdueixen massa contrasenyes incorrectes."</string>
     <string name="policylab_resetPassword" msgid="214556238645096520">"Canviar el bloqueig de pantalla"</string>
     <string name="policydesc_resetPassword" msgid="4626419138439341851">"Canvia el bloqueig de pantalla."</string>
     <string name="policylab_forceLock" msgid="7360335502968476434">"Bloquejar la pantalla"</string>
@@ -1899,8 +1899,7 @@
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Sol·licita el PIN per deixar de fixar"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Sol·licita el patró de desbloqueig per deixar de fixar"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demana la contrasenya per deixar de fixar"</string>
-    <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
-    <skip />
+    <string name="package_installed_device_owner" msgid="8684974629306529138">"Instal·lat per l\'administrador.\nVes a la configuració per veure els permisos concedits."</string>
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Actualitzat per l\'administrador"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Suprimit per l\'administrador"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"D\'acord"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index fef6fa6..f7b903f 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -832,7 +832,7 @@
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Nastavit pravidla pro heslo"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Ovládání délky a znaků povolených v heslech a kódech PIN zámku obrazovky."</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"Sledovat pokusy o odemknutí obrazovky"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Sledovat počet nesprávných hesel zadaných při odemykání obrazovky a uzamknout tablet nebo vymazat z tabletu všechna data, pokud bylo zadáno příliš mnoho nesprávných hesel."</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Monitoruje se počet nesprávných hesel zadaných při odemykání obrazovky, a pokud bylo zadáno příliš mnoho nesprávných hesel, tablet se uzamkne nebo se z něj vymažou všechna data."</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Sledovat počet nesprávných hesel zadaných při odemykání obrazovky, a pokud jich bude zadáno příliš mnoho, uzamknout zařízení Android TV nebo z něj vymazat všechna data."</string>
     <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Monitorovat počet nesprávných hesel zadaných při odemykání obrazovky a uzamknout informační a zábavní systém nebo vymazat veškerá data v informačním a zábavním systému, pokud je zadáno příliš mnoho nesprávných hesel."</string>
     <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Sleduje počet nesprávných hesel zadaných při odemykání obrazovky a uzamkne telefon nebo vymaže z telefonu všechna data, pokud bylo zadáno příliš mnoho nesprávných hesel."</string>
@@ -845,7 +845,7 @@
     <string name="policylab_forceLock" msgid="7360335502968476434">"Uzamknout obrazovku"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"Určíte, jak a kdy se obrazovka uzamkne."</string>
     <string name="policylab_wipeData" msgid="1359485247727537311">"Mazat všechna data"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Bez upozornění smazat všechna data tabletu obnovením továrních dat."</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Bez upozornění se smažou všechna data tabletu obnovením továrních dat."</string>
     <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Provést obnovení továrních dat a bez upozornění tím vymazat data v zařízení Android TV."</string>
     <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Bez upozornění se smažou všechna data informačního a zábavního systému obnovením továrních dat."</string>
     <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Bez upozornění se smažou všechna data telefonu obnovením továrních dat."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index ae1da16..0122a2c 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -830,7 +830,7 @@
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Passwortregeln festlegen"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Zulässige Länge und Zeichen für Passwörter für die Displaysperre festlegen"</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"Versuche zum Entsperren des Displays überwachen"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Anzahl der falsch eingegebenen Passwörter beim Entsperren des Displays überwachen und Tablet sperren oder alle Daten auf dem Tablet löschen, wenn zu häufig ein falsches Passwort eingegeben wird."</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Anzahl der falsch eingegebenen Passwörter beim Entsperren des Displays überwachen und Tablet sperren oder alle Daten auf dem Tablet löschen, wenn zu häufig ein falsches Passwort eingegeben wird"</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Es wird überwacht, wie oft beim Versuch, den Bildschirm zu entsperren, ein falsches Passwort eingegeben wird. Wenn es zu viele Fehlversuche gibt, wird das Android TV-Gerät gesperrt oder alle Daten darauf werden gelöscht."</string>
     <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Anzahl der falsch eingegebenen Passwörter beim Entsperren des Displays erfassen und Infotainmentsystem sperren oder alle Daten des Infotainmentsystems löschen, wenn zu häufig ein falsches Passwort eingegeben wird."</string>
     <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Anzahl der falsch eingegebenen Passwörter beim Entsperren des Bildschirms überwachen und Telefon sperren oder alle Daten auf dem Telefon löschen, wenn zu häufig ein falsches Passwort eingegeben wird."</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 71b5903..15ac935 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -356,8 +356,7 @@
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string>
     <string name="dream_preview_title" msgid="5570751491996100804">"Preview, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for dream_accessibility_action_click (7392398629967797805) -->
-    <skip />
+    <string name="dream_accessibility_action_click" msgid="7392398629967797805">"dismiss"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 25d6c18..78e4f32 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -356,8 +356,7 @@
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‎Take screenshot‎‏‎‎‏‎"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎Can take a screenshot of the display.‎‏‎‎‏‎"</string>
     <string name="dream_preview_title" msgid="5570751491996100804">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‎‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‎‎Preview, ‎‏‎‎‏‏‎<xliff:g id="DREAM_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <!-- no translation found for dream_accessibility_action_click (7392398629967797805) -->
-    <skip />
+    <string name="dream_accessibility_action_click" msgid="7392398629967797805">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‎dismiss‎‏‎‎‏‎"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎disable or modify status bar‎‏‎‎‏‎"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‎Allows the app to disable the status bar or add and remove system icons.‎‏‎‎‏‎"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎be the status bar‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 953bfbd..d524aac 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -844,7 +844,7 @@
     <string name="policylab_forceLock" msgid="7360335502968476434">"Bloquear la pantalla"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"Controla cómo y cuándo se bloquea la pantalla."</string>
     <string name="policylab_wipeData" msgid="1359485247727537311">"Borrar todos los datos"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Eliminar los datos de la tablet sin avisar y restablecer la configuración de fábrica"</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Borra los datos de la tablet sin avisar y restablece la configuración de fábrica."</string>
     <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Restablece la configuración de fábrica para borrar los datos del dispositivo Android TV sin previo aviso."</string>
     <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Permite borrar los datos del sistema de infoentretenimiento sin previo aviso mediante el restablecimiento de la configuración de fábrica."</string>
     <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Borra los datos del dispositivo sin avisar y restablece la configuración de fábrica."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index ba2c5e5..5f48741 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -831,7 +831,7 @@
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Establecimiento de reglas de contraseña"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Controla la longitud y los caracteres permitidos en los PIN y en las contraseñas de bloqueo de pantalla."</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"Supervisar los intentos de desbloqueo de pantalla"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Controla el número de contraseñas incorrectas introducidas al desbloquear la pantalla y bloquea el tablet o elimina todos sus datos si se introducen demasiadas contraseñas incorrectas."</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Controla el número de contraseñas incorrectas introducidas al desbloquear la pantalla y bloquea la tablet o elimina todos sus datos si se introducen demasiadas contraseñas incorrectas."</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Comprueba cuántas veces se han introducido contraseñas incorrectas para desbloquear la pantalla y, si te parece que han sido demasiadas, bloquea tu dispositivo Android TV o borra todos sus datos."</string>
     <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Controla el número de contraseñas incorrectas introducidas al desbloquear la pantalla y bloquea el sistema de infoentretenimiento o borra todos sus datos si se introducen demasiadas contraseñas incorrectas."</string>
     <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Controla el número de contraseñas incorrectas introducidas al desbloquear la pantalla y bloquea el teléfono o elimina todos sus datos si se introducen demasiadas contraseñas incorrectas."</string>
@@ -844,7 +844,7 @@
     <string name="policylab_forceLock" msgid="7360335502968476434">"Bloquear la pantalla"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"Controla cómo y cuándo se bloquea la pantalla"</string>
     <string name="policylab_wipeData" msgid="1359485247727537311">"Borrar todos los datos"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Borrar los datos del tablet sin avisar restableciendo el estado de fábrica"</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Borra los datos de la tablet sin avisar restableciendo el estado de fábrica"</string>
     <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Restablece los datos de fábrica de tu dispositivo Android TV, eliminando sin previo aviso los datos que tuviera."</string>
     <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Borra los datos del sistema de infoentretenimiento sin avisar restableciendo el estado de fábrica."</string>
     <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Borra los datos del teléfono sin avisar restableciendo el estado de fábrica"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index b100016..1e50e92 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -843,7 +843,7 @@
     <string name="policylab_forceLock" msgid="7360335502968476434">"Ekraani lukustamine"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"Määrake, kuidas ja millal ekraan lukustub."</string>
     <string name="policylab_wipeData" msgid="1359485247727537311">"Kõikide andmete kustutamine"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Kustutage tahvelarvuti andmed hoiatamata, lähtestades arvuti tehaseandmetele."</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Kustutab tahvelarvuti andmed hoiatamata, lähtestades arvuti tehaseandmetele."</string>
     <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Kustutatakse teie Android TV seadme andmed ilma hoiatamata, lähtestades seadme tehase andmetele."</string>
     <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Teabe ja meelelahutuse süsteemi andmete hoiatamata kustutamine tehase andmetele lähtestamise abil."</string>
     <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Kustutab telefoniandmed hoiatuseta, lähtestades telefoni tehaseseadetele."</string>
@@ -1898,8 +1898,7 @@
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Enne vabastamist küsi PIN-koodi"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Enne vabastamist küsi avamismustrit"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Enne vabastamist küsi parooli"</string>
-    <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
-    <skip />
+    <string name="package_installed_device_owner" msgid="8684974629306529138">"Installis teie administraator.\nAntud õiguste vaatamiseks avage seaded"</string>
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Administraator on seda värskendanud"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Administraator on selle kustutanud"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index aa87f24..2a21478 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1898,8 +1898,7 @@
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pyydä PIN ennen irrotusta"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pyydä lukituksenpoistokuvio ennen irrotusta"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pyydä salasana ennen irrotusta"</string>
-    <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
-    <skip />
+    <string name="package_installed_device_owner" msgid="8684974629306529138">"Järjestelmänvalvojan asentama.\nTarkista myönnetyt luvat asetuksista."</string>
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Järjestelmänvalvoja päivitti tämän."</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Järjestelmänvalvoja poisti tämän."</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index f94ebac..a3d71d9 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1899,8 +1899,7 @@
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Demander le code avant de retirer l\'épingle"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Demander le schéma de déverrouillage avant de retirer l\'épingle"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demander le mot de passe avant de retirer l\'épingle"</string>
-    <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
-    <skip />
+    <string name="package_installed_device_owner" msgid="8684974629306529138">"Installé par votre administrateur.\nAllez dans les paramètres pour consulter les autorisations accordées."</string>
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Mis à jour par votre administrateur"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Supprimé par votre administrateur"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index f393074..9eb691f 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1898,8 +1898,7 @@
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"अनपिन करने से पहले पिन के लिए पूछें"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन करने से पहले लॉक खोलने के पैटर्न के लिए पूछें"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"अनपिन करने से पहले पासवर्ड के लिए पूछें"</string>
-    <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
-    <skip />
+    <string name="package_installed_device_owner" msgid="8684974629306529138">"इसे आपके एडमिन ने इंस्टॉल किया है.\nजिन अनुमतियों को मंज़ूरी मिली है उन्हें देखने के लिए, सेटिंग में जाएं"</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>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 33cde13..84598ed 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -831,7 +831,7 @@
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Postavi pravila zaporke"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Upravlja duljinom i znakovima koji su dopušteni u zaporkama i PIN-ovima zaključavanja zaslona."</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"Nadzor pokušaja otključavanja zaslona"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Nadziri broj netočnih zaporki unesenih pri otključavanju zaslona i zaključaj tabletno računalo ili izbriši sve podatke na njemu ako je uneseno previše netočnih zaporki."</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Nadzire se broj netočnih zaporki unesenih pri otključavanju zaslona, a tablet se zaključava ili se s njega brišu svi podaci ako je uneseno previše netočnih zaporki."</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Prati broj netočnih zaporki unesenih prilikom otključavanja zaslona i zaključava Android TV uređaj ili s njega briše sve podatke ako se unese previše netočnih zaporki."</string>
     <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Prati broj netočnih zaporki unesenih prilikom otključavanja zaslona i zaključava sustav za informiranje i zabavu ili briše sve njegove podatke ako se unese previše netočnih zaporki."</string>
     <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Nadzire broj netočno unesenih zaporki pri otključavanju zaslona i zaključava telefon ili briše sve podatke na telefonu ako je uneseno previše netočnih zaporki."</string>
@@ -844,7 +844,7 @@
     <string name="policylab_forceLock" msgid="7360335502968476434">"Zaključavanje zaslona"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"Upravlja se načinom i vremenom zaključavanja zaslona."</string>
     <string name="policylab_wipeData" msgid="1359485247727537311">"Brisanje svih podataka"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Vraćanjem u tvorničko stanje izbriši podatke tabletnog računala bez upozorenja."</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Vraćanjem na tvorničke postavke brišu se podaci tableta bez upozorenja."</string>
     <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Podatke Android TV uređaja izbrišite bez upozorenja vraćanjem uređaja na tvorničke postavke."</string>
     <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Briše podatke sustava za informiranje i zabavu bez upozorenja vraćanjem na tvorničko stanje."</string>
     <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Vraćanjem na tvorničke postavke brišu se podaci s telefona bez upozorenja."</string>
@@ -1537,7 +1537,7 @@
     <string name="vpn_lockdown_config" msgid="8331697329868252169">"Promijenite mrežu ili postavke VPN-a"</string>
     <string name="upload_file" msgid="8651942222301634271">"Odaberite datoteku"</string>
     <string name="no_file_chosen" msgid="4146295695162318057">"Nema odabranih datoteka"</string>
-    <string name="reset" msgid="3865826612628171429">"Ponovo postavi"</string>
+    <string name="reset" msgid="3865826612628171429">"Poništi"</string>
     <string name="submit" msgid="862795280643405865">"Pošalji"</string>
     <string name="car_mode_disable_notification_title" msgid="8450693275833142896">"Pokrenuta je aplikacija za vožnju"</string>
     <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Dodirnite za zatvaranje aplikacije za vožnju."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index acf2266..d688035 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1898,8 +1898,7 @@
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"PIN-kód kérése a kitűzés feloldásához"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Feloldási minta kérése a kitűzés feloldásához"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Jelszó kérése a rögzítés feloldásához"</string>
-    <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
-    <skip />
+    <string name="package_installed_device_owner" msgid="8684974629306529138">"A rendszergazda által telepítve.\nLépjen a beállításokhoz a megadott engedélyek megtekintéséhez."</string>
     <string name="package_updated_device_owner" msgid="7560272363805506941">"A rendszergazda által frissítve"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"A rendszergazda által törölve"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index b304edc..2692d06 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1898,8 +1898,7 @@
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Biðja um PIN-númer til að losa"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Biðja um opnunarmynstur til að losa"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Biðja um aðgangsorð til að losa"</string>
-    <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
-    <skip />
+    <string name="package_installed_device_owner" msgid="8684974629306529138">"Sett upp af stjórnanda.\nFarðu í stillingar til að sjá heimildir"</string>
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Kerfisstjóri uppfærði"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Kerfisstjóri eyddi"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Í lagi"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 00b79b6..2cc0590 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -844,7 +844,7 @@
     <string name="policylab_forceLock" msgid="7360335502968476434">"Bloccare lo schermo"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"Controlla come e quando si blocca lo schermo."</string>
     <string name="policylab_wipeData" msgid="1359485247727537311">"Cancellare tutti i dati"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Cancella i dati del tablet senza preavviso eseguendo un ripristino dati di fabbrica."</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Cancella i dati del tablet senza preavviso eseguendo un ripristino dei dati di fabbrica."</string>
     <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Consente di cancellare i dati del dispositivo Android TV senza preavviso eseguendo un ripristino dei dati di fabbrica."</string>
     <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Cancella i dati del sistema di infotainment senza preavviso eseguendo un ripristino dei dati di fabbrica."</string>
     <string name="policydesc_wipeData" product="default" msgid="8036084184768379022">"Cancella i dati del telefono senza preavviso eseguendo un ripristino dei dati di fabbrica."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 5f6cd38..2ef91cd 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -843,7 +843,7 @@
     <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="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>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index ec92812..0d48bbb 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -830,7 +830,7 @@
     <string name="policylab_limitPassword" msgid="4851829918814422199">"ಪಾಸ್‌ವರ್ಡ್ ನಿಮಯಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"ಪರದೆ ಲಾಕ್‌ನಲ್ಲಿನ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಮತ್ತು ಪಿನ್‌ಗಳ ಅನುಮತಿಸಲಾದ ಅಕ್ಷರಗಳ ಪ್ರಮಾಣವನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"ಪರದೆಯ ಅನ್‌ಲಾಕ್ ಪ್ರಯತ್ನಗಳನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ಪರದೆಯನ್ನು ಅನ್‌ಲಾಕ್‌ ಮಾಡುವಾಗ ತಪ್ಪಾಗಿ ಟೈಪ್‌ ಮಾಡಿದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ, ಮತ್ತು ಟ್ಯಾಬ್ಲೆಟ್‌ ಅನ್ನು ಲಾಕ್‌ ಮಾಡಿ ಅಥವಾ ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ಟೈಪ್‌ ಮಾಡಿದ್ದರೆ ಟ್ಯಾಬ್ಲೆಟ್‌ನ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</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>
@@ -1898,8 +1898,7 @@
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ಅನ್‌ಪಿನ್ ಮಾಡಲು ಪಿನ್‌ ಕೇಳು"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ಅನ್‌ಪಿನ್ ಮಾಡಲು ಅನ್‌ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಕೇಳಿ"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ಅನ್‌ಪಿನ್ ಮಾಡಲು ಪಾಸ್‌ವರ್ಡ್ ಕೇಳು"</string>
-    <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
-    <skip />
+    <string name="package_installed_device_owner" msgid="8684974629306529138">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿದ್ದಾರೆ.\nನೀಡಲಾದ ಅನುಮತಿಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ಹೋಗಿ"</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>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 12adb17..1ffde6f 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -830,7 +830,7 @@
     <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="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>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 230e701..30e4eca 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -830,14 +830,14 @@
     <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="tablet" msgid="2388436408621909298">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप गरिन्छ भन्ने कुराको रेकर्ड राख्नुहोस् र धेरै पटक गलत पासवर्ड टाइप गरिएका खण्डमा ट्याबलेट लक गर्नुहोस् वा यसका सबै डेटा मेटाउनुहोस्।"</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप गरेको सङ्ख्या निरीक्षण गर्नुहोस्, र धेरै पटक गलत पासवर्डहरू टाइप गरिएको खण्डमा आफ्नो Android टिभी यन्त्र लक गर्नुहोस् वा डिभाइसमा भएको सम्पूर्ण डेटा मेटाउनुहोस्।"</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="tablet" msgid="2049038943004297474">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप गरिन्छ भन्ने कुराको रेकर्ड राख्नुहोस् र धेरै पटक गलत पासवर्ड टाइप गरिएका खण्डमा ट्याबलेट लक गर्नुहोस् वा प्रयोगकर्ताका सबै डेटा मेटाउनुहोस्।"</string>
     <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप गरेको सङ्ख्या निरीक्षण गर्नुहोस्, र धेरै पटक गलत पासवर्डहरू टाइप गरिएको खण्डमा आफ्नो Android टिभी यन्त्र लक गर्नुहोस् वा यो प्रयोगकर्ताको सम्पूर्ण डेटा मेटाउनुहोस्।"</string>
     <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप गरिन्छ भन्ने कुरा निगरानी गर्नुहोस् र अत्यन्तै धेरै पटक गलत पासवर्ड टाइप गरिएका खण्डमा यो इन्फोटेनमेन्ट प्रणाली लक गर्नुहोस् वा यस प्रोफाइलका सबै डेटा मेटाउनुहोस्।"</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप संख्या अनुगमन गर्नुहोस्, र यदि निकै धेरै गलत पासवर्डहरू टाइप गरिएमा फोन लक गर्नुहोस् वा प्रयोगकर्ताको डेटा मेटाउनुहोस्।"</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>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 5de3287..f59d2ae 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -356,8 +356,7 @@
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Screenshot maken"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan een screenshot van het scherm maken."</string>
     <string name="dream_preview_title" msgid="5570751491996100804">"Voorbeeld, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for dream_accessibility_action_click (7392398629967797805) -->
-    <skip />
+    <string name="dream_accessibility_action_click" msgid="7392398629967797805">"sluiten"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"statusbalk uitzetten of wijzigen"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Hiermee kan de app de statusbalk uitzetten of systeemiconen toevoegen en verwijderen."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"de statusbalk zijn"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 6f186ff..9c41d73 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -830,7 +830,7 @@
     <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="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>
@@ -843,7 +843,7 @@
     <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="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>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index a6937d2..ab40341 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -832,7 +832,7 @@
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Określ reguły hasła"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Kontrolowanie długości haseł blokady ekranu i kodów PIN oraz dozwolonych w nich znaków."</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"Monitorowanie prób odblokowania ekranu"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Przy odblokowywaniu ekranu monitoruj, ile razy wpisano nieprawidłowe hasło i blokuj tablet lub usuń z niego wszystkie dane, jeśli nieprawidłowe hasło podano zbyt wiele razy."</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Przy odblokowywaniu ekranu monitoruje, ile razy wpisano nieprawidłowe hasło i blokuje tablet lub usuwa z niego wszystkie dane, jeśli nieprawidłowe hasło podano zbyt wiele razy"</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Monitorowanie liczby nieudanych prób odblokowania ekranu za pomocą hasła oraz blokowanie urządzenia z Androidem TV lub kasowanie z niego wszystkich danych w razie wpisania błędnego hasła zbyt wiele razy."</string>
     <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Monitorowanie przypadków nieprawidłowego wpisania hasła podczas odblokowywania ekranu i blokowanie systemu multimedialno-rozrywkowego lub usuwanie z niego wszystkich danych przy zbyt dużej liczbie błędnych prób."</string>
     <string name="policydesc_watchLogin" product="default" msgid="4885030206253600299">"Przy odblokowywaniu ekranu monitoruje, ile razy wpisano nieprawidłowe hasło, i blokuje telefon lub usuwa z niego wszystkie dane, jeśli nieprawidłowe hasło podano zbyt wiele razy."</string>
@@ -1267,7 +1267,7 @@
     <string name="screen_compat_mode_scale" msgid="8627359598437527726">"Skala"</string>
     <string name="screen_compat_mode_show" msgid="5080361367584709857">"Zawsze pokazuj"</string>
     <string name="screen_compat_mode_hint" msgid="4032272159093750908">"Włącz ponownie, wybierając Ustawienia systemu &gt; Aplikacje &gt; Pobrane."</string>
-    <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> nie obsługuje obecnie ustawionego rozmiaru wyświetlacza i może działać niestabilnie."</string>
+    <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> nie obsługuje obecnie ustawionego rozmiaru wyświetlanych elementów i może działać niestabilnie."</string>
     <string name="unsupported_display_size_show" msgid="980129850974919375">"Zawsze pokazuj"</string>
     <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> została skompilowana pod niezgodną wersję systemu Android i może zachowywać się niezgodnie z oczekiwaniami. Sprawdź, czy jest dostępna zaktualizowana wersja aplikacji."</string>
     <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Zawsze pokazuj"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 4772ff8..4d61bdd 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -357,8 +357,7 @@
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fazer captura de ecrã"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"É possível tirar uma captura de ecrã."</string>
     <string name="dream_preview_title" msgid="5570751491996100804">"Pré-visualização, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for dream_accessibility_action_click (7392398629967797805) -->
-    <skip />
+    <string name="dream_accessibility_action_click" msgid="7392398629967797805">"ignorar"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desativar ou modificar barra de estado"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite à app desativar a barra de estado ou adicionar e remover ícones do sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ser apresentada na barra de estado"</string>
@@ -838,7 +837,7 @@
     <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="2049038943004297474">"Monitorizar o número de palavras-passe incorretas introduzidas ao desbloquear o ecrã e bloquear o tablet ou apagar todos os dados deste utilizador se forem introduzidas demasiadas palavras-passe incorretas."</string>
     <string name="policydesc_watchLogin_secondaryUser" product="tv" msgid="8965224107449407052">"Monitorizar o número de palavras-passe incorretas introduzidas ao desbloquear o ecrã e bloquear o dispositivo Android TV ou apagar todos os dados deste utilizador se forem introduzidas demasiadas palavras-passe incorretas."</string>
     <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Monitorize o número de palavras-passe incorretas introduzidas ao desbloquear o ecrã e bloqueie o sistema de infoentretenimento ou apague todos os dados deste utilizador, se forem introduzidas demasiadas palavras-passe incorretas."</string>
-    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Monitorizar o número de palavras-passe incorretas introduzidas ao desbloquear o ecrã e bloquear o telemóvel ou apagar todos os dados deste utilizador se forem introduzidas demasiadas palavras-passe incorretas."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Monitorizar o número de palavras-passe incorretas introduzidas ao desbloquear o ecrã, e bloquear o telemóvel ou apagar todos os dados deste utilizador se forem introduzidas demasiadas palavras-passe incorretas."</string>
     <string name="policylab_resetPassword" msgid="214556238645096520">"Alterar o bloqueio de ecrã"</string>
     <string name="policydesc_resetPassword" msgid="4626419138439341851">"Altera o bloqueio de ecrã."</string>
     <string name="policylab_forceLock" msgid="7360335502968476434">"Bloquear o ecrã"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 6768e29..569eb35 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1899,8 +1899,7 @@
     <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>
-    <!-- no translation found for package_installed_device_owner (8684974629306529138) -->
-    <skip />
+    <string name="package_installed_device_owner" msgid="8684974629306529138">"Инсталирао је администратор.\nИдите у подешавања да бисте видели одобрене дозволе"</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>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 1c65e61..eb1e453 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -843,7 +843,7 @@
     <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="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>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 423cf88..3c82307 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -843,7 +843,7 @@
     <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="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>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index a248ede..cc02a7e 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -190,6 +190,13 @@
     <integer name="config_satellite_nb_iot_inactivity_timeout_millis">180000</integer>
     <java-symbol type="integer" name="config_satellite_nb_iot_inactivity_timeout_millis" />
 
+    <!-- The time duration in millis after which cellular scanning will be enabled and satellite
+         will move to IDLE state. This timeout duration is used for satellite with NB IOT radio
+         technologies in demo mode.
+         -->
+    <integer name="config_satellite_demo_mode_nb_iot_inactivity_timeout_millis">60000</integer>
+    <java-symbol type="integer" name="config_satellite_demo_mode_nb_iot_inactivity_timeout_millis" />
+
     <!-- The time duration in millis needed to switch the modem image from TN to NTN. -->
     <integer name="config_satellite_modem_image_switching_duration_millis">20000</integer>
     <java-symbol type="integer" name="config_satellite_modem_image_switching_duration_millis" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2f9f4df..4ea97a5 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -6050,6 +6050,10 @@
     <!-- Dialog text.  Shown when the user is unable to send a text message from a personal app due to restrictions set
          by their organization, and so must switch to a work app or cancel. [CHAR LIMIT=NONE] -->
     <string name="miniresolver_sms_information">Your organization only allows you to send messages from work apps</string>
+    <!-- Dialog text. Shown as when redirecting Calls from Private Space to the main user. [CHAR LIMIT=NONE] -->
+    <string name="miniresolver_private_space_phone_information">"You can only make phone calls from your personal Phone app. Calls made with personal Phone will be added to your personal call history."</string>
+    <!-- Dialog text. Shown as when redirecting SMS and MMS messages from Private Space to the main user. [CHAR LIMIT=NONE] -->
+    <string name="miniresolver_private_space_messages_information">"You can only send SMS messages from your personal Messages app."</string>
     <!-- Button option. Open the link in the personal browser. [CHAR LIMIT=NONE] -->
     <string name="miniresolver_use_personal_browser">Use personal browser</string>
     <!-- Button option. Open the link in the work browser. [CHAR LIMIT=NONE] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 90132c3..e304027 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1628,6 +1628,8 @@
   <java-symbol type="string" name="miniresolver_switch" />
   <java-symbol type="string" name="miniresolver_call_information" />
   <java-symbol type="string" name="miniresolver_sms_information" />
+  <java-symbol type="string" name="miniresolver_private_space_phone_information" />
+  <java-symbol type="string" name="miniresolver_private_space_messages_information" />
   <java-symbol type="id" name="miniresolver_info_section" />
   <java-symbol type="id" name="miniresolver_info_section_text" />
   <java-symbol type="id" name="button_open" />
diff --git a/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java b/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
index 9bb064c..62d89f6 100644
--- a/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
+++ b/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
@@ -19,10 +19,20 @@
 import static android.os.storage.VolumeInfo.STATE_MOUNTED;
 import static android.os.storage.VolumeInfo.STATE_UNMOUNTED;
 
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.os.Bundle;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 import android.platform.test.annotations.Presubmit;
@@ -35,9 +45,11 @@
 import junit.framework.TestCase;
 
 import org.mockito.Mockito;
+import org.xmlpull.v1.XmlPullParser;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
 
 @Presubmit
@@ -93,9 +105,11 @@
     private static final class MockedApplicationPackageManager extends ApplicationPackageManager {
         private boolean mForceAllowOnExternal = false;
         private boolean mAllow3rdPartyOnInternal = true;
+        private HashMap<ApplicationInfo, Resources> mResourcesMap;
 
         public MockedApplicationPackageManager() {
             super(null, null);
+            mResourcesMap = new HashMap<ApplicationInfo, Resources>();
         }
 
         public void setForceAllowOnExternal(boolean forceAllowOnExternal) {
@@ -106,6 +120,10 @@
             mAllow3rdPartyOnInternal = allow3rdPartyOnInternal;
         }
 
+        public void setResourcesForApplication(ApplicationInfo info, Resources resources) {
+            mResourcesMap.put(info, resources);
+        }
+
         @Override
         public boolean isForceAllowOnExternal(Context context) {
             return mForceAllowOnExternal;
@@ -122,6 +140,16 @@
                 StorageManager storageManager, IPackageManager pm) {
             return super.getPackageCandidateVolumes(app, storageManager, pm);
         }
+
+        @Override
+        public Resources getResourcesForApplication(ApplicationInfo app)
+                throws NameNotFoundException {
+            if (mResourcesMap.containsKey(app)) {
+                return mResourcesMap.get(app);
+            }
+
+            return super.getResourcesForApplication(app);
+        }
     }
 
     private StorageManager getMockedStorageManager() {
@@ -254,4 +282,73 @@
             verifyReturnedVolumes(candidates, sAdoptedVol);
         }
     }
+
+    public void testExtractPackageItemInfoAttributes_noServiceInfo() {
+        final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
+        assertThat(appPkgMgr.extractPackageItemInfoAttributes(null, null, null,
+                new int[]{})).isNull();
+    }
+
+    public void testExtractPackageItemInfoAttributes_noMetaData() {
+        final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
+        final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
+        assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, null,
+                new int[]{})).isNull();
+    }
+
+    public void testExtractPackageItemInfoAttributes_noParser() {
+        final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
+        final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
+        final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class);
+        when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo);
+        assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, null,
+                new int[]{})).isNull();
+    }
+
+    public void testExtractPackageItemInfoAttributes_noMetaDataXml() {
+        final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
+        final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
+        final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class);
+        when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo);
+        when(packageItemInfo.loadXmlMetaData(any(), any())).thenReturn(null);
+        assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, null,
+                new int[]{})).isNull();
+    }
+
+    public void testExtractPackageItemInfoAttributes_nonMatchingRootTag() throws Exception {
+        final String rootTag = "rootTag";
+        final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
+        final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
+        final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class);
+        final XmlResourceParser parser = Mockito.mock(XmlResourceParser.class);
+
+        when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo);
+        packageItemInfo.metaData = new Bundle();
+        when(packageItemInfo.loadXmlMetaData(any(), any())).thenReturn(parser);
+        when(parser.next()).thenReturn(XmlPullParser.END_DOCUMENT);
+        when(parser.getName()).thenReturn(rootTag + "0");
+        assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, rootTag,
+                new int[]{})).isNull();
+    }
+
+    public void testExtractPackageItemInfoAttributes_successfulExtraction() throws Exception {
+        final String rootTag = "rootTag";
+        final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
+        final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
+        final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class);
+        final XmlResourceParser parser = Mockito.mock(XmlResourceParser.class);
+        final Resources resources = Mockito.mock(Resources.class);
+        final TypedArray attributes = Mockito.mock(TypedArray.class);
+
+        when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo);
+        packageItemInfo.metaData = new Bundle();
+        when(packageItemInfo.loadXmlMetaData(any(), any())).thenReturn(parser);
+        when(parser.next()).thenReturn(XmlPullParser.END_DOCUMENT);
+        when(parser.getName()).thenReturn(rootTag);
+        when(resources.obtainAttributes(any(), any())).thenReturn(attributes);
+        appPkgMgr.setResourcesForApplication(applicationInfo, resources);
+
+        assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, rootTag,
+                new int[]{})).isEqualTo(attributes);
+    }
 }
diff --git a/core/tests/coretests/src/android/view/ViewFrameRateTest.java b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
index 4cdc993..c4ac98b 100644
--- a/core/tests/coretests/src/android/view/ViewFrameRateTest.java
+++ b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
@@ -19,6 +19,7 @@
 import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
 import static android.view.Surface.FRAME_RATE_CATEGORY_LOW;
 import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL;
+import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE;
 import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY;
 import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY;
 import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
@@ -435,6 +436,80 @@
         waitForAfterDraw();
     }
 
+    /**
+     * A common behavior is for two different views to be invalidated in succession, but
+     * intermittently. We want to treat this as an intermittent invalidation.
+     *
+     * This test will only succeed on non-cuttlefish devices, so it is commented out
+     * for potential manual testing.
+     */
+//    @Test
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
+    public void intermittentDoubleInvalidate() throws Throwable {
+        View parent = (View) mMovingView.getParent();
+        mActivityRule.runOnUiThread(() -> {
+            parent.setWillNotDraw(false);
+            // Make sure the View is large
+            ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
+            layoutParams.width = parent.getWidth();
+            layoutParams.height = parent.getHeight();
+            mMovingView.setLayoutParams(layoutParams);
+        });
+        waitForFrameRateCategoryToSettle();
+        for (int i = 0; i < 5; i++) {
+            int expectedCategory;
+            if (i < 4) {
+                // not intermittent yet.
+                // It takes 2 frames of intermittency before Views vote as intermittent.
+                // It takes 4 more frames for the category to drop to the next category.
+                expectedCategory =
+                        toolkitFrameRateDefaultNormalReadOnly() ? FRAME_RATE_CATEGORY_NORMAL
+                                : FRAME_RATE_CATEGORY_HIGH;
+            } else {
+                // intermittent
+                expectedCategory = FRAME_RATE_CATEGORY_NORMAL;
+            }
+            mActivityRule.runOnUiThread(() -> {
+                mMovingView.invalidate();
+                runAfterDraw(() -> assertEquals(expectedCategory,
+                        mViewRoot.getLastPreferredFrameRateCategory()));
+            });
+            waitForAfterDraw();
+            mActivityRule.runOnUiThread(() -> {
+                parent.invalidate();
+                runAfterDraw(() -> assertEquals(expectedCategory,
+                        mViewRoot.getLastPreferredFrameRateCategory()));
+            });
+            waitForAfterDraw();
+            Thread.sleep(90);
+        }
+    }
+
+    // When a view has two motions that offset each other, the overall motion
+    // should be canceled and be considered unmoved.
+    @Test
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY
+    })
+    public void sameFrameMotion() throws Throwable {
+        mMovingView.setRequestedFrameRate(View.REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE);
+        waitForFrameRateCategoryToSettle();
+
+        mActivityRule.runOnUiThread(() -> {
+            mMovingView.offsetLeftAndRight(10);
+            mMovingView.offsetLeftAndRight(-10);
+            mMovingView.offsetTopAndBottom(100);
+            mMovingView.offsetTopAndBottom(-100);
+            mMovingView.invalidate();
+            runAfterDraw(() -> {
+                assertEquals(0f, mViewRoot.getLastPreferredFrameRate(), 0f);
+                assertEquals(FRAME_RATE_CATEGORY_NO_PREFERENCE,
+                        mViewRoot.getLastPreferredFrameRateCategory());
+            });
+        });
+        waitForAfterDraw();
+    }
     private void runAfterDraw(@NonNull Runnable runnable) {
         Handler handler = new Handler(Looper.getMainLooper());
         mAfterDrawLatch = new CountDownLatch(1);
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index 36bede9..852d696 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -34,6 +34,7 @@
 
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
+import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
@@ -403,7 +404,9 @@
         mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mCallback1);
         OnBackInvokedCallbackInfo callbackInfo = assertSetCallbackInfo();
 
-        mDispatcher.onMotionEvent(mMotionEvent);
+        // Send motion event in View's main thread.
+        final Handler main = Handler.getMain();
+        main.runWithScissors(() -> mDispatcher.onMotionEvent(mMotionEvent), 100);
         assertFalse(mDispatcher.mTouchTracker.isActive());
 
         callbackInfo.getCallback().onBackStarted(mBackEvent);
@@ -411,8 +414,9 @@
         assertTrue(mDispatcher.isDispatching());
         assertTrue(mDispatcher.mTouchTracker.isActive());
 
-        mDispatcher.onMotionEvent(mMotionEvent);
+        main.runWithScissors(() -> mDispatcher.onMotionEvent(mMotionEvent), 100);
         waitForIdle();
-        verify(mCallback1).onBackProgressed(any());
+        // onBackPressed is called from animator, so it can happen more than once.
+        verify(mCallback1, atLeast(1)).onBackProgressed(any());
     }
 }
diff --git a/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java b/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java
index 9cb9122..03cb17e 100644
--- a/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java
+++ b/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java
@@ -21,6 +21,7 @@
 import static org.junit.Assert.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -95,6 +96,16 @@
     }
 
     @Test
+    public void testPackageMonitorNotRegisterWithoutSupportPackageRestartQuery() throws Exception {
+        PackageMonitor spyPackageMonitor = spy(new TestPackageMonitor(false));
+
+        spyPackageMonitor.register(mMockContext, UserHandle.ALL, mMockHandler);
+
+        verify(mMockContext, never()).registerReceiverAsUser(any(), eq(UserHandle.ALL), any(),
+                eq(null), eq(mMockHandler));
+    }
+
+    @Test
     public void testPackageMonitorDoHandlePackageEventUidRemoved() throws Exception {
         PackageMonitor spyPackageMonitor = spy(new TestPackageMonitor());
 
@@ -471,5 +482,12 @@
     }
 
     public static class TestPackageMonitor extends PackageMonitor {
+        public TestPackageMonitor(boolean b) {
+            super(b);
+        }
+
+        public TestPackageMonitor() {
+            super();
+        }
     }
 }
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 46a3e7f..89d3058 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -67,7 +67,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.SystemProperties;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
@@ -113,8 +112,7 @@
 public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmentCallback,
         ActivityEmbeddingComponent, DividerPresenter.DragEventCallback {
     static final String TAG = "SplitController";
-    static final boolean ENABLE_SHELL_TRANSITIONS =
-            SystemProperties.getBoolean("persist.wm.debug.shell_transit", true);
+    static final boolean ENABLE_SHELL_TRANSITIONS = true;
 
     // TODO(b/243518738): Move to WM Extensions if we have requirement of overlay without
     //  association. It's not set in WM Extensions nor Wm Jetpack library currently.
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 5c978e2..89781fd 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -210,6 +210,7 @@
         "androidx.recyclerview_recyclerview",
         "kotlinx-coroutines-android",
         "kotlinx-coroutines-core",
+        "//frameworks/libs/systemui:com_android_systemui_shared_flags_lib",
         "//frameworks/libs/systemui:iconloader_base",
         "com_android_wm_shell_flags_lib",
         "com.android.window.flags.window-aconfig-java",
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/IShellTransitions.aidl b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/IShellTransitions.aidl
index 526407e..3256abf 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/IShellTransitions.aidl
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/IShellTransitions.aidl
@@ -28,13 +28,14 @@
 interface IShellTransitions {
 
     /**
-     * Registers a remote transition handler.
+     * Registers a remote transition handler for all operations excluding takeovers (see
+     * registerRemoteForTakeover()).
      */
     oneway void registerRemote(in TransitionFilter filter,
             in RemoteTransition remoteTransition) = 1;
 
     /**
-     * Unregisters a remote transition handler.
+     * Unregisters a remote transition handler for all operations.
      */
     oneway void unregisterRemote(in RemoteTransition remoteTransition) = 2;
 
@@ -52,4 +53,10 @@
      * Returns a container surface for the home root task.
      */
     SurfaceControl getHomeTaskOverlayContainer() = 5;
+
+    /**
+     * Registers a remote transition for takeover operations only.
+     */
+    oneway void registerRemoteForTakeover(in TransitionFilter filter,
+            in RemoteTransition remoteTransition) = 6;
 }
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/ShellTransitions.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/ShellTransitions.java
index 5e49f55..6d4ab4c 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/ShellTransitions.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/ShellTransitions.java
@@ -28,13 +28,20 @@
 @ExternalThread
 public interface ShellTransitions {
     /**
-     * Registers a remote transition.
+     * Registers a remote transition for all operations excluding takeovers (see
+     * {@link ShellTransitions#registerRemoteForTakeover(TransitionFilter, RemoteTransition)}).
      */
     default void registerRemote(@NonNull TransitionFilter filter,
             @NonNull RemoteTransition remoteTransition) {}
 
     /**
-     * Unregisters a remote transition.
+     * Registers a remote transition for takeover operations only.
+     */
+    default void registerRemoteForTakeover(@NonNull TransitionFilter filter,
+            @NonNull RemoteTransition remoteTransition) {}
+
+    /**
+     * Unregisters a remote transition for all operations.
      */
     default void unregisterRemote(@NonNull RemoteTransition remoteTransition) {}
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
index 808c212..037b1ec 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
@@ -20,6 +20,7 @@
 import android.animation.ValueAnimator
 import android.content.Context
 import android.content.res.Configuration
+import android.graphics.Color
 import android.graphics.Matrix
 import android.graphics.PointF
 import android.graphics.Rect
@@ -35,6 +36,7 @@
 import android.view.animation.Interpolator
 import android.window.BackEvent
 import android.window.BackMotionEvent
+import android.window.BackNavigationInfo
 import android.window.BackProgressAnimator
 import android.window.IOnBackInvokedCallback
 import com.android.internal.jank.Cuj
@@ -67,6 +69,7 @@
     private val currentEnteringRect = RectF()
 
     private val backAnimRect = Rect()
+    private val cropRect = Rect()
 
     private var cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
 
@@ -95,6 +98,10 @@
     private var maxScrimAlpha: Float = 0f
 
     private var isLetterboxed = false
+    private var enteringHasSameLetterbox = false
+    private var leftLetterboxLayer: SurfaceControl? = null
+    private var rightLetterboxLayer: SurfaceControl? = null
+    private var letterboxColor: Int = 0
 
     override fun onConfigurationChanged(newConfiguration: Configuration) {
         cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
@@ -115,8 +122,12 @@
 
         transaction.setAnimationTransaction()
         isLetterboxed = closingTarget!!.taskInfo.appCompatTaskInfo.topActivityBoundsLetterboxed
-        if (isLetterboxed) {
-            // Include letterbox in back animation
+        enteringHasSameLetterbox = isLetterboxed &&
+                closingTarget!!.localBounds.equals(enteringTarget!!.localBounds)
+
+        if (isLetterboxed && !enteringHasSameLetterbox) {
+            // Play animation with letterboxes, if closing and entering target have mismatching
+            // letterboxes
             backAnimRect.set(closingTarget!!.windowConfiguration.bounds)
         } else {
             // otherwise play animation on localBounds only
@@ -144,12 +155,25 @@
         targetEnteringRect.set(startEnteringRect)
         targetEnteringRect.scaleCentered(MAX_SCALE)
 
-        // Draw background with task background color.
+        // Draw background with task background color (or letterbox color).
+        val backgroundColor = if (isLetterboxed) {
+            letterboxColor
+        } else {
+            enteringTarget!!.taskInfo.taskDescription!!.backgroundColor
+        }
         background.ensureBackground(
-            closingTarget!!.windowConfiguration.bounds,
-            enteringTarget!!.taskInfo.taskDescription!!.backgroundColor, transaction
+            closingTarget!!.windowConfiguration.bounds, backgroundColor, transaction
         )
         ensureScrimLayer()
+        if (isLetterboxed && enteringHasSameLetterbox) {
+            // crop left and right letterboxes
+            cropRect.set(closingTarget!!.localBounds.left, 0, closingTarget!!.localBounds.right,
+                    closingTarget!!.windowConfiguration.bounds.height())
+            // and add fake letterbox square surfaces instead
+            ensureLetterboxes()
+        } else {
+            cropRect.set(backAnimRect)
+        }
         applyTransaction()
     }
 
@@ -249,18 +273,25 @@
         }
         finishCallback = null
         removeScrimLayer()
+        removeLetterbox()
         isLetterboxed = false
+        enteringHasSameLetterbox = false
     }
 
     private fun applyTransform(leash: SurfaceControl?, rect: RectF, alpha: Float) {
         if (leash == null || !leash.isValid) return
         val scale = rect.width() / backAnimRect.width()
         transformMatrix.reset()
-        transformMatrix.setScale(scale, scale)
+        val scalePivotX = if (isLetterboxed && enteringHasSameLetterbox) {
+            closingTarget!!.localBounds.left.toFloat()
+        } else {
+            0f
+        }
+        transformMatrix.setScale(scale, scale, scalePivotX, 0f)
         transformMatrix.postTranslate(rect.left, rect.top)
         transaction.setAlpha(leash, alpha)
             .setMatrix(leash, transformMatrix, tmpFloat9)
-            .setCrop(leash, backAnimRect)
+            .setCrop(leash, cropRect)
             .setCornerRadius(leash, cornerRadius)
     }
 
@@ -297,15 +328,73 @@
     }
 
     private fun removeScrimLayer() {
-        scrimLayer?.let {
-            if (it.isValid) {
-                transaction.remove(it)
-                applyTransaction()
-            }
-        }
+        if (removeLayer(scrimLayer)) applyTransaction()
         scrimLayer = null
     }
 
+    /**
+     * Adds two "fake" letterbox square surfaces to the left and right of the localBounds of the
+     * closing target
+     */
+    private fun ensureLetterboxes() {
+        closingTarget?.let { t ->
+            if (t.localBounds.left != 0 && leftLetterboxLayer == null) {
+                val bounds = Rect(0, t.windowConfiguration.bounds.top, t.localBounds.left,
+                        t.windowConfiguration.bounds.bottom)
+                leftLetterboxLayer = ensureLetterbox(bounds)
+            }
+            if (t.localBounds.right != t.windowConfiguration.bounds.right &&
+                    rightLetterboxLayer == null) {
+                val bounds = Rect(t.localBounds.right, t.windowConfiguration.bounds.top,
+                        t.windowConfiguration.bounds.right, t.windowConfiguration.bounds.bottom)
+                rightLetterboxLayer = ensureLetterbox(bounds)
+            }
+        }
+    }
+
+    private fun ensureLetterbox(bounds: Rect): SurfaceControl {
+        val letterboxBuilder = SurfaceControl.Builder()
+                .setName("Cross-Activity back animation letterbox")
+                .setCallsite("CrossActivityBackAnimation")
+                .setColorLayer()
+                .setOpaque(true)
+                .setHidden(false)
+
+        rootTaskDisplayAreaOrganizer.attachToDisplayArea(Display.DEFAULT_DISPLAY, letterboxBuilder)
+        val layer = letterboxBuilder.build()
+        val colorComponents = floatArrayOf(Color.red(letterboxColor) / 255f,
+                Color.green(letterboxColor) / 255f, Color.blue(letterboxColor) / 255f)
+        transaction
+                .setColor(layer, colorComponents)
+                .setCrop(layer, bounds)
+                .setRelativeLayer(layer, closingTarget!!.leash, 1)
+                .show(layer)
+        return layer
+    }
+
+    private fun removeLetterbox() {
+        if (removeLayer(leftLetterboxLayer) || removeLayer(rightLetterboxLayer)) applyTransaction()
+        leftLetterboxLayer = null
+        rightLetterboxLayer = null
+    }
+
+    private fun removeLayer(layer: SurfaceControl?): Boolean {
+        layer?.let {
+            if (it.isValid) {
+                transaction.remove(it)
+                return true
+            }
+        }
+        return false
+    }
+
+    override fun prepareNextAnimation(
+            animationInfo: BackNavigationInfo.CustomAnimationInfo?,
+            letterboxColor: Int
+    ): Boolean {
+        this.letterboxColor = letterboxColor
+        return false
+    }
 
     private inner class Callback : IOnBackInvokedCallback.Default() {
         override fun onBackStarted(backMotionEvent: BackMotionEvent) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
index 838dab4..e27b40e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
@@ -271,7 +271,8 @@
 
     /** Load customize animation before animation start. */
     @Override
-    public boolean prepareNextAnimation(BackNavigationInfo.CustomAnimationInfo animationInfo) {
+    public boolean prepareNextAnimation(BackNavigationInfo.CustomAnimationInfo animationInfo,
+            int letterboxColor) {
         if (animationInfo == null) {
             return false;
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimation.java
index 8a0daaa..9cd193b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimation.java
@@ -42,11 +42,12 @@
     public abstract BackAnimationRunner getRunner();
 
     /**
-     * Prepare the next animation with customized animation.
+     * Prepare the next animation.
      *
      * @return true if this type of back animation should override the default.
      */
-    public boolean prepareNextAnimation(BackNavigationInfo.CustomAnimationInfo animationInfo) {
+    public boolean prepareNextAnimation(BackNavigationInfo.CustomAnimationInfo animationInfo,
+            int letterboxColor) {
         return false;
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java
index 7a6032c..6fafa75 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java
@@ -154,11 +154,14 @@
         if (type == BackNavigationInfo.TYPE_CROSS_ACTIVITY && mAnimationDefinition.contains(type)) {
             if (mCustomizeActivityAnimation != null
                     && mCustomizeActivityAnimation.prepareNextAnimation(
-                            backNavigationInfo.getCustomAnimationInfo())) {
+                            backNavigationInfo.getCustomAnimationInfo(), 0)) {
                 mAnimationDefinition.get(type).resetWaitingAnimation();
                 mAnimationDefinition.set(
                         BackNavigationInfo.TYPE_CROSS_ACTIVITY,
                         mCustomizeActivityAnimation.getRunner());
+            } else if (mDefaultCrossActivityAnimation != null) {
+                mDefaultCrossActivityAnimation.prepareNextAnimation(null,
+                        backNavigationInfo.getLetterboxColor());
             }
         }
         BackAnimationRunner runner = mAnimationDefinition.get(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 dae62ac..30eb8b5d 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
@@ -18,6 +18,7 @@
 
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -109,7 +110,7 @@
     }
 
     /** Inflates split decor surface on the root surface. */
-    public void inflate(Context context, SurfaceControl rootLeash, Rect rootBounds) {
+    public void inflate(Context context, SurfaceControl rootLeash) {
         if (mIconLeash != null && mViewHost != null) {
             return;
         }
@@ -128,13 +129,12 @@
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 0 /* width */, 0 /* height */, TYPE_APPLICATION_OVERLAY,
                 FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT);
-        lp.width = rootBounds.width();
-        lp.height = rootBounds.height();
+        lp.width = mIconSize;
+        lp.height = mIconSize;
         lp.token = new Binder();
         lp.setTitle(TAG);
         lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
-        // TODO(b/189839391): Set INPUT_FEATURE_NO_INPUT_CHANNEL after WM supports
-        //  TRUSTED_OVERLAY for windowless window without input channel.
+        lp.inputFeatures |= INPUT_FEATURE_NO_INPUT_CHANNEL;
         mViewHost.setView(rootLayout, lp);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index c625b69..a7829c9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -27,6 +27,7 @@
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
 import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
 
+import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_CAN_HAND_OFF_ANIMATION;
 import static com.android.wm.shell.util.SplitBounds.KEY_EXTRA_SPLIT_BOUNDS;
 
 import android.annotation.Nullable;
@@ -54,6 +55,7 @@
 import android.window.TaskSnapshot;
 import android.window.TransitionInfo;
 import android.window.TransitionRequestInfo;
+import android.window.WindowAnimationState;
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
@@ -283,6 +285,7 @@
         private IBinder mTransition = null;
         private boolean mKeyguardLocked = false;
         private boolean mWillFinishToHome = false;
+        private Transitions.TransitionHandler mTakeoverHandler = null;
 
         /** The animation is idle, waiting for the user to choose a task to switch to. */
         private static final int STATE_NORMAL = 0;
@@ -576,9 +579,13 @@
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
                     "Applying transaction=%d", t.getId());
             t.apply();
-            Bundle b = new Bundle(1 /*capacity*/);
+
+            mTakeoverHandler = mTransitions.getHandlerForTakeover(mTransition, info);
+
+            Bundle b = new Bundle(2 /*capacity*/);
             b.putParcelable(KEY_EXTRA_SPLIT_BOUNDS,
                     mRecentTasksController.getSplitBoundsForTaskId(closingSplitTaskId));
+            b.putBoolean(KEY_EXTRA_SHELL_CAN_HAND_OFF_ANIMATION, mTakeoverHandler != null);
             try {
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
                         "[%d] RecentsController.start: calling onAnimationStart with %d apps",
@@ -597,6 +604,63 @@
             return true;
         }
 
+        @Override
+        public void handOffAnimation(
+                RemoteAnimationTarget[] targets, WindowAnimationState[] states) {
+            mExecutor.execute(() -> {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                        "[%d] RecentsController.handOffAnimation", mInstanceId);
+
+                if (mTakeoverHandler == null) {
+                    Slog.e(TAG, "Tried to hand off an animation without a valid takeover "
+                            + "handler.");
+                    return;
+                }
+
+                if (targets.length != states.length) {
+                    Slog.e(TAG, "Tried to hand off an animation, but the number of targets "
+                            + "(" + targets.length + ") doesn't match the number of states "
+                            + "(" + states.length + ")");
+                    return;
+                }
+
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                        "[%d] RecentsController.handOffAnimation: got %d states for %d "
+                                + "changes", mInstanceId, states.length, mInfo.getChanges().size());
+                WindowAnimationState[] updatedStates =
+                        new WindowAnimationState[mInfo.getChanges().size()];
+
+                // Ensure that the ordering of animation states is the same as that of  matching
+                // changes in mInfo. prefixOrderIndex is set up in reverse order to that of the
+                // changes, so that's what we use to get to the correct ordering.
+                for (int i = 0; i < targets.length; i++) {
+                    RemoteAnimationTarget target = targets[i];
+                    updatedStates[updatedStates.length - target.prefixOrderIndex] = states[i];
+                }
+
+                Transitions.TransitionFinishCallback finishCB = mFinishCB;
+                // Reset the callback here, so any stray calls that aren't coming from the new
+                // handler are ignored.
+                mFinishCB = null;
+
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                        "[%d] RecentsController.handOffAnimation: calling "
+                                + "takeOverAnimation with %d states", mInstanceId,
+                        updatedStates.length);
+                mTakeoverHandler.takeOverAnimation(
+                        mTransition, mInfo, new SurfaceControl.Transaction(),
+                        wct -> {
+                            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                                    "[%d] RecentsController.handOffAnimation: finish "
+                                            + "callback", mInstanceId);
+                            // Set the callback once again so we can finish correctly.
+                            mFinishCB = finishCB;
+                            finishInner(true /* toHome */, false /* userLeave */,
+                                    null /* finishCb */);
+                        }, updatedStates);
+            });
+        }
+
         /**
          * Updates this controller when a new transition is requested mid-recents transition.
          */
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 fadc970..4c68106 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
@@ -1762,10 +1762,8 @@
     void finishEnterSplitScreen(SurfaceControl.Transaction finishT) {
         ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "finishEnterSplitScreen");
         mSplitLayout.update(finishT, true /* resetImePosition */);
-        mMainStage.getSplitDecorManager().inflate(mContext, mMainStage.mRootLeash,
-                getMainStageBounds());
-        mSideStage.getSplitDecorManager().inflate(mContext, mSideStage.mRootLeash,
-                getSideStageBounds());
+        mMainStage.getSplitDecorManager().inflate(mContext, mMainStage.mRootLeash);
+        mSideStage.getSplitDecorManager().inflate(mContext, mSideStage.mRootLeash);
         setDividerVisibility(true, finishT);
         // Ensure divider surface are re-parented back into the hierarchy at the end of the
         // transition. See Transition#buildFinishTransaction for more detail.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index f33ab33..f41bca3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -218,8 +218,7 @@
             // Inflates split decor view only when the root task is visible.
             if (!ENABLE_SHELL_TRANSITIONS && mRootTaskInfo.isVisible != taskInfo.isVisible) {
                 if (taskInfo.isVisible) {
-                    mSplitDecorManager.inflate(mContext, mRootLeash,
-                            taskInfo.configuration.windowConfiguration.getBounds());
+                    mSplitDecorManager.inflate(mContext, mRootLeash);
                 } else {
                     mSyncQueue.runInSync(t -> mSplitDecorManager.release(t));
                 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
index da3aa4a..e552e6c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
@@ -30,7 +30,6 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.PixelFormat;
 import android.hardware.display.DisplayManager;
@@ -54,7 +53,6 @@
 import android.window.StartingWindowInfo;
 import android.window.StartingWindowRemovalInfo;
 
-import com.android.internal.R;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.ContrastColorUtil;
 import com.android.wm.shell.common.ShellExecutor;
@@ -206,7 +204,6 @@
                 final SplashWindowRecord record =
                         (SplashWindowRecord) mStartingWindowRecordManager.getRecord(taskId);
                 if (record != null) {
-                    record.parseAppSystemBarColor(context);
                     // Block until we get the background color.
                     final SplashScreenView contentView = viewSupplier.get();
                     if (suggestType != STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
@@ -427,8 +424,6 @@
 
         private boolean mSetSplashScreen;
         private SplashScreenView mSplashView;
-        private int mSystemBarAppearance;
-        private boolean mDrawsSystemBarBackgrounds;
 
         SplashWindowRecord(IBinder appToken, View decorView,
                 @StartingWindowInfo.StartingWindowType int suggestType) {
@@ -448,19 +443,6 @@
             mSetSplashScreen = true;
         }
 
-        void parseAppSystemBarColor(Context context) {
-            final TypedArray a = context.obtainStyledAttributes(R.styleable.Window);
-            mDrawsSystemBarBackgrounds = a.getBoolean(
-                    R.styleable.Window_windowDrawsSystemBarBackgrounds, false);
-            if (a.getBoolean(R.styleable.Window_windowLightStatusBar, false)) {
-                mSystemBarAppearance |= WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
-            }
-            if (a.getBoolean(R.styleable.Window_windowLightNavigationBar, false)) {
-                mSystemBarAppearance |= WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
-            }
-            a.recycle();
-        }
-
         @Override
         public boolean removeIfPossible(StartingWindowRemovalInfo info, boolean immediately) {
             if (mRootView == null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellSharedConstants.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellSharedConstants.java
index 56c0d0e..c886cc9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellSharedConstants.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellSharedConstants.java
@@ -42,4 +42,7 @@
     public static final String KEY_EXTRA_SHELL_DESKTOP_MODE = "extra_shell_desktop_mode";
     // See IDragAndDrop.aidl
     public static final String KEY_EXTRA_SHELL_DRAG_AND_DROP = "extra_shell_drag_and_drop";
+    // See IRecentsAnimationController.aidl
+    public static final String KEY_EXTRA_SHELL_CAN_HAND_OFF_ANIMATION =
+            "extra_shell_can_hand_off_animation";
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
index 94519a0..69c4167 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java
@@ -27,6 +27,7 @@
 import android.window.RemoteTransition;
 import android.window.TransitionInfo;
 import android.window.TransitionRequestInfo;
+import android.window.WindowAnimationState;
 import android.window.WindowContainerTransaction;
 
 import com.android.internal.protolog.common.ProtoLog;
@@ -65,30 +66,9 @@
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Using registered One-shot remote"
                 + " transition %s for (#%d).", mRemote, info.getDebugId());
 
-        final IBinder.DeathRecipient remoteDied = () -> {
-            Log.e(Transitions.TAG, "Remote transition died, finishing");
-            mMainExecutor.execute(
-                    () -> finishCallback.onTransitionFinished(null /* wct */));
-        };
-        IRemoteTransitionFinishedCallback cb = new IRemoteTransitionFinishedCallback.Stub() {
-            @Override
-            public void onTransitionFinished(WindowContainerTransaction wct,
-                    SurfaceControl.Transaction sct) {
-                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
-                        "Finished one-shot remote transition %s for (#%d).", mRemote,
-                        info.getDebugId());
-                if (mRemote.asBinder() != null) {
-                    mRemote.asBinder().unlinkToDeath(remoteDied, 0 /* flags */);
-                }
-                if (sct != null) {
-                    finishTransaction.merge(sct);
-                }
-                mMainExecutor.execute(() -> {
-                    finishCallback.onTransitionFinished(wct);
-                    mRemote = null;
-                });
-            }
-        };
+        final IBinder.DeathRecipient remoteDied = createDeathRecipient(finishCallback);
+        IRemoteTransitionFinishedCallback cb =
+                createFinishedCallback(info, finishTransaction, finishCallback, remoteDied);
         Transitions.setRunningRemoteTransitionDelegate(mRemote.getAppThread());
         try {
             if (mRemote.asBinder() != null) {
@@ -152,6 +132,51 @@
     }
 
     @Override
+    public boolean takeOverAnimation(
+            @NonNull IBinder transition, @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction transaction,
+            @NonNull Transitions.TransitionFinishCallback finishCallback,
+            @NonNull WindowAnimationState[] states) {
+        if (mTransition != transition) return false;
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "Using registered One-shot "
+                + "remote transition %s to take over (#%d).", mRemote, info.getDebugId());
+
+        final IBinder.DeathRecipient remoteDied = createDeathRecipient(finishCallback);
+        IRemoteTransitionFinishedCallback cb = createFinishedCallback(
+                info, null /* finishTransaction */, finishCallback, remoteDied);
+
+        Transitions.setRunningRemoteTransitionDelegate(mRemote.getAppThread());
+
+        try {
+            if (mRemote.asBinder() != null) {
+                mRemote.asBinder().linkToDeath(remoteDied, 0 /* flags */);
+            }
+
+            // If the remote is actually in the same process, then make a copy of parameters since
+            // remote impls assume that they have to clean-up native references.
+            final SurfaceControl.Transaction remoteStartT =
+                    RemoteTransitionHandler.copyIfLocal(transaction, mRemote.getRemoteTransition());
+            final TransitionInfo remoteInfo =
+                    remoteStartT == transaction ? info : info.localRemoteCopy();
+            mRemote.getRemoteTransition().takeOverAnimation(
+                    transition, remoteInfo, remoteStartT, cb, states);
+
+            // Assume that remote will apply the transaction.
+            transaction.clear();
+            return true;
+        } catch (RemoteException e) {
+            Log.e(Transitions.TAG, "Error running remote transition takeover.", e);
+            if (mRemote.asBinder() != null) {
+                mRemote.asBinder().unlinkToDeath(remoteDied, 0 /* flags */);
+            }
+            finishCallback.onTransitionFinished(null /* wct */);
+            mRemote = null;
+        }
+
+        return false;
+    }
+
+    @Override
     @Nullable
     public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
             @Nullable TransitionRequestInfo request) {
@@ -174,6 +199,41 @@
         }
     }
 
+    private IBinder.DeathRecipient createDeathRecipient(
+            Transitions.TransitionFinishCallback finishCallback) {
+        return () -> {
+            Log.e(Transitions.TAG, "Remote transition died, finishing");
+            mMainExecutor.execute(
+                    () -> finishCallback.onTransitionFinished(null /* wct */));
+        };
+    }
+
+    private IRemoteTransitionFinishedCallback createFinishedCallback(
+            @NonNull TransitionInfo info,
+            @Nullable SurfaceControl.Transaction finishTransaction,
+            @NonNull Transitions.TransitionFinishCallback finishCallback,
+            @NonNull IBinder.DeathRecipient remoteDied) {
+        return new IRemoteTransitionFinishedCallback.Stub() {
+            @Override
+            public void onTransitionFinished(WindowContainerTransaction wct,
+                    SurfaceControl.Transaction sct) {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
+                        "Finished one-shot remote transition %s for (#%d).", mRemote,
+                        info.getDebugId());
+                if (mRemote.asBinder() != null) {
+                    mRemote.asBinder().unlinkToDeath(remoteDied, 0 /* flags */);
+                }
+                if (finishTransaction != null && sct != null) {
+                    finishTransaction.merge(sct);
+                }
+                mMainExecutor.execute(() -> {
+                    finishCallback.onTransitionFinished(wct);
+                    mRemote = null;
+                });
+            }
+        };
+    }
+
     @Override
     public String toString() {
         return "OneShotRemoteHandler:" + mRemote.getDebugName() + ":"
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
index 4c4c580..d686046 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java
@@ -16,6 +16,8 @@
 
 package com.android.wm.shell.transition;
 
+import static com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.IBinder;
@@ -32,6 +34,7 @@
 import android.window.TransitionFilter;
 import android.window.TransitionInfo;
 import android.window.TransitionRequestInfo;
+import android.window.WindowAnimationState;
 import android.window.WindowContainerTransaction;
 
 import androidx.annotation.BinderThread;
@@ -41,7 +44,9 @@
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.shared.TransitionUtil;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 
 /**
  * Handler that deals with RemoteTransitions. It will only request to handle a transition
@@ -58,6 +63,8 @@
     /** Ordered by specificity. Last filters will be checked first */
     private final ArrayList<Pair<TransitionFilter, RemoteTransition>> mFilters =
             new ArrayList<>();
+    private final ArrayList<Pair<TransitionFilter, RemoteTransition>> mTakeoverFilters =
+            new ArrayList<>();
 
     private final ArrayMap<IBinder, RemoteDeathHandler> mDeathHandlers = new ArrayMap<>();
 
@@ -70,14 +77,23 @@
         mFilters.add(new Pair<>(filter, remote));
     }
 
+    void addFilteredForTakeover(TransitionFilter filter, RemoteTransition remote) {
+        handleDeath(remote.asBinder(), null /* finishCallback */);
+        mTakeoverFilters.add(new Pair<>(filter, remote));
+    }
+
     void removeFiltered(RemoteTransition remote) {
         boolean removed = false;
-        for (int i = mFilters.size() - 1; i >= 0; --i) {
-            if (mFilters.get(i).second.asBinder().equals(remote.asBinder())) {
-                mFilters.remove(i);
-                removed = true;
+        for (ArrayList<Pair<TransitionFilter, RemoteTransition>> filters
+                : Arrays.asList(mFilters, mTakeoverFilters)) {
+            for (int i = filters.size() - 1; i >= 0; --i) {
+                if (filters.get(i).second.asBinder().equals(remote.asBinder())) {
+                    filters.remove(i);
+                    removed = true;
+                }
             }
         }
+
         if (removed) {
             unhandleDeath(remote.asBinder(), null /* finishCallback */);
         }
@@ -237,6 +253,47 @@
         }
     }
 
+    @Nullable
+    @Override
+    public Transitions.TransitionHandler getHandlerForTakeover(
+            @NonNull IBinder transition, @NonNull TransitionInfo info) {
+        if (!returnAnimationFrameworkLibrary()) {
+            return null;
+        }
+
+        for (Pair<TransitionFilter, RemoteTransition> registered : mTakeoverFilters) {
+            if (registered.first.matches(info)) {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                        "Found matching remote to takeover (#%d)", info.getDebugId());
+
+                OneShotRemoteHandler oneShot =
+                        new OneShotRemoteHandler(mMainExecutor, registered.second);
+                oneShot.setTransition(transition);
+                return oneShot;
+            }
+        }
+
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                "No matching remote found to takeover (#%d)", info.getDebugId());
+        return null;
+    }
+
+    @Override
+    public boolean takeOverAnimation(
+            @NonNull IBinder transition, @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction transaction,
+            @NonNull Transitions.TransitionFinishCallback finishCallback,
+            @NonNull WindowAnimationState[] states) {
+        Transitions.TransitionHandler handler = getHandlerForTakeover(transition, info);
+        if (handler == null) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                    "Take over request failed: no matching remote for (#%d)", info.getDebugId());
+            return false;
+        }
+        ((OneShotRemoteHandler) handler).setTransition(transition);
+        return handler.takeOverAnimation(transition, info, transaction, finishCallback, states);
+    }
+
     @Override
     @Nullable
     public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
@@ -284,6 +341,34 @@
         }
     }
 
+    void dump(@NonNull PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+
+        pw.println(prefix + "Registered Remotes:");
+        if (mFilters.isEmpty()) {
+            pw.println(innerPrefix + "none");
+        } else {
+            for (Pair<TransitionFilter, RemoteTransition> entry : mFilters) {
+                dumpRemote(pw, innerPrefix, entry.second);
+            }
+        }
+
+        pw.println(prefix + "Registered Takeover Remotes:");
+        if (mTakeoverFilters.isEmpty()) {
+            pw.println(innerPrefix + "none");
+        } else {
+            for (Pair<TransitionFilter, RemoteTransition> entry : mTakeoverFilters) {
+                dumpRemote(pw, innerPrefix, entry.second);
+            }
+        }
+    }
+
+    private void dumpRemote(@NonNull PrintWriter pw, String prefix, RemoteTransition remote) {
+        pw.print(prefix);
+        pw.print(remote.getDebugName());
+        pw.println(" (" + Integer.toHexString(System.identityHashCode(remote)) + ")");
+    }
+
     /** NOTE: binder deaths can alter the filter order */
     private class RemoteDeathHandler implements IBinder.DeathRecipient {
         private final IBinder mRemote;
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 437a00e..9b2922d 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
@@ -35,6 +35,7 @@
 import static android.window.TransitionInfo.FLAG_NO_ANIMATION;
 import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
 
+import static com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary;
 import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 import static com.android.wm.shell.shared.TransitionUtil.isClosingType;
 import static com.android.wm.shell.shared.TransitionUtil.isOpeningType;
@@ -43,9 +44,11 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityTaskManager;
+import android.app.AppGlobals;
 import android.app.IApplicationThread;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.os.Handler;
 import android.os.IBinder;
@@ -62,6 +65,7 @@
 import android.window.TransitionInfo;
 import android.window.TransitionMetrics;
 import android.window.TransitionRequestInfo;
+import android.window.WindowAnimationState;
 import android.window.WindowContainerTransaction;
 
 import androidx.annotation.BinderThread;
@@ -124,8 +128,7 @@
     static final String TAG = "ShellTransitions";
 
     /** Set to {@code true} to enable shell transitions. */
-    public static final boolean ENABLE_SHELL_TRANSITIONS =
-            SystemProperties.getBoolean("persist.wm.debug.shell_transit", true);
+    public static final boolean ENABLE_SHELL_TRANSITIONS = getShellTransitEnabled();
     public static final boolean SHELL_TRANSITIONS_ROTATION = ENABLE_SHELL_TRANSITIONS
             && SystemProperties.getBoolean("persist.wm.debug.shell_transit_rotate", false);
 
@@ -419,12 +422,24 @@
         mHandlers.set(0, handler);
     }
 
-    /** Register a remote transition to be used when `filter` matches an incoming transition */
+    /**
+     * Register a remote transition to be used for all operations except takeovers when `filter`
+     * matches an incoming transition.
+     */
     public void registerRemote(@NonNull TransitionFilter filter,
             @NonNull RemoteTransition remoteTransition) {
         mRemoteTransitionHandler.addFiltered(filter, remoteTransition);
     }
 
+    /**
+     * Register a remote transition to be used for all operations except takeovers when `filter`
+     * matches an incoming transition.
+     */
+    public void registerRemoteForTakeover(@NonNull TransitionFilter filter,
+            @NonNull RemoteTransition remoteTransition) {
+        mRemoteTransitionHandler.addFilteredForTakeover(filter, remoteTransition);
+    }
+
     /** Unregisters a remote transition and all associated filters */
     public void unregisterRemote(@NonNull RemoteTransition remoteTransition) {
         mRemoteTransitionHandler.removeFiltered(remoteTransition);
@@ -1187,6 +1202,29 @@
     }
 
     /**
+     * Checks whether a handler exists capable of taking over the given transition, and returns it.
+     * Otherwise it returns null.
+     */
+    @Nullable
+    public TransitionHandler getHandlerForTakeover(
+            @NonNull IBinder transition, @NonNull TransitionInfo info) {
+        if (!returnAnimationFrameworkLibrary()) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                    "Trying to get a handler for takeover but the flag is disabled");
+            return null;
+        }
+
+        for (TransitionHandler handler : mHandlers) {
+            TransitionHandler candidate = handler.getHandlerForTakeover(transition, info);
+            if (candidate != null) {
+                return candidate;
+            }
+        }
+
+        return null;
+    }
+
+    /**
      * Finish running animations (almost) immediately when a SLEEP transition comes in. We use this
      * as both a way to reduce unnecessary work (animations not visible while screen off) and as a
      * failsafe to unblock "stuck" animations (in particular remote animations).
@@ -1328,6 +1366,49 @@
                 @NonNull TransitionFinishCallback finishCallback) { }
 
         /**
+         * Checks whether this handler is capable of taking over a transition matching `info`.
+         * {@link TransitionHandler#takeOverAnimation(IBinder, TransitionInfo,
+         * SurfaceControl.Transaction, TransitionFinishCallback, WindowAnimationState[])} is
+         * guaranteed to succeed if called on the handler returned by this method.
+         *
+         * Note that the handler returned by this method can either be itself, or a different one
+         * selected by this handler to take care of the transition on its behalf.
+         *
+         * @param transition The transition that should be taken over.
+         * @param info Information about the transition to be taken over.
+         * @return A handler capable of taking over a matching transition, or null.
+         */
+        @Nullable
+        default TransitionHandler getHandlerForTakeover(
+                @NonNull IBinder transition, @NonNull TransitionInfo info) {
+            return null;
+        }
+
+        /**
+         * Attempt to take over a running transition. This must succeed if this handler was returned
+         * by {@link TransitionHandler#getHandlerForTakeover(IBinder, TransitionInfo)}.
+         *
+         * @param transition The transition that should be taken over.
+         * @param info Information about the what is changing in the transition.
+         * @param transaction Contains surface changes that resulted from the transition. Any
+         *                    additional changes should be added to this transaction and committed
+         *                    inside this method.
+         * @param finishCallback Call this at the end of the animation, if the take-over succeeds.
+         *                       Note that this will be called instead of the callback originally
+         *                       passed to startAnimation(), so the caller should make sure all
+         *                       necessary cleanup happens here. This MUST be called on main thread.
+         * @param states The animation states of the transition's window at the time this method was
+         *               called.
+         * @return true if the transition was taken over, false if not.
+         */
+        default boolean takeOverAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+                @NonNull SurfaceControl.Transaction transaction,
+                @NonNull TransitionFinishCallback finishCallback,
+                @NonNull WindowAnimationState[] states) {
+            return false;
+        }
+
+        /**
          * Potentially handles a startTransition request.
          *
          * @param transition The transition whose start is being requested.
@@ -1432,16 +1513,21 @@
         @Override
         public void registerRemote(@NonNull TransitionFilter filter,
                 @NonNull RemoteTransition remoteTransition) {
-            mMainExecutor.execute(() -> {
-                mRemoteTransitionHandler.addFiltered(filter, remoteTransition);
-            });
+            mMainExecutor.execute(
+                    () -> mRemoteTransitionHandler.addFiltered(filter, remoteTransition));
+        }
+
+        @Override
+        public void registerRemoteForTakeover(@NonNull TransitionFilter filter,
+                @NonNull RemoteTransition remoteTransition) {
+            mMainExecutor.execute(() -> mRemoteTransitionHandler.addFilteredForTakeover(
+                    filter, remoteTransition));
         }
 
         @Override
         public void unregisterRemote(@NonNull RemoteTransition remoteTransition) {
-            mMainExecutor.execute(() -> {
-                mRemoteTransitionHandler.removeFiltered(remoteTransition);
-            });
+            mMainExecutor.execute(
+                    () -> mRemoteTransitionHandler.removeFiltered(remoteTransition));
         }
     }
 
@@ -1470,17 +1556,23 @@
         public void registerRemote(@NonNull TransitionFilter filter,
                 @NonNull RemoteTransition remoteTransition) {
             executeRemoteCallWithTaskPermission(mTransitions, "registerRemote",
-                    (transitions) -> {
-                        transitions.mRemoteTransitionHandler.addFiltered(filter, remoteTransition);
-                    });
+                    (transitions) -> transitions.mRemoteTransitionHandler.addFiltered(
+                            filter, remoteTransition));
+        }
+
+        @Override
+        public void registerRemoteForTakeover(@NonNull TransitionFilter filter,
+                @NonNull RemoteTransition remoteTransition) {
+            executeRemoteCallWithTaskPermission(mTransitions, "registerRemoteForTakeover",
+                    (transitions) -> transitions.mRemoteTransitionHandler.addFilteredForTakeover(
+                            filter, remoteTransition));
         }
 
         @Override
         public void unregisterRemote(@NonNull RemoteTransition remoteTransition) {
             executeRemoteCallWithTaskPermission(mTransitions, "unregisterRemote",
-                    (transitions) -> {
-                        transitions.mRemoteTransitionHandler.removeFiltered(remoteTransition);
-                    });
+                    (transitions) ->
+                            transitions.mRemoteTransitionHandler.removeFiltered(remoteTransition));
         }
 
         @Override
@@ -1565,6 +1657,8 @@
             pw.println(" (" + Integer.toHexString(System.identityHashCode(handler)) + ")");
         }
 
+        mRemoteTransitionHandler.dump(pw, prefix);
+
         pw.println(prefix + "Observers:");
         for (TransitionObserver observer : mObservers) {
             pw.print(innerPrefix);
@@ -1617,4 +1711,16 @@
             }
         }
     }
+
+    private static boolean getShellTransitEnabled() {
+        try {
+            if (AppGlobals.getPackageManager().hasSystemFeature(
+                    PackageManager.FEATURE_AUTOMOTIVE, 0)) {
+                return SystemProperties.getBoolean("persist.wm.debug.shell_transit", true);
+            }
+        } catch (RemoteException re) {
+            Log.w(TAG, "Error getting system features");
+        }
+        return true;
+    }
 }
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
index 43fd32b..6671391 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -200,7 +200,6 @@
         mRelayoutParams.mShadowRadiusId = shadowRadiusID;
         mRelayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
         mRelayoutParams.mSetTaskPositionAndCrop = setTaskCropAndPosition;
-        mRelayoutParams.mAllowCaptionInputFallthrough = false;
 
         relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
         // After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
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 6a9d17f..922c55f 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
@@ -1037,7 +1037,6 @@
                         mSyncQueue,
                         mRootTaskDisplayAreaOrganizer);
         mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
-        windowDecoration.createResizeVeil();
 
         final DragPositioningCallback dragPositioningCallback;
         if (!DesktopModeStatus.isVeiledResizeEnabled()) {
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 da1699c..cb6495c 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
@@ -44,6 +44,7 @@
 import android.graphics.Region;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
+import android.os.Trace;
 import android.util.Log;
 import android.util.Size;
 import android.view.Choreographer;
@@ -51,6 +52,7 @@
 import android.view.SurfaceControl;
 import android.view.View;
 import android.view.ViewConfiguration;
+import android.view.WindowManager;
 import android.widget.ImageButton;
 import android.window.WindowContainerTransaction;
 
@@ -107,8 +109,6 @@
     private MaximizeMenu mMaximizeMenu;
 
     private ResizeVeil mResizeVeil;
-
-    private Drawable mAppIconDrawable;
     private Bitmap mAppIconBitmap;
     private CharSequence mAppName;
 
@@ -160,7 +160,9 @@
         mSyncQueue = syncQueue;
         mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
 
+        Trace.beginSection("DesktopModeWindowDecoration#loadAppInfo");
         loadAppInfo();
+        Trace.endSection();
     }
 
     void setCaptionListeners(
@@ -206,6 +208,7 @@
     void relayout(ActivityManager.RunningTaskInfo taskInfo,
             SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
             boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop) {
+        Trace.beginSection("DesktopModeWindowDecoration#relayout");
         if (isHandleMenuActive()) {
             mHandleMenu.relayout(startT);
         }
@@ -217,16 +220,22 @@
         final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
         final WindowContainerTransaction wct = new WindowContainerTransaction();
 
+        Trace.beginSection("DesktopModeWindowDecoration#relayout-inner");
         relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
+        Trace.endSection();
         // After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
 
+        Trace.beginSection("DesktopModeWindowDecoration#relayout-applyWCT");
         mTaskOrganizer.applyTransaction(wct);
+        Trace.endSection();
 
         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.
+            Trace.endSection(); // DesktopModeWindowDecoration#relayout
             return;
         }
+
         if (oldRootView != mResult.mRootView) {
             if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_focused_window_decor) {
                 mWindowDecorViewHolder = new DesktopModeFocusedWindowDecorationViewHolder(
@@ -254,7 +263,9 @@
                 throw new IllegalArgumentException("Unexpected layout resource id");
             }
         }
+        Trace.beginSection("DesktopModeWindowDecoration#relayout-binding");
         mWindowDecorViewHolder.bindData(mTaskInfo);
+        Trace.endSection();
 
         if (!mTaskInfo.isFocused) {
             closeHandleMenu();
@@ -270,11 +281,13 @@
                 updateExclusionRegion();
             }
             closeDragResizeListener();
+            Trace.endSection(); // DesktopModeWindowDecoration#relayout
             return;
         }
 
         if (oldDecorationSurface != mDecorationContainerSurface || mDragResizeListener == null) {
             closeDragResizeListener();
+            Trace.beginSection("DesktopModeWindowDecoration#relayout-DragResizeInputListener");
             mDragResizeListener = new DragResizeInputListener(
                     mContext,
                     mHandler,
@@ -285,6 +298,7 @@
                     mSurfaceControlBuilderSupplier,
                     mSurfaceControlTransactionSupplier,
                     mDisplayController);
+            Trace.endSection();
         }
 
         final int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext())
@@ -309,6 +323,7 @@
                 mMaximizeMenu.positionMenu(calculateMaximizeMenuPosition(), startT);
             }
         }
+        Trace.endSection(); // DesktopModeWindowDecoration#relayout
     }
 
     @VisibleForTesting
@@ -326,11 +341,12 @@
         relayoutParams.mCaptionWidthId = getCaptionWidthId(relayoutParams.mLayoutResId);
 
         if (captionLayoutId == R.layout.desktop_mode_app_controls_window_decor) {
-            // If the app is requesting to customize the caption bar, allow input to fall through
-            // to the windows below so that the app can respond to input events on their custom
-            // content.
-            relayoutParams.mAllowCaptionInputFallthrough =
-                    TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo);
+            if (TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo)) {
+                // If the app is requesting to customize the caption bar, allow input to fall
+                // through to the windows below so that the app can respond to input events on
+                // their custom content.
+                relayoutParams.mInputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY;
+            }
             // Report occluding elements as bounding rects to the insets system so that apps can
             // draw in the empty space in the center:
             //   First, the "app chip" section of the caption bar (+ some extra margins).
@@ -345,6 +361,11 @@
             controlsElement.mWidthResId = R.dimen.desktop_mode_customizable_caption_margin_end;
             controlsElement.mAlignment = RelayoutParams.OccludingCaptionElement.Alignment.END;
             relayoutParams.mOccludingCaptionElements.add(controlsElement);
+        } else if (captionLayoutId == R.layout.desktop_mode_focused_window_decor) {
+            // The focused decor (fullscreen/split) does not need to handle input because input in
+            // the App Handle is handled by the InputMonitor in DesktopModeWindowDecorViewModel.
+            relayoutParams.mInputFeatures
+                    |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
         }
         if (DesktopModeStatus.useWindowShadow(/* isFocusedWindow= */ taskInfo.isFocused)) {
             relayoutParams.mShadowRadiusId = taskInfo.isFocused
@@ -444,12 +465,12 @@
         }
         PackageManager pm = mContext.getApplicationContext().getPackageManager();
         final IconProvider provider = new IconProvider(mContext);
-        mAppIconDrawable = provider.getIcon(activityInfo);
+        final Drawable appIconDrawable = provider.getIcon(activityInfo);
         final Resources resources = mContext.getResources();
         final BaseIconFactory factory = new BaseIconFactory(mContext,
                 resources.getDisplayMetrics().densityDpi,
                 resources.getDimensionPixelSize(R.dimen.desktop_mode_caption_icon_radius));
-        mAppIconBitmap = factory.createScaledBitmap(mAppIconDrawable, MODE_DEFAULT);
+        mAppIconBitmap = factory.createScaledBitmap(appIconDrawable, MODE_DEFAULT);
         final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
         mAppName = pm.getApplicationLabel(applicationInfo);
     }
@@ -466,8 +487,9 @@
      * Create the resize veil for this task. Note the veil's visibility is View.GONE by default
      * until a resize event calls showResizeVeil below.
      */
-    void createResizeVeil() {
-        mResizeVeil = new ResizeVeil(mContext, mDisplayController, mAppIconDrawable, mTaskInfo,
+    private void createResizeVeilIfNeeded() {
+        if (mResizeVeil != null) return;
+        mResizeVeil = new ResizeVeil(mContext, mDisplayController, mAppIconBitmap, mTaskInfo,
                 mTaskSurface, mSurfaceControlTransactionSupplier);
     }
 
@@ -475,6 +497,7 @@
      * Show the resize veil.
      */
     public void showResizeVeil(Rect taskBounds) {
+        createResizeVeilIfNeeded();
         mResizeVeil.showVeil(mTaskSurface, taskBounds);
     }
 
@@ -482,6 +505,7 @@
      * Show the resize veil.
      */
     public void showResizeVeil(SurfaceControl.Transaction tx, Rect taskBounds) {
+        createResizeVeilIfNeeded();
         mResizeVeil.showVeil(tx, mTaskSurface, taskBounds, false /* fadeIn */);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java
index 2c4092a..93e2a21 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.java
@@ -24,11 +24,12 @@
 import android.app.ActivityManager.RunningTaskInfo;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.PixelFormat;
 import android.graphics.PointF;
 import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
+import android.os.Trace;
 import android.view.Display;
 import android.view.LayoutInflater;
 import android.view.SurfaceControl;
@@ -64,7 +65,7 @@
     private final SurfaceControlBuilderFactory mSurfaceControlBuilderFactory;
     private final WindowDecoration.SurfaceControlViewHostFactory mSurfaceControlViewHostFactory;
     private final SurfaceSession mSurfaceSession = new SurfaceSession();
-    private final Drawable mAppIcon;
+    private final Bitmap mAppIcon;
     private ImageView mIconView;
     private int mIconSize;
     private SurfaceControl mParentSurface;
@@ -97,7 +98,7 @@
 
     public ResizeVeil(Context context,
             @NonNull DisplayController displayController,
-            Drawable appIcon, RunningTaskInfo taskInfo,
+            Bitmap appIcon, RunningTaskInfo taskInfo,
             SurfaceControl taskSurface,
             Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier) {
         this(context,
@@ -112,7 +113,7 @@
 
     public ResizeVeil(Context context,
             @NonNull DisplayController displayController,
-            Drawable appIcon, RunningTaskInfo taskInfo,
+            Bitmap appIcon, RunningTaskInfo taskInfo,
             SurfaceControl taskSurface,
             Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
             SurfaceControlBuilderFactory surfaceControlBuilderFactory,
@@ -135,6 +136,7 @@
             // Display may not be available yet, skip this until then.
             return;
         }
+        Trace.beginSection("ResizeVeil#setupResizeVeil");
         mVeilSurface = mSurfaceControlBuilderFactory
                 .create("Resize veil of Task=" + mTaskInfo.taskId)
                 .setContainerLayer()
@@ -162,7 +164,7 @@
         final View root = LayoutInflater.from(mContext)
                 .inflate(R.layout.desktop_mode_resize_veil, null /* root */);
         mIconView = root.findViewById(R.id.veil_application_icon);
-        mIconView.setImageDrawable(mAppIcon);
+        mIconView.setImageBitmap(mAppIcon);
 
         final WindowManager.LayoutParams lp =
                 new WindowManager.LayoutParams(
@@ -179,6 +181,7 @@
 
         mViewHost = mSurfaceControlViewHostFactory.create(mContext, mDisplay, wwm, "ResizeVeil");
         mViewHost.setView(root, lp);
+        Trace.endSection();
     }
 
     private boolean obtainDisplayOrRegisterListener() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 36da1ac..54656ff 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -33,6 +33,7 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Binder;
+import android.os.Trace;
 import android.view.Display;
 import android.view.InsetsSource;
 import android.view.InsetsState;
@@ -311,7 +312,7 @@
                 boundingRects = null;
             } else {
                 // The customizable region can at most be equal to the caption bar.
-                if (params.mAllowCaptionInputFallthrough) {
+                if (params.hasInputFeatureSpy()) {
                     outResult.mCustomizableCaptionRegion.set(mCaptionInsetsRect);
                 }
                 boundingRects = new Rect[numOfElements];
@@ -324,7 +325,7 @@
                             calculateBoundingRect(element, elementWidthPx, mCaptionInsetsRect);
                     // Subtract the regions used by the caption elements, the rest is
                     // customizable.
-                    if (params.mAllowCaptionInputFallthrough) {
+                    if (params.hasInputFeatureSpy()) {
                         outResult.mCustomizableCaptionRegion.op(boundingRects[i],
                                 Region.Op.DIFFERENCE);
                     }
@@ -378,6 +379,7 @@
             startT.unsetColor(mTaskSurface);
         }
 
+        Trace.beginSection("CaptionViewHostLayout");
         if (mCaptionWindowManager == null) {
             // Put caption under a container surface because ViewRootImpl sets the destination frame
             // of windowless window layers and BLASTBufferQueue#update() doesn't support offset.
@@ -394,11 +396,7 @@
                         WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
         lp.setTitle("Caption of Task=" + mTaskInfo.taskId);
         lp.setTrustedOverlay();
-        if (params.mAllowCaptionInputFallthrough) {
-            lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY;
-        } else {
-            lp.inputFeatures &= ~WindowManager.LayoutParams.INPUT_FEATURE_SPY;
-        }
+        lp.inputFeatures = params.mInputFeatures;
         if (mViewHost == null) {
             mViewHost = mSurfaceControlViewHostFactory.create(mDecorWindowContext, mDisplay,
                     mCaptionWindowManager);
@@ -412,6 +410,7 @@
             }
             mViewHost.relayout(lp);
         }
+        Trace.endSection(); // CaptionViewHostLayout
     }
 
     private Rect calculateBoundingRect(@NonNull OccludingCaptionElement element,
@@ -605,7 +604,7 @@
         int mCaptionHeightId;
         int mCaptionWidthId;
         final List<OccludingCaptionElement> mOccludingCaptionElements = new ArrayList<>();
-        boolean mAllowCaptionInputFallthrough;
+        int mInputFeatures;
 
         int mShadowRadiusId;
         int mCornerRadius;
@@ -620,7 +619,7 @@
             mCaptionHeightId = Resources.ID_NULL;
             mCaptionWidthId = Resources.ID_NULL;
             mOccludingCaptionElements.clear();
-            mAllowCaptionInputFallthrough = false;
+            mInputFeatures = 0;
 
             mShadowRadiusId = Resources.ID_NULL;
             mCornerRadius = 0;
@@ -630,6 +629,10 @@
             mWindowDecorConfig = null;
         }
 
+        boolean hasInputFeatureSpy() {
+            return (mInputFeatures & WindowManager.LayoutParams.INPUT_FEATURE_SPY) != 0;
+        }
+
         /**
          * Describes elements within the caption bar that could occlude app content, and should be
          * sent as bounding rectangles to the insets system.
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/CustomizeActivityAnimationTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/CustomizeActivityAnimationTest.java
index cebbbd8..158d640 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/CustomizeActivityAnimationTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/CustomizeActivityAnimationTest.java
@@ -96,7 +96,7 @@
                 .loadAnimation(any(), eq(true));
 
         mCustomizeActivityAnimation.prepareNextAnimation(
-                new BackNavigationInfo.CustomAnimationInfo("TestPackage"));
+                new BackNavigationInfo.CustomAnimationInfo("TestPackage"), 0);
         final RemoteAnimationTarget close = createAnimationTarget(false);
         final RemoteAnimationTarget open = createAnimationTarget(true);
         // start animation with remote animation targets
@@ -129,7 +129,7 @@
                 .loadAnimation(any(), eq(true));
 
         mCustomizeActivityAnimation.prepareNextAnimation(
-                new BackNavigationInfo.CustomAnimationInfo("TestPackage"));
+                new BackNavigationInfo.CustomAnimationInfo("TestPackage"), 0);
         final RemoteAnimationTarget close = createAnimationTarget(false);
         final RemoteAnimationTarget open = createAnimationTarget(true);
         // start animation with remote animation targets
@@ -155,7 +155,7 @@
     @Test
     public void receiveFinishWithoutAnimationAfterInvoke() throws InterruptedException {
         mCustomizeActivityAnimation.prepareNextAnimation(
-                new BackNavigationInfo.CustomAnimationInfo("TestPackage"));
+                new BackNavigationInfo.CustomAnimationInfo("TestPackage"), 0);
         // start animation without any remote animation targets
         final CountDownLatch finishCalled = new CountDownLatch(1);
         final Runnable finishCallback = finishCalled::countDown;
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 2366917..964d86e 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
@@ -73,6 +73,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.util.ArraySet;
 import android.util.Pair;
 import android.view.IRecentsAnimationRunner;
@@ -87,6 +88,7 @@
 import android.window.TransitionFilter;
 import android.window.TransitionInfo;
 import android.window.TransitionRequestInfo;
+import android.window.WindowAnimationState;
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
@@ -98,6 +100,7 @@
 
 import com.android.internal.R;
 import com.android.internal.policy.TransitionAnimation;
+import com.android.systemui.shared.Flags;
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
@@ -114,6 +117,7 @@
 import com.android.wm.shell.util.StubTransaction;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
@@ -141,6 +145,9 @@
     private final TestTransitionHandler mDefaultHandler = new TestTransitionHandler();
     private final Handler mMainHandler = new Handler(Looper.getMainLooper());
 
+    @Rule
+    public final SetFlagsRule setFlagsRule = new SetFlagsRule();
+
     @Before
     public void setUp() {
         doAnswer(invocation -> new Binder())
@@ -475,11 +482,97 @@
     }
 
     @Test
+    public void testRegisteredRemoteTransitionTakeover() {
+        Transitions transitions = createTestTransitions();
+        transitions.replaceDefaultHandlerForTest(mDefaultHandler);
+
+        IRemoteTransition testRemote = new RemoteTransitionStub() {
+            @Override
+            public void startAnimation(IBinder token, TransitionInfo info,
+                    SurfaceControl.Transaction t,
+                    IRemoteTransitionFinishedCallback finishCallback) throws RemoteException {
+                final Transitions.TransitionHandler takeoverHandler =
+                        transitions.getHandlerForTakeover(token, info);
+
+                if (takeoverHandler == null) {
+                    finishCallback.onTransitionFinished(null /* wct */, null /* sct */);
+                    return;
+                }
+
+                takeoverHandler.takeOverAnimation(token, info, new SurfaceControl.Transaction(),
+                        wct -> {
+                            try {
+                                finishCallback.onTransitionFinished(wct, null /* sct */);
+                            } catch (RemoteException e) {
+                                // Fail
+                            }
+                        }, new WindowAnimationState[info.getChanges().size()]);
+            }
+        };
+        final boolean[] takeoverRemoteCalled = new boolean[]{false};
+        IRemoteTransition testTakeoverRemote = new RemoteTransitionStub() {
+            @Override
+            public void startAnimation(IBinder token, TransitionInfo info,
+                    SurfaceControl.Transaction t,
+                    IRemoteTransitionFinishedCallback finishCallback) {}
+
+            @Override
+            public void takeOverAnimation(IBinder transition, TransitionInfo info,
+                    SurfaceControl.Transaction startTransaction,
+                    IRemoteTransitionFinishedCallback finishCallback, WindowAnimationState[] states)
+                    throws RemoteException {
+                takeoverRemoteCalled[0] = true;
+                finishCallback.onTransitionFinished(null /* wct */, null /* sct */);
+            }
+        };
+
+        TransitionFilter filter = new TransitionFilter();
+        filter.mRequirements =
+                new TransitionFilter.Requirement[]{new TransitionFilter.Requirement()};
+        filter.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
+
+        transitions.registerRemote(filter, new RemoteTransition(testRemote, "Test"));
+        transitions.registerRemoteForTakeover(
+                filter, new RemoteTransition(testTakeoverRemote, "Test"));
+        mMainExecutor.flushAll();
+
+        // Takeover shouldn't happen when the flag is disabled.
+        setFlagsRule.disableFlags(Flags.FLAG_RETURN_ANIMATION_FRAMEWORK_LIBRARY);
+        IBinder transitToken = new Binder();
+        transitions.requestStartTransition(transitToken,
+                new TransitionRequestInfo(TRANSIT_OPEN, null /* trigger */, null /* remote */));
+        TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
+                .addChange(TRANSIT_OPEN).addChange(TRANSIT_CLOSE).build();
+        transitions.onTransitionReady(transitToken, info, new StubTransaction(),
+                new StubTransaction());
+        assertEquals(0, mDefaultHandler.activeCount());
+        assertFalse(takeoverRemoteCalled[0]);
+        mDefaultHandler.finishAll();
+        mMainExecutor.flushAll();
+        verify(mOrganizer, times(1)).finishTransition(eq(transitToken), any());
+
+        // Takeover should happen when the flag is enabled.
+        setFlagsRule.enableFlags(Flags.FLAG_RETURN_ANIMATION_FRAMEWORK_LIBRARY);
+        transitions.requestStartTransition(transitToken,
+                new TransitionRequestInfo(TRANSIT_OPEN, null /* trigger */, null /* remote */));
+        info = new TransitionInfoBuilder(TRANSIT_OPEN)
+                .addChange(TRANSIT_OPEN).addChange(TRANSIT_CLOSE).build();
+        transitions.onTransitionReady(transitToken, info, new StubTransaction(),
+                new StubTransaction());
+        assertEquals(0, mDefaultHandler.activeCount());
+        assertTrue(takeoverRemoteCalled[0]);
+        mDefaultHandler.finishAll();
+        mMainExecutor.flushAll();
+        verify(mOrganizer, times(2)).finishTransition(eq(transitToken), any());
+    }
+
+    @Test
     public void testOneShotRemoteHandler() {
         Transitions transitions = createTestTransitions();
         transitions.replaceDefaultHandlerForTest(mDefaultHandler);
 
         final boolean[] remoteCalled = new boolean[]{false};
+        final boolean[] takeoverRemoteCalled = new boolean[]{false};
         final WindowContainerTransaction remoteFinishWCT = new WindowContainerTransaction();
         IRemoteTransition testRemote = new RemoteTransitionStub() {
             @Override
@@ -489,12 +582,22 @@
                 remoteCalled[0] = true;
                 finishCallback.onTransitionFinished(remoteFinishWCT, null /* sct */);
             }
+
+            @Override
+            public void takeOverAnimation(IBinder transition, TransitionInfo info,
+                    SurfaceControl.Transaction startTransaction,
+                    IRemoteTransitionFinishedCallback finishCallback, WindowAnimationState[] states)
+                    throws RemoteException {
+                takeoverRemoteCalled[0] = true;
+                finishCallback.onTransitionFinished(remoteFinishWCT, null /* sct */);
+            }
         };
 
         final int transitType = TRANSIT_FIRST_CUSTOM + 1;
 
         OneShotRemoteHandler oneShot = new OneShotRemoteHandler(mMainExecutor,
                 new RemoteTransition(testRemote, "Test"));
+
         // Verify that it responds to the remote but not other things.
         IBinder transitToken = new Binder();
         assertNotNull(oneShot.handleRequest(transitToken,
@@ -505,6 +608,7 @@
 
         Transitions.TransitionFinishCallback testFinish =
                 mock(Transitions.TransitionFinishCallback.class);
+
         // Verify that it responds to animation properly
         oneShot.setTransition(transitToken);
         IBinder anotherToken = new Binder();
@@ -514,6 +618,16 @@
         assertTrue(oneShot.startAnimation(transitToken, new TransitionInfo(transitType, 0),
                 new StubTransaction(), new StubTransaction(),
                 testFinish));
+        assertTrue(remoteCalled[0]);
+
+        // Verify that it handles takeovers properly
+        IBinder newToken = new Binder();
+        oneShot.setTransition(newToken);
+        assertFalse(oneShot.takeOverAnimation(transitToken, new TransitionInfo(transitType, 0),
+                new StubTransaction(), testFinish, new WindowAnimationState[0]));
+        assertTrue(oneShot.takeOverAnimation(newToken, new TransitionInfo(transitType, 0),
+                new StubTransaction(), testFinish, new WindowAnimationState[0]));
+        assertTrue(takeoverRemoteCalled[0]);
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index f9b5882..608f74b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -18,6 +18,7 @@
 
 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.view.WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -44,6 +45,7 @@
 import android.view.Display;
 import android.view.SurfaceControl;
 import android.view.SurfaceControlViewHost;
+import android.view.WindowManager;
 import android.window.WindowContainerTransaction;
 
 import androidx.test.filters.SmallTest;
@@ -187,7 +189,7 @@
                 /* applyStartTransactionOnDraw= */ true,
                 /* shouldSetTaskPositionAndCrop */ false);
 
-        assertThat(relayoutParams.mAllowCaptionInputFallthrough).isTrue();
+        assertThat(relayoutParams.hasInputFeatureSpy()).isTrue();
     }
 
     @Test
@@ -204,7 +206,7 @@
                 /* applyStartTransactionOnDraw= */ true,
                 /* shouldSetTaskPositionAndCrop */ false);
 
-        assertThat(relayoutParams.mAllowCaptionInputFallthrough).isFalse();
+        assertThat(relayoutParams.hasInputFeatureSpy()).isFalse();
     }
 
     @Test
@@ -220,7 +222,55 @@
                 /* applyStartTransactionOnDraw= */ true,
                 /* shouldSetTaskPositionAndCrop */ false);
 
-        assertThat(relayoutParams.mAllowCaptionInputFallthrough).isFalse();
+        assertThat(relayoutParams.hasInputFeatureSpy()).isFalse();
+    }
+
+    @Test
+    public void updateRelayoutParams_freeform_inputChannelNeeded() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        final RelayoutParams relayoutParams = new RelayoutParams();
+
+        DesktopModeWindowDecoration.updateRelayoutParams(
+                relayoutParams,
+                mTestableContext,
+                taskInfo,
+                /* applyStartTransactionOnDraw= */ true,
+                /* shouldSetTaskPositionAndCrop */ false);
+
+        assertThat(hasNoInputChannelFeature(relayoutParams)).isFalse();
+    }
+
+    @Test
+    public void updateRelayoutParams_fullscreen_inputChannelNotNeeded() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        final RelayoutParams relayoutParams = new RelayoutParams();
+
+        DesktopModeWindowDecoration.updateRelayoutParams(
+                relayoutParams,
+                mTestableContext,
+                taskInfo,
+                /* applyStartTransactionOnDraw= */ true,
+                /* shouldSetTaskPositionAndCrop */ false);
+
+        assertThat(hasNoInputChannelFeature(relayoutParams)).isTrue();
+    }
+
+    @Test
+    public void updateRelayoutParams_multiwindow_inputChannelNotNeeded() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+        final RelayoutParams relayoutParams = new RelayoutParams();
+
+        DesktopModeWindowDecoration.updateRelayoutParams(
+                relayoutParams,
+                mTestableContext,
+                taskInfo,
+                /* applyStartTransactionOnDraw= */ true,
+                /* shouldSetTaskPositionAndCrop */ false);
+
+        assertThat(hasNoInputChannelFeature(relayoutParams)).isTrue();
     }
 
     private void fillRoundedCornersResources(int fillValue) {
@@ -268,4 +318,9 @@
         return taskInfo;
 
     }
+
+    private static boolean hasNoInputChannelFeature(RelayoutParams params) {
+        return (params.mInputFeatures & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL)
+                != 0;
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt
index 847c2dd..8742591 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt
@@ -15,8 +15,8 @@
  */
 package com.android.wm.shell.windowdecor
 
+import android.graphics.Bitmap
 import android.graphics.Rect
-import android.graphics.drawable.Drawable
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.Display
@@ -60,7 +60,7 @@
     @Mock
     private lateinit var mockDisplayController: DisplayController
     @Mock
-    private lateinit var mockAppIcon: Drawable
+    private lateinit var mockAppIcon: Bitmap
     @Mock
     private lateinit var mockDisplay: Display
     @Mock
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
index a9f4492..48ac1e5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
@@ -197,7 +197,7 @@
         rectAfterEnd.top += 20
         rectAfterEnd.bottom += 20
 
-        verify(mockDesktopWindowDecoration, never()).createResizeVeil()
+        verify(mockDesktopWindowDecoration, never()).showResizeVeil(any())
         verify(mockDesktopWindowDecoration, never()).hideResizeVeil()
         verify(mockTransitions).startTransition(eq(TRANSIT_CHANGE), argThat { wct ->
             return@argThat wct.changes.any { (token, change) ->
diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp
index a8e8547..0f29613 100644
--- a/libs/hwui/renderthread/VulkanSurface.cpp
+++ b/libs/hwui/renderthread/VulkanSurface.cpp
@@ -322,11 +322,16 @@
         return false;
     }
 
-    err = native_window_set_buffer_count(window, windowInfo.bufferCount);
-    if (err != 0) {
-        ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%zu) failed: %s (%d)",
-              windowInfo.bufferCount, strerror(-err), err);
-        return false;
+    // If bufferCount == 1 then we're in shared buffer mode and we cannot actually call
+    // set_buffer_count, it'll just fail.
+    if (windowInfo.bufferCount > 1) {
+        err = native_window_set_buffer_count(window, windowInfo.bufferCount);
+        if (err != 0) {
+            ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%zu) failed: %s "
+                  "(%d)",
+                  windowInfo.bufferCount, strerror(-err), err);
+            return false;
+        }
     }
 
     err = native_window_set_usage(window, windowInfo.windowUsageFlags);
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index ffd6e16..554fe5e 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -1005,7 +1005,6 @@
      *     RoutingController#wasTransferInitiatedBySelf()}.
      * @hide
      */
-    @FlaggedApi(FLAG_ENABLE_BUILT_IN_SPEAKER_ROUTE_SUITABILITY_STATUSES)
     public void transfer(
             @NonNull RoutingController controller,
             @NonNull MediaRoute2Info route,
diff --git a/nfc/jarjar-rules.txt b/nfc/jarjar-rules.txt
index 99ae144..63a6a58 100644
--- a/nfc/jarjar-rules.txt
+++ b/nfc/jarjar-rules.txt
@@ -27,9 +27,8 @@
 rule android.os.PersistableBundleProto* com.android.nfc.x.@0
 
 # Used by framework-nfc for reading trunk stable flags
-rule android.nfc.FakeFeatureFlagsImpl* com.android.nfc.x.@0
-rule android.nfc.FeatureFlags* com.android.nfc.x.@0
-rule android.nfc.Flags* com.android.nfc.x.@0
+rule android.nfc.*Flags* com.android.nfc.x.@0
+rule android.nfc.Flags com.android.nfc.x.@0
 rule android.permission.flags.** com.android.nfc.x.@0
 
 # Used by framework-nfc for misc utilities
diff --git a/packages/CredentialManager/res/values-bs/strings.xml b/packages/CredentialManager/res/values-bs/strings.xml
index c2d452db..8d44d9c 100644
--- a/packages/CredentialManager/res/values-bs/strings.xml
+++ b/packages/CredentialManager/res/values-bs/strings.xml
@@ -48,7 +48,7 @@
     <string name="passwords" msgid="5419394230391253816">"lozinke"</string>
     <string name="sign_ins" msgid="4710739369149469208">"prijave"</string>
     <string name="sign_in_info" msgid="2627704710674232328">"informacije o prijavi"</string>
-    <string name="save_credential_to_title" msgid="3172811692275634301">"Sačuvaj <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> na"</string>
+    <string name="save_credential_to_title" msgid="3172811692275634301">"Sačuvaj vrstu akreditiva \"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>\" na"</string>
     <string name="create_passkey_in_other_device_title" msgid="2360053098931886245">"Kreirati pristupni ključ na drugom uređaju?"</string>
     <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Sačuvati lozinku na drugom uređaju?"</string>
     <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Sačuvati akreditive za prijavu na drugom uređaju?"</string>
diff --git a/packages/CredentialManager/res/values-ca/strings.xml b/packages/CredentialManager/res/values-ca/strings.xml
index 32405a4..95b6c29 100644
--- a/packages/CredentialManager/res/values-ca/strings.xml
+++ b/packages/CredentialManager/res/values-ca/strings.xml
@@ -20,7 +20,7 @@
     <string name="app_name" msgid="4539824758261855508">"Gestor de credencials"</string>
     <string name="string_cancel" msgid="6369133483981306063">"Cancel·la"</string>
     <string name="string_continue" msgid="1346732695941131882">"Continua"</string>
-    <string name="string_more_options" msgid="2763852250269945472">"Desa diferent"</string>
+    <string name="string_more_options" msgid="2763852250269945472">"Desa d\'altra forma"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Més informació"</string>
     <string name="content_description_show_password" msgid="3283502010388521607">"Mostra la contrasenya"</string>
     <string name="content_description_hide_password" msgid="6841375971631767996">"Amaga la contrasenya"</string>
@@ -74,7 +74,7 @@
     <string name="get_dialog_description_single_tap" msgid="2797059565126030879">"Utilitza el bloqueig de pantalla per iniciar la sessió a <xliff:g id="APP_NAME">%1$s</xliff:g> amb <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7096423827682163270">"Desbloqueja les opcions d\'inici de sessió per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Tria una clau d\'accés desada per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Tria una clau d\'accés desada per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Tria una contrasenya desada per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Tria un inici de sessió desat per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_title_choose_sign_in_for" msgid="645728947702442421">"Selecciona un compte per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"Vols triar una opció per a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
diff --git a/packages/CredentialManager/res/values-de/strings.xml b/packages/CredentialManager/res/values-de/strings.xml
index ccff535..115f544 100644
--- a/packages/CredentialManager/res/values-de/strings.xml
+++ b/packages/CredentialManager/res/values-de/strings.xml
@@ -48,7 +48,7 @@
     <string name="passwords" msgid="5419394230391253816">"Passwörter"</string>
     <string name="sign_ins" msgid="4710739369149469208">"Anmeldungen"</string>
     <string name="sign_in_info" msgid="2627704710674232328">"Anmeldedaten"</string>
-    <string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> speichern unter"</string>
+    <string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> speichern in"</string>
     <string name="create_passkey_in_other_device_title" msgid="2360053098931886245">"Passkey auf einem anderen Gerät erstellen?"</string>
     <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Passwort auf einem anderen Gerät speichern?"</string>
     <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Anmeldedaten auf einem anderen Gerät speichern?"</string>
@@ -74,7 +74,7 @@
     <string name="get_dialog_description_single_tap" msgid="2797059565126030879">"Du kannst die Displaysperre verwenden, um dich in <xliff:g id="APP_NAME">%1$s</xliff:g> als <xliff:g id="USERNAME">%2$s</xliff:g> anzumelden"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7096423827682163270">"Anmeldeoptionen für <xliff:g id="APP_NAME">%1$s</xliff:g> freischalten"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Einen gespeicherten Passkey für <xliff:g id="APP_NAME">%1$s</xliff:g> auswählen"</string>
-    <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Ein gespeichertes Passwort für <xliff:g id="APP_NAME">%1$s</xliff:g> auswählen"</string>
+    <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Gespeichertes Passwort für <xliff:g id="APP_NAME">%1$s</xliff:g> auswählen"</string>
     <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Gespeicherte Anmeldedaten für <xliff:g id="APP_NAME">%1$s</xliff:g> auswählen"</string>
     <string name="get_dialog_title_choose_sign_in_for" msgid="645728947702442421">"Konto für <xliff:g id="APP_NAME">%1$s</xliff:g> auswählen"</string>
     <string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"Option für <xliff:g id="APP_NAME">%1$s</xliff:g> auswählen?"</string>
diff --git a/packages/CredentialManager/res/values-fr/strings.xml b/packages/CredentialManager/res/values-fr/strings.xml
index c406857..b239fc3 100644
--- a/packages/CredentialManager/res/values-fr/strings.xml
+++ b/packages/CredentialManager/res/values-fr/strings.xml
@@ -20,7 +20,7 @@
     <string name="app_name" msgid="4539824758261855508">"Gestionnaire d\'identifiants"</string>
     <string name="string_cancel" msgid="6369133483981306063">"Annuler"</string>
     <string name="string_continue" msgid="1346732695941131882">"Continuer"</string>
-    <string name="string_more_options" msgid="2763852250269945472">"Sauver autrement"</string>
+    <string name="string_more_options" msgid="2763852250269945472">"Autre façon"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"En savoir plus"</string>
     <string name="content_description_show_password" msgid="3283502010388521607">"Afficher le mot de passe"</string>
     <string name="content_description_hide_password" msgid="6841375971631767996">"Masquer le mot de passe"</string>
diff --git a/packages/CredentialManager/res/values-ko/strings.xml b/packages/CredentialManager/res/values-ko/strings.xml
index 468f4e7..7067a40 100644
--- a/packages/CredentialManager/res/values-ko/strings.xml
+++ b/packages/CredentialManager/res/values-ko/strings.xml
@@ -89,7 +89,7 @@
     <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="6390367581393605009">"탭하여 잠금 해제"</string>
     <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="8131725029983174901">"로그인 정보 없음"</string>
     <string name="no_sign_in_info_in" msgid="2641118151920288356">"<xliff:g id="SOURCE">%1$s</xliff:g>의 로그인 정보 없음"</string>
-    <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"로그인 관리"</string>
+    <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"로그인 정보 관리"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"다른 기기에서"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"다른 기기 사용"</string>
     <string name="request_cancelled_by" msgid="3735222326886267820">"<xliff:g id="APP_NAME">%1$s</xliff:g>에 의해 요청이 취소됨"</string>
diff --git a/packages/CredentialManager/res/values-my/strings.xml b/packages/CredentialManager/res/values-my/strings.xml
index 2f6086a..e0def18 100644
--- a/packages/CredentialManager/res/values-my/strings.xml
+++ b/packages/CredentialManager/res/values-my/strings.xml
@@ -20,7 +20,7 @@
     <string name="app_name" msgid="4539824758261855508">"အထောက်အထားမန်နေဂျာ"</string>
     <string name="string_cancel" msgid="6369133483981306063">"မလုပ်တော့"</string>
     <string name="string_continue" msgid="1346732695941131882">"ရှေ့ဆက်ရန်"</string>
-    <string name="string_more_options" msgid="2763852250269945472">"အခြားနည်း သိမ်းရန်"</string>
+    <string name="string_more_options" msgid="2763852250269945472">"အခြားနည်းသုံးရန်"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"ပိုမိုလေ့လာရန်"</string>
     <string name="content_description_show_password" msgid="3283502010388521607">"စကားဝှက်ကို ပြရန်"</string>
     <string name="content_description_hide_password" msgid="6841375971631767996">"စကားဝှက်ကို ဖျောက်ရန်"</string>
diff --git a/packages/CredentialManager/res/values-or/strings.xml b/packages/CredentialManager/res/values-or/strings.xml
index 336b29f..e3a9191 100644
--- a/packages/CredentialManager/res/values-or/strings.xml
+++ b/packages/CredentialManager/res/values-or/strings.xml
@@ -20,7 +20,7 @@
     <string name="app_name" msgid="4539824758261855508">"କ୍ରେଡେନସିଆଲ ମେନେଜର"</string>
     <string name="string_cancel" msgid="6369133483981306063">"ବାତିଲ କରନ୍ତୁ"</string>
     <string name="string_continue" msgid="1346732695941131882">"ଜାରି ରଖନ୍ତୁ"</string>
-    <string name="string_more_options" msgid="2763852250269945472">"ଅନ୍ୟ ଉପାୟରେ ସେଭ କର"</string>
+    <string name="string_more_options" msgid="2763852250269945472">"ଅନ୍ୟ ଭାବେ ସେଭ କରନ୍ତୁ"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
     <string name="content_description_show_password" msgid="3283502010388521607">"ପାସୱାର୍ଡ ଦେଖାନ୍ତୁ"</string>
     <string name="content_description_hide_password" msgid="6841375971631767996">"ପାସୱାର୍ଡ ଲୁଚାନ୍ତୁ"</string>
diff --git a/packages/CredentialManager/res/values-pt-rPT/strings.xml b/packages/CredentialManager/res/values-pt-rPT/strings.xml
index 2204e02..a3476d9 100644
--- a/packages/CredentialManager/res/values-pt-rPT/strings.xml
+++ b/packages/CredentialManager/res/values-pt-rPT/strings.xml
@@ -20,7 +20,7 @@
     <string name="app_name" msgid="4539824758261855508">"Credential Manager"</string>
     <string name="string_cancel" msgid="6369133483981306063">"Cancelar"</string>
     <string name="string_continue" msgid="1346732695941131882">"Continuar"</string>
-    <string name="string_more_options" msgid="2763852250269945472">"Guardar outra forma"</string>
+    <string name="string_more_options" msgid="2763852250269945472">"Guardar de outra forma"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Saber mais"</string>
     <string name="content_description_show_password" msgid="3283502010388521607">"Mostrar palavra-passe"</string>
     <string name="content_description_hide_password" msgid="6841375971631767996">"Ocultar palavra-passe"</string>
diff --git a/packages/CredentialManager/res/values-ru/strings.xml b/packages/CredentialManager/res/values-ru/strings.xml
index ec2a2d6..936ff79 100644
--- a/packages/CredentialManager/res/values-ru/strings.xml
+++ b/packages/CredentialManager/res/values-ru/strings.xml
@@ -20,7 +20,7 @@
     <string name="app_name" msgid="4539824758261855508">"Менеджер учетных данных"</string>
     <string name="string_cancel" msgid="6369133483981306063">"Отмена"</string>
     <string name="string_continue" msgid="1346732695941131882">"Продолжить"</string>
-    <string name="string_more_options" msgid="2763852250269945472">"Сохранить"</string>
+    <string name="string_more_options" msgid="2763852250269945472">"Другой способ"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Подробнее"</string>
     <string name="content_description_show_password" msgid="3283502010388521607">"Показать пароль"</string>
     <string name="content_description_hide_password" msgid="6841375971631767996">"Скрыть пароль"</string>
diff --git a/packages/CredentialManager/res/values-sq/strings.xml b/packages/CredentialManager/res/values-sq/strings.xml
index 8dc0fc2..d943979 100644
--- a/packages/CredentialManager/res/values-sq/strings.xml
+++ b/packages/CredentialManager/res/values-sq/strings.xml
@@ -48,7 +48,7 @@
     <string name="passwords" msgid="5419394230391253816">"fjalëkalime"</string>
     <string name="sign_ins" msgid="4710739369149469208">"identifikimet"</string>
     <string name="sign_in_info" msgid="2627704710674232328">"informacionet e identifikimit"</string>
-    <string name="save_credential_to_title" msgid="3172811692275634301">"Ruaj <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> te"</string>
+    <string name="save_credential_to_title" msgid="3172811692275634301">"Të ruhet <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> te"</string>
     <string name="create_passkey_in_other_device_title" msgid="2360053098931886245">"Të krijohet çelësi i kalimit në një pajisje tjetër?"</string>
     <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Të ruhet fjalëkalimi në një pajisje tjetër?"</string>
     <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Të ruhet identifikimi në një pajisje tjetër?"</string>
diff --git a/packages/CredentialManager/res/values-tr/strings.xml b/packages/CredentialManager/res/values-tr/strings.xml
index 3c9c3b7..b423b2c 100644
--- a/packages/CredentialManager/res/values-tr/strings.xml
+++ b/packages/CredentialManager/res/values-tr/strings.xml
@@ -74,7 +74,7 @@
     <string name="get_dialog_description_single_tap" msgid="2797059565126030879">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasında <xliff:g id="USERNAME">%2$s</xliff:g> hesabıyla oturum açmak için ekran kilidinizi kullanın"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7096423827682163270">"<xliff:g id="APP_NAME">%1$s</xliff:g> için oturum açma seçeneklerinin kilidini açın"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> için kayıtlı bir geçiş anahtarı kullanın"</string>
-    <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"<xliff:g id="APP_NAME">%1$s</xliff:g> için kayıtlı bir şifre kullanın"</string>
+    <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"<xliff:g id="APP_NAME">%1$s</xliff:g> için kayıtlı bir şifre seçin"</string>
     <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"<xliff:g id="APP_NAME">%1$s</xliff:g> için kayıtlı oturum açma bilgilerini kullanın"</string>
     <string name="get_dialog_title_choose_sign_in_for" msgid="645728947702442421">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması için bir hesap seçin"</string>
     <string name="get_dialog_title_choose_option_for" msgid="4976380044745029107">"<xliff:g id="APP_NAME">%1$s</xliff:g> için bir seçim yapmak ister misiniz?"</string>
diff --git a/packages/CredentialManager/res/values-uk/strings.xml b/packages/CredentialManager/res/values-uk/strings.xml
index a3f79ca..cd5b7bb 100644
--- a/packages/CredentialManager/res/values-uk/strings.xml
+++ b/packages/CredentialManager/res/values-uk/strings.xml
@@ -82,7 +82,7 @@
     <string name="get_dialog_use_saved_passkey_for" msgid="4618100798664888512">"Увійти іншим способом"</string>
     <string name="snackbar_action" msgid="37373514216505085">"Переглянути варіанти"</string>
     <string name="get_dialog_button_label_continue" msgid="6446201694794283870">"Продовжити"</string>
-    <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Опції входу"</string>
+    <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Способи входу"</string>
     <string name="button_label_view_more" msgid="3429098227286495651">"Переглянути більше"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Для користувача <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Заблоковані менеджери паролів"</string>
diff --git a/packages/CredentialManager/res/values-zh-rTW/strings.xml b/packages/CredentialManager/res/values-zh-rTW/strings.xml
index d5f3093..6b22e36 100644
--- a/packages/CredentialManager/res/values-zh-rTW/strings.xml
+++ b/packages/CredentialManager/res/values-zh-rTW/strings.xml
@@ -40,7 +40,7 @@
     <string name="choose_provider_title" msgid="8870795677024868108">"選擇要將<xliff:g id="CREATETYPES">%1$s</xliff:g>存在哪裡"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"選取密碼管理工具並儲存資訊,下次就能更快登入"</string>
     <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"要建立用於登入「<xliff:g id="APP_NAME">%1$s</xliff:g>」的密碼金鑰嗎?"</string>
-    <string name="choose_create_option_password_title" msgid="4481366993598649224">"要儲存用於登入「<xliff:g id="APP_NAME">%1$s</xliff:g>」的密碼嗎?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"要儲存登入「<xliff:g id="APP_NAME">%1$s</xliff:g>」的密碼嗎?"</string>
     <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"要儲存「<xliff:g id="APP_NAME">%1$s</xliff:g>」的登入資訊嗎?"</string>
     <string name="passkey" msgid="632353688396759522">"密碼金鑰"</string>
     <string name="password" msgid="6738570945182936667">"密碼"</string>
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
index a2f55cd..8cde454 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
@@ -125,6 +125,7 @@
             return Triple(true, false, null)
         }
         val shouldShowCancellationUi = cancelUiRequest.shouldShowCancellationExplanation()
+        viewModel?.onDeveloperCancellationReceivedForBiometricPrompt()
         Log.d(
             Constants.LOG_TAG, "Received UI cancellation intent. Should show cancellation" +
             " ui = $shouldShowCancellationUi")
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
index 7bc3241..d4a8110 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
@@ -19,6 +19,7 @@
 import android.app.Activity
 import android.hardware.biometrics.BiometricPrompt
 import android.hardware.biometrics.BiometricPrompt.AuthenticationResult
+import android.os.CancellationSignal
 import android.os.IBinder
 import android.text.TextUtils
 import android.util.Log
@@ -232,8 +233,13 @@
         authResult: BiometricPrompt.AuthenticationResult? = null,
         authError: BiometricError? = null,
     ) {
-        Log.d(Constants.LOG_TAG, "credential selected: {provider=${entry.providerId}" +
-            ", key=${entry.entryKey}, subkey=${entry.entrySubkey}}")
+        if (authError == null) {
+            Log.d(Constants.LOG_TAG, "credential selected: {provider=${entry.providerId}" +
+                        ", key=${entry.entryKey}, subkey=${entry.entrySubkey}}")
+        } else {
+                Log.d(Constants.LOG_TAG, "Biometric flow error: ${authError.errorCode} " +
+                        "propagating to provider, message: ${authError.errorMessage}.")
+        }
         uiState = if (entry.pendingIntent != null) {
             uiState.copy(
                 selectedEntry = entry,
@@ -385,9 +391,15 @@
         val providerId = selectedEntry.providerId
         val entryKey = selectedEntry.entryKey
         val entrySubkey = selectedEntry.entrySubkey
-        Log.d(
-            Constants.LOG_TAG, "Option selected for entry: " +
-            " {provider=$providerId, key=$entryKey, subkey=$entrySubkey")
+        if (authError == null) {
+            Log.d(
+                Constants.LOG_TAG, "Option selected for entry: " +
+                        " {provider=$providerId, key=$entryKey, subkey=$entrySubkey"
+            )
+        } else {
+            Log.d(Constants.LOG_TAG, "Biometric flow error: ${authError.errorCode} " +
+                    "propagating to provider, message: ${authError.errorMessage}.")
+        }
         if (selectedEntry.pendingIntent != null) {
             uiState = uiState.copy(
                 selectedEntry = selectedEntry,
@@ -424,6 +436,33 @@
     /**************************************************************************/
 
     /**
+     * Cancels the biometric prompt's cancellation signal. Should only be called when the credential
+     * manager ui receives a developer cancellation signal. If the prompt is already done, we do
+     * not allow a cancellation, given the UI cancellation will be caught by the backend. We also
+     * set the biometricStatus to CANCELED, so that only in this case, we do *not* propagate the
+     * ERROR_CANCELED when a developer cancellation signal is the root cause.
+     */
+    fun onDeveloperCancellationReceivedForBiometricPrompt() {
+        val biometricCancellationSignal = uiState.biometricState.biometricCancellationSignal
+        if (!biometricCancellationSignal.isCanceled && uiState.biometricState.biometricStatus
+            != BiometricPromptState.COMPLETE) {
+            uiState = uiState.copy(
+                biometricState = uiState.biometricState.copy(
+                    biometricStatus = BiometricPromptState.CANCELED
+                )
+            )
+            biometricCancellationSignal.cancel()
+        }
+    }
+
+    /**
+     * Retrieve the biometric prompt's cancellation signal (e.g. to pass into the 'authenticate'
+     * API).
+     */
+    fun getBiometricCancellationSignal(): CancellationSignal =
+        uiState.biometricState.biometricCancellationSignal
+
+    /**
      * This allows falling back from the biometric prompt screen to the normal get flow by applying
      * a reset to all necessary states involved in the fallback.
      */
@@ -450,9 +489,9 @@
     }
 
     /**
-     * This returns the present biometric state.
+     * This returns the present biometric prompt state's status.
      */
-    fun getBiometricPromptState(): BiometricPromptState =
+    fun getBiometricPromptStateStatus(): BiometricPromptState =
         uiState.biometricState.biometricStatus
 
     /**************************************************************************/
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
index 0d19a45..b43b5f3 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
@@ -65,7 +65,6 @@
  * ).
  *
  * The above are examples; the credential type can change depending on scenario.
- * // TODO(b/333445112) : Finalize once all the strings and create flow is iterated to completion
  */
 data class BiometricDisplayInfo(
     val providerIcon: Bitmap,
@@ -84,7 +83,8 @@
 data class BiometricState(
     val biometricResult: BiometricResult? = null,
     val biometricError: BiometricError? = null,
-    val biometricStatus: BiometricPromptState = BiometricPromptState.INACTIVE
+    val biometricStatus: BiometricPromptState = BiometricPromptState.INACTIVE,
+    val biometricCancellationSignal: CancellationSignal = CancellationSignal(),
 )
 
 /**
@@ -118,6 +118,7 @@
     getBiometricPromptState: () -> BiometricPromptState,
     onBiometricPromptStateChange: (BiometricPromptState) -> Unit,
     onBiometricFailureFallback: (BiometricFlowType) -> Unit,
+    getBiometricCancellationSignal: () -> CancellationSignal,
     getRequestDisplayInfo: RequestDisplayInfo? = null,
     getProviderInfoList: List<ProviderInfo>? = null,
     getProviderDisplayInfo: ProviderDisplayInfo? = null,
@@ -141,11 +142,13 @@
 
     val callback: BiometricPrompt.AuthenticationCallback =
         setupBiometricAuthenticationCallback(sendDataToProvider, biometricEntry,
-            onCancelFlowAndFinish, onIllegalStateAndFinish, onBiometricPromptStateChange)
+            onCancelFlowAndFinish, onIllegalStateAndFinish, onBiometricPromptStateChange,
+            getBiometricPromptState)
 
-    Log.d(TAG, "The BiometricPrompt API call begins.")
+    Log.d(TAG, "The BiometricPrompt API call begins for Get.")
     runBiometricFlow(context, biometricDisplayInfo, callback, openMoreOptionsPage,
-        onBiometricFailureFallback, BiometricFlowType.GET, onCancelFlowAndFinish)
+        onBiometricFailureFallback, BiometricFlowType.GET, onCancelFlowAndFinish,
+        getBiometricCancellationSignal)
 }
 
 /**
@@ -163,6 +166,7 @@
     getBiometricPromptState: () -> BiometricPromptState,
     onBiometricPromptStateChange: (BiometricPromptState) -> Unit,
     onBiometricFailureFallback: (BiometricFlowType) -> Unit,
+    getBiometricCancellationSignal: () -> CancellationSignal,
     createRequestDisplayInfo: com.android.credentialmanager.createflow
     .RequestDisplayInfo? = null,
     createProviderInfo: EnabledProviderInfo? = null,
@@ -185,11 +189,13 @@
 
     val callback: BiometricPrompt.AuthenticationCallback =
         setupBiometricAuthenticationCallback(sendDataToProvider, biometricEntry,
-            onCancelFlowAndFinish, onIllegalStateAndFinish, onBiometricPromptStateChange)
+            onCancelFlowAndFinish, onIllegalStateAndFinish, onBiometricPromptStateChange,
+            getBiometricPromptState)
 
-    Log.d(TAG, "The BiometricPrompt API call begins.")
+    Log.d(TAG, "The BiometricPrompt API call begins for Create.")
     runBiometricFlow(context, biometricDisplayInfo, callback, openMoreOptionsPage,
-        onBiometricFailureFallback, BiometricFlowType.CREATE, onCancelFlowAndFinish)
+        onBiometricFailureFallback, BiometricFlowType.CREATE, onCancelFlowAndFinish,
+        getBiometricCancellationSignal)
 }
 
 /**
@@ -206,7 +212,8 @@
     openMoreOptionsPage: () -> Unit,
     onBiometricFailureFallback: (BiometricFlowType) -> Unit,
     biometricFlowType: BiometricFlowType,
-    onCancelFlowAndFinish: () -> Unit
+    onCancelFlowAndFinish: () -> Unit,
+    getBiometricCancellationSignal: () -> CancellationSignal,
 ) {
     try {
         if (!canCallBiometricPrompt(biometricDisplayInfo, context)) {
@@ -217,12 +224,7 @@
         val biometricPrompt = setupBiometricPrompt(context, biometricDisplayInfo,
             openMoreOptionsPage, biometricDisplayInfo.biometricRequestInfo, onCancelFlowAndFinish)
 
-        val cancellationSignal = CancellationSignal()
-        cancellationSignal.setOnCancelListener {
-            Log.d(TAG, "Your cancellation signal was called.")
-            // TODO(b/333445112) : Migrate towards passing along the developer cancellation signal
-            // or validate the necessity for this
-        }
+        val cancellationSignal = getBiometricCancellationSignal()
 
         val executor = getMainExecutor(context)
 
@@ -251,8 +253,6 @@
  * Note that if device credential is the only available modality but not requested, or if none
  * of the requested modalities are available, we fallback to the normal flow to ensure a selector
  * shows up.
- * // TODO(b/334197980) : While we already fallback in cases the selector doesn't show, confirm
- * // final plan.
  */
 private fun canCallBiometricPrompt(
     biometricDisplayInfo: BiometricDisplayInfo,
@@ -270,12 +270,12 @@
         return false
     }
 
-    if (ifOnlySupportsAtMostDeviceCredentials(biometricManager)) return false
+    if (onlySupportsAtMostDeviceCredentials(biometricManager)) return false
 
     return true
 }
 
-private fun ifOnlySupportsAtMostDeviceCredentials(biometricManager: BiometricManager): Boolean {
+private fun onlySupportsAtMostDeviceCredentials(biometricManager: BiometricManager): Boolean {
     if (biometricManager.canAuthenticate(Authenticators.BIOMETRIC_WEAK) !=
         BiometricManager.BIOMETRIC_SUCCESS &&
         biometricManager.canAuthenticate(Authenticators.BIOMETRIC_STRONG) !=
@@ -343,11 +343,11 @@
     selectedEntry: EntryInfo,
     onCancelFlowAndFinish: () -> Unit,
     onIllegalStateAndFinish: (String) -> Unit,
-    onBiometricPromptStateChange: (BiometricPromptState) -> Unit
+    onBiometricPromptStateChange: (BiometricPromptState) -> Unit,
+    getBiometricPromptState: () -> BiometricPromptState,
 ): BiometricPrompt.AuthenticationCallback {
     val callback: BiometricPrompt.AuthenticationCallback =
         object : BiometricPrompt.AuthenticationCallback() {
-            // TODO(b/333445772) : Validate remaining callbacks
             override fun onAuthenticationSucceeded(
                 authResult: BiometricPrompt.AuthenticationResult?
             ) {
@@ -374,6 +374,12 @@
             override fun onAuthenticationError(errorCode: Int, errString: CharSequence?) {
                 super.onAuthenticationError(errorCode, errString)
                 Log.d(TAG, "Authentication error-ed out: $errorCode and $errString")
+                if (getBiometricPromptState() == BiometricPromptState.CANCELED && errorCode
+                    == BiometricPrompt.BIOMETRIC_ERROR_CANCELED) {
+                    Log.d(TAG, "Developer cancellation signal received. Nothing more to do.")
+                    // This unique edge case means a developer cancellation signal was sent.
+                    return
+                }
                 onBiometricPromptStateChange(BiometricPromptState.COMPLETE)
                 if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED) {
                     // Note that because the biometric prompt is imbued directly
@@ -471,8 +477,7 @@
     val singleEntryType = selectedEntry.credentialType
     val username = selectedEntry.userName
 
-    // TODO(b/330396140) : Finalize localization and parsing for specific sign in option flows
-    //  (fingerprint, face, etc...))
+    // TODO(b/336362538) : In W, utilize updated localization strings
     displayTitleText = context.getString(
         generateDisplayTitleTextResCode(singleEntryType),
         getRequestDisplayInfo.appName
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricPromptState.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricPromptState.kt
index e1aa041..eb77937 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricPromptState.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricPromptState.kt
@@ -22,5 +22,10 @@
     /** The biometric prompt is active but data hasn't been returned yet. */
     PENDING,
     /** The biometric prompt has closed and returned data we then send to the provider activity. */
-    COMPLETE
+    COMPLETE,
+    /**
+     * The biometric prompt has been canceled by a developer signal. If this is true, certain
+     * conditions can be triggered, such as no longer propagating ERROR_CANCELED.
+     */
+    CANCELED,
 }
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index 282a1b5..7d61f73 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -18,6 +18,7 @@
 
 import android.credentials.flags.Flags.selectorUiImprovementsEnabled
 import android.hardware.biometrics.BiometricPrompt
+import android.os.CancellationSignal
 import android.text.TextUtils
 import androidx.activity.compose.ManagedActivityResultLauncher
 import androidx.activity.result.ActivityResult
@@ -118,9 +119,11 @@
                                 fallbackToOriginalFlow =
                                 viewModel::fallbackFromBiometricToNormalFlow,
                                 getBiometricPromptState =
-                                viewModel::getBiometricPromptState,
+                                viewModel::getBiometricPromptStateStatus,
                                 onBiometricPromptStateChange =
-                                viewModel::onBiometricPromptStateChange
+                                viewModel::onBiometricPromptStateChange,
+                                getBiometricCancellationSignal =
+                                viewModel::getBiometricCancellationSignal
                             )
                         CreateScreenState.MORE_OPTIONS_SELECTION_ONLY -> MoreOptionsSelectionCard(
                                 requestDisplayInfo = createCredentialUiState.requestDisplayInfo,
@@ -638,6 +641,7 @@
     fallbackToOriginalFlow: (BiometricFlowType) -> Unit,
     getBiometricPromptState: () -> BiometricPromptState,
     onBiometricPromptStateChange: (BiometricPromptState) -> Unit,
+    getBiometricCancellationSignal: () -> CancellationSignal,
 ) {
     if (biometricEntry == null) {
         fallbackToOriginalFlow(BiometricFlowType.CREATE)
@@ -655,5 +659,6 @@
         createProviderInfo = enabledProviderInfo,
         onBiometricFailureFallback = fallbackToOriginalFlow,
         onIllegalStateAndFinish = onIllegalScreenStateAndFinish,
+        getBiometricCancellationSignal = getBiometricCancellationSignal,
     )
 }
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index c98bb5e..ba61b90 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -20,6 +20,7 @@
 import android.credentials.flags.Flags.selectorUiImprovementsEnabled
 import android.graphics.drawable.Drawable
 import android.hardware.biometrics.BiometricPrompt
+import android.os.CancellationSignal
 import androidx.activity.compose.ManagedActivityResultLauncher
 import androidx.activity.result.ActivityResult
 import androidx.activity.result.IntentSenderRequest
@@ -161,9 +162,11 @@
                                 fallbackToOriginalFlow =
                                 viewModel::fallbackFromBiometricToNormalFlow,
                                 getBiometricPromptState =
-                                viewModel::getBiometricPromptState,
+                                viewModel::getBiometricPromptStateStatus,
                                 onBiometricPromptStateChange =
-                                viewModel::onBiometricPromptStateChange
+                                viewModel::onBiometricPromptStateChange,
+                                getBiometricCancellationSignal =
+                                viewModel::getBiometricCancellationSignal
                             )
                         } else if (credmanBiometricApiEnabled() &&
                                 getCredentialUiState.currentScreenState
@@ -256,6 +259,7 @@
     fallbackToOriginalFlow: (BiometricFlowType) -> Unit,
     getBiometricPromptState: () -> BiometricPromptState,
     onBiometricPromptStateChange: (BiometricPromptState) -> Unit,
+    getBiometricCancellationSignal: () -> CancellationSignal,
 ) {
     if (biometricEntry == null) {
         fallbackToOriginalFlow(BiometricFlowType.GET)
@@ -273,7 +277,8 @@
         getRequestDisplayInfo = requestDisplayInfo,
         getProviderInfoList = providerInfoList,
         getProviderDisplayInfo = providerDisplayInfo,
-        onBiometricFailureFallback = fallbackToOriginalFlow
+        onBiometricFailureFallback = fallbackToOriginalFlow,
+        getBiometricCancellationSignal = getBiometricCancellationSignal
     )
 }
 
diff --git a/packages/InputDevices/res/raw/keyboard_layout_thai_pattachote.kcm b/packages/InputDevices/res/raw/keyboard_layout_thai_pattachote.kcm
new file mode 100644
index 0000000..a136aca
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_thai_pattachote.kcm
@@ -0,0 +1,317 @@
+# Copyright 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Thai Pattachote keyboard layout.
+#
+
+type OVERLAY
+
+map key 86 PLUS
+
+### ROW 1
+
+key GRAVE {
+    label:                              '_'
+    base:                               '_'
+    shift, capslock:                    '\u0e3f'
+}
+
+key 1 {
+    label:                              '='
+    base:                               '='
+    shift, capslock:                    '+'
+}
+
+key 2 {
+    label:                              '\u0e52'
+    base:                               '\u0e52'
+    shift, capslock:                    '\u0022'
+}
+
+key 3 {
+    label:                              '\u0e53'
+    base:                               '\u0e53'
+    shift, capslock:                    '/'
+}
+
+key 4 {
+    label:                              '\u0e54'
+    base:                               '\u0e54'
+    shift, capslock:                    ','
+}
+
+key 5 {
+    label:                              '\u0e55'
+    base:                               '\u0e55'
+    shift, capslock:                    '?'
+}
+
+key 6 {
+    label:                              '\u0e39'
+    base:                               '\u0e39'
+    shift, capslock:                    '\u0e38'
+}
+
+key 7 {
+    label:                              '\u0e57'
+    base:                               '\u0e57'
+    shift, capslock:                    '_'
+}
+
+key 8 {
+    label:                              '\u0e58'
+    base:                               '\u0e58'
+    shift, capslock:                    '.'
+}
+
+key 9 {
+    label:                              '\u0e59'
+    base:                               '\u0e59'
+    shift, capslock:                    '('
+}
+
+key 0 {
+    label:                              '\u0e50'
+    base:                               '\u0e50'
+    shift, capslock:                    ')'
+}
+
+key MINUS {
+    label:                              '\u0e51'
+    base:                               '\u0e51'
+    shift, capslock:                    '-'
+}
+
+key EQUALS {
+    label:                              '\u0e56'
+    base:                               '\u0e56'
+    shift, capslock:                    '%'
+}
+
+### ROW 2
+
+key Q {
+    label:                              '\u0e47'
+    base:                               '\u0e47'
+    shift, capslock:                    '\u0e4a'
+}
+
+key W {
+    label:                              '\u0e15'
+    base:                               '\u0e15'
+    shift, capslock:                    '\u0e24'
+}
+
+key E {
+    label:                              '\u0e22'
+    base:                               '\u0e22'
+    shift, capslock:                    '\u0e46'
+}
+
+key R {
+    label:                              '\u0e2d'
+    base:                               '\u0e2d'
+    shift, capslock:                    '\u0e0d'
+}
+
+key T {
+    label:                              '\u0e23'
+    base:                               '\u0e23'
+    shift, capslock:                    '\u0e29'
+}
+
+key Y {
+    label:                              '\u0e48'
+    base:                               '\u0e48'
+    shift, capslock:                    '\u0e36'
+}
+
+key U {
+    label:                              '\u0e14'
+    base:                               '\u0e14'
+    shift, capslock:                    '\u0e1d'
+}
+
+key I {
+    label:                              '\u0e21'
+    base:                               '\u0e21'
+    shift, capslock:                    '\u0e0b'
+}
+
+key O {
+    label:                              '\u0e27'
+    base:                               '\u0e27'
+    shift, capslock:                    '\u0e16'
+}
+
+key P {
+    label:                              '\u0e41'
+    base:                               '\u0e41'
+    shift, capslock:                    '\u0e12'
+}
+
+key LEFT_BRACKET {
+    label:                              '\u0e43'
+    base:                               '\u0e43'
+    shift, capslock:                    '\u0e2f'
+}
+
+key RIGHT_BRACKET {
+    label:                              '\u0e0c'
+    base:                               '\u0e0c'
+    shift, capslock:                    '\u0e26'
+}
+
+### ROW 3
+
+key A {
+    label:                              '\u0e49'
+    base:                               '\u0e49'
+    shift, capslock:                    '\u0e4b'
+}
+
+key S {
+    label:                              '\u0e17'
+    base:                               '\u0e17'
+    shift, capslock:                    '\u0e18'
+}
+
+key D {
+    label:                              '\u0e07'
+    base:                               '\u0e07'
+    shift, capslock:                    '\u0e33'
+}
+
+key F {
+    label:                              '\u0e01'
+    base:                               '\u0e01'
+    shift, capslock:                    '\u0e13'
+}
+
+key G {
+    label:                              '\u0e31'
+    base:                               '\u0e31'
+    shift, capslock:                    '\u0e4c'
+}
+
+key H {
+    label:                              '\u0e35'
+    base:                               '\u0e35'
+    shift, capslock:                    '\u0e37'
+}
+
+key J {
+    label:                              '\u0e32'
+    base:                               '\u0e32'
+    shift, capslock:                    '\u0e1c'
+}
+
+key K {
+    label:                              '\u0e19'
+    base:                               '\u0e19'
+    shift, capslock:                    '\u0e0a'
+}
+
+key L {
+    label:                              '\u0e40'
+    base:                               '\u0e40'
+    shift, capslock:                    '\u0e42'
+}
+
+key SEMICOLON {
+    label:                              '\u0e44'
+    base:                               '\u0e44'
+    shift, capslock:                    '\u0e06'
+}
+
+key APOSTROPHE {
+    label:                              '\u0e02'
+    base:                               '\u0e02'
+    shift, capslock:                    '\u0e11'
+}
+
+key BACKSLASH {
+    label:                              '\u0e45'
+    base:                               '\u0e45'
+    shift, capslock:                    '\u0e4d'
+}
+
+### ROW 4
+
+key PLUS {
+    label:                              '\u0e45'
+    base:                               '\u0e45'
+    shift, capslock:                    '\u0e4d'
+}
+
+key Z {
+    label:                              '\u0e1a'
+    base:                               '\u0e1a'
+    shift, capslock:                    '\u0e0e'
+}
+
+key X {
+    label:                              '\u0e1b'
+    base:                               '\u0e1b'
+    shift, capslock:                    '\u0e0f'
+}
+
+key C {
+    label:                              '\u0e25'
+    base:                               '\u0e25'
+    shift, capslock:                    '\u0e10'
+}
+
+key V {
+    label:                              '\u0e2b'
+    base:                               '\u0e2b'
+    shift, capslock:                    '\u0e20'
+}
+
+key B {
+    label:                              '\u0e34'
+    base:                               '\u0e34'
+    shift, capslock:                    '\u0e31'
+}
+
+key N {
+    label:                              '\u0e04'
+    base:                               '\u0e04'
+    shift, capslock:                    '\u0e28'
+}
+
+key M {
+    label:                              '\u0e2a'
+    base:                               '\u0e2a'
+    shift, capslock:                    '\u0e2e'
+}
+
+key COMMA {
+    label:                              '\u0e30'
+    base:                               '\u0e30'
+    shift, capslock:                    '\u0e1f'
+}
+
+key PERIOD {
+    label:                              '\u0e08'
+    base:                               '\u0e08'
+    shift, capslock:                    '\u0e09'
+}
+
+key SLASH {
+    label:                              '\u0e1e'
+    base:                               '\u0e1e'
+    shift, capslock:                    '\u0e2c'
+}
\ No newline at end of file
diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml
index 33a1d76..e10bd7f 100644
--- a/packages/InputDevices/res/values/strings.xml
+++ b/packages/InputDevices/res/values/strings.xml
@@ -149,4 +149,7 @@
 
     <!-- Thai (Kedmanee variant) keyboard layout label. [CHAR LIMIT=35] -->
     <string name="keyboard_layout_thai_kedmanee">Thai (Kedmanee)</string>
+
+    <!-- Thai (Pattachote variant) keyboard layout label. [CHAR LIMIT=35] -->
+    <string name="keyboard_layout_thai_pattachote">Thai (Pattachote)</string>
 </resources>
diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml
index 4b7ea90..c18d73c 100644
--- a/packages/InputDevices/res/xml/keyboard_layouts.xml
+++ b/packages/InputDevices/res/xml/keyboard_layouts.xml
@@ -325,4 +325,11 @@
         android:keyboardLayout="@raw/keyboard_layout_thai_kedmanee"
         android:keyboardLocale="th-Thai"
         android:keyboardLayoutType="extended" />
+
+    <keyboard-layout
+        android:name="keyboard_layout_thai_pattachote"
+        android:label="@string/keyboard_layout_thai_pattachote"
+        android:keyboardLayout="@raw/keyboard_layout_thai_pattachote"
+        android:keyboardLocale="th-Thai"
+        android:keyboardLayoutType="extended" />
 </keyboard-layouts>
diff --git a/packages/PackageInstaller/res/values-pt-rPT/strings.xml b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
index c39956d..a0a1eb9 100644
--- a/packages/PackageInstaller/res/values-pt-rPT/strings.xml
+++ b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
@@ -99,7 +99,7 @@
     <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"Para sua segurança, o relógio não está atualmente autorizado a instalar apps desconhecidas a partir desta origem. Pode alterar esta opção nas Definições."</string>
     <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Para sua segurança, o telemóvel não está atualmente autorizado a instalar apps desconhecidas a partir desta origem. Pode alterar esta opção nas Definições."</string>
     <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"O seu telemóvel e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta app, concorda que é responsável por quaisquer danos causados ao telemóvel ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"O seu tablet e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta app, concorda que é responsável por quaisquer danos causados ao tablet ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"O seu tablet e os dados pessoais estão mais vulneráveis a ataques por parte de apps desconhecidas. Ao instalar esta app, concorda que é responsável por quaisquer danos causados ao tablet ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
     <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"A sua TV e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta app, concorda que é responsável por quaisquer danos causados à TV ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
     <string name="cloned_app_label" msgid="7503612829833756160">"Clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="archiving_app_label" msgid="1127085259724124725">"Arquivar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>?"</string>
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt
index b7f2c1e..90cee16 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt
@@ -22,12 +22,14 @@
 object SettingsDimension {
     val paddingTiny = 2.dp
     val paddingSmall = 4.dp
+    val paddingLarge = 16.dp
+    val paddingExtraLarge = 24.dp
 
     val itemIconSize = 24.dp
     val itemIconContainerSize = 72.dp
-    val itemPaddingStart = 24.dp
-    val itemPaddingEnd = 16.dp
-    val itemPaddingVertical = 16.dp
+    val itemPaddingStart = paddingExtraLarge
+    val itemPaddingEnd = paddingLarge
+    val itemPaddingVertical = paddingLarge
     val itemPadding = PaddingValues(
         start = itemPaddingStart,
         top = itemPaddingVertical,
@@ -70,6 +72,6 @@
     /** The sizes info of illustration widget. */
     val illustrationMaxWidth = 412.dp
     val illustrationMaxHeight = 300.dp
-    val illustrationPadding = 16.dp
+    val illustrationPadding = paddingLarge
     val illustrationCornerRadius = 28.dp
 }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SuwScaffold.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SuwScaffold.kt
index 163766a..e39b175 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SuwScaffold.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SuwScaffold.kt
@@ -101,7 +101,13 @@
     imageVector: ImageVector,
     title: String
 ) {
-    Column(Modifier.padding(SettingsDimension.itemPadding)) {
+    Column(
+        Modifier.padding(
+            start = SettingsDimension.itemPaddingStart,
+            top = SettingsDimension.itemPaddingVertical,
+            end = SettingsDimension.itemPaddingEnd,
+        )
+    ) {
         Icon(
             imageVector = imageVector,
             contentDescription = null,
@@ -124,7 +130,14 @@
     actionButton: BottomAppBarButton?,
     dismissButton: BottomAppBarButton?,
 ) {
-    Row(modifier = Modifier.padding(SettingsDimension.itemPaddingAround)) {
+    Row(
+        Modifier.padding(
+            start = SettingsDimension.itemPaddingEnd,
+            top = SettingsDimension.paddingExtraLarge,
+            end = SettingsDimension.itemPaddingEnd,
+            bottom = SettingsDimension.itemPaddingVertical,
+        )
+    ) {
         dismissButton?.apply {
             TextButton(onClick = onClick, enabled = enabled) {
                 ActionText(text)
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index f9800b3..9641204 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -94,41 +94,32 @@
     <string name="bluetooth_connected_no_headset_battery_level" msgid="2661863370509206428">"Gekoppel (geen foon nie), battery <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">"Gekoppel (geen media nie), battery <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">"Gekoppel (geen foon of media nie), battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
-    <!-- no translation found for bluetooth_active_battery_level (2685517576209066008) -->
+    <string name="bluetooth_active_battery_level" msgid="2685517576209066008">"Aktief. <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
+    <string name="bluetooth_active_battery_level_untethered" msgid="4961338936672922617">"Aktief. L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
-    <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
-    <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batterykrag"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
-    <!-- no translation found for bluetooth_battery_level_untethered (1616774716076301755) -->
-    <skip />
-    <!-- no translation found for bluetooth_battery_level_untethered_left (5725764679536058365) -->
-    <skip />
-    <!-- no translation found for bluetooth_battery_level_untethered_right (8377995536997790142) -->
-    <skip />
+    <string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
+    <string name="bluetooth_battery_level_untethered_left" msgid="5725764679536058365">"Links: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
+    <string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Regs: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktief"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Gestoor"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktief, net links"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktief, net regs"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktief, links en regs"</string>
-    <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
     <skip />
-    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
     <skip />
-    <!-- no translation found for bluetooth_battery_level_lea_support (5968584103507988820) -->
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
     <skip />
-    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (803110681688633362) -->
-    <skip />
-    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (7707464334346454950) -->
-    <skip />
-    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (8941549024377771038) -->
-    <skip />
-    <!-- no translation found for bluetooth_no_battery_level_lea_support (5721725041048434075) -->
-    <skip />
+    <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktief (net media). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
+    <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiewe (net media). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery"</string>
+    <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Gekoppel (steun oudiodeling). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
+    <string name="bluetooth_battery_level_untethered_lea_support" msgid="803110681688633362">"Gekoppel (steun oudiodeling). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
+    <string name="bluetooth_battery_level_untethered_left_lea_support" msgid="7707464334346454950">"Gekoppel (steun oudiodeling). Links: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
+    <string name="bluetooth_battery_level_untethered_right_lea_support" msgid="8941549024377771038">"Gekoppel (steun oudiodeling). Regs: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
+    <string name="bluetooth_no_battery_level_lea_support" msgid="5721725041048434075">"Gekoppel (steun oudiodeling)"</string>
     <string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Aktief (net media)"</string>
     <string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Steun oudiodeling"</string>
     <string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Aktief (net media), net linkerkant"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 729ac28..51cf441 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ባትሪ"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ባትሪ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ንቁ"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"ተቀምጧል"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 9f13551..b1a7332 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"مستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"‏مستوى شحن البطارية: ‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"نشط"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"محفوظ"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 62c1201..13b639a 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰী"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"বেটাৰী <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"সক্ৰিয়"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"ছেভ কৰা হৈছে"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index b1bbf34..809601e 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batareya: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Yadda saxlandı"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, yalnız sol"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, yalnız sağ"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, sol və sağ"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 4af26f2..24830b4 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterija, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivan"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Sačuvano"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 9998c9e..986c089 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Узровень зараду: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Зарад акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Уключана"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Захавана"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 03065c6..7097078 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активно"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Запазено"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index b69a542..e4637fe 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"চার্জ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ব্যাটারি <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"চালু আছে"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"সেভ করা আছে"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 2cc6dc5..e71c2ec 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivan"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Sačuvano"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivno, samo lijevi"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivno, samo desni"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivno, lijevi i desni"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 5a4a923..09b4297 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Actiu"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Desat"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Actiu, només l\'esquerre"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Actiu, només el dret"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Actiu, esquerre i dret"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 9a3ba63..b2d75bd 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterie"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterie <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivní"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Uloženo"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivní, pouze levé"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivní, pouze pravé"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivní, levé a pravé"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index c7f1c6e..0f92316 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batteri: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Gemt"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, kun venstre"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, kun højre"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, venstre og højre"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index cc962b4..c8d7acd 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Akku – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Gespeichert"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, nur links"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, nur rechts"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, links und rechts"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 2ea96a7..2cc9350 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> μπαταρία"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Ενεργό"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Αποθηκεύτηκε"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index d4f14f4..af00515 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Active"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Saved"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Active, left only"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, right only"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, left and right"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 6b49bc9..bc08544 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -96,10 +96,8 @@
     <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Connected (no phone or media), battery <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="2685517576209066008">"Active. <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
     <string name="bluetooth_active_battery_level_untethered" msgid="4961338936672922617">"Active. L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
-    <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
-    <skip />
+    <string name="bluetooth_active_battery_level_untethered_left" msgid="2895644748625343977">"Active. L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
+    <string name="bluetooth_active_battery_level_untethered_right" msgid="7407517998880370179">"Active. R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
@@ -107,9 +105,9 @@
     <string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"Right: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Active"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Saved"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Active, left only"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, right only"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, left and right"</string>
+    <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Active (left only)"</string>
+    <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Active (right only)"</string>
+    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Active (left and right)"</string>
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Active (media only). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Active (media only). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connected (supports audio sharing). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index d4f14f4..af00515 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Active"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Saved"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Active, left only"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, right only"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, left and right"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index d4f14f4..af00515 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Battery <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Active"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Saved"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Active, left only"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, right only"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, left and right"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index c255633..b123a13 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -96,10 +96,8 @@
     <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎Connected (no phone or media), battery ‎‏‎‎‏‏‎<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="2685517576209066008">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‏‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‎‎‎‎‎‏‎‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎Active. ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ battery.‎‏‎‎‏‎"</string>
     <string name="bluetooth_active_battery_level_untethered" msgid="4961338936672922617">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎Active. L: ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎, R: ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎ battery.‎‏‎‎‏‎"</string>
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
-    <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
-    <skip />
+    <string name="bluetooth_active_battery_level_untethered_left" msgid="2895644748625343977">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‏‎‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‏‎Active. L: ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ battery.‎‏‎‎‏‎"</string>
+    <string name="bluetooth_active_battery_level_untethered_right" msgid="7407517998880370179">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎Active. R: ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ battery.‎‏‎‎‏‎"</string>
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‎‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ battery‎‏‎‎‏‎"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‏‎‏‎‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎Battery ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="bluetooth_battery_level_untethered" msgid="1616774716076301755">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‏‏‎L: ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎, R: ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎ battery.‎‏‎‎‏‎"</string>
@@ -107,9 +105,9 @@
     <string name="bluetooth_battery_level_untethered_right" msgid="8377995536997790142">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‏‎‎Right: ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ battery‎‏‎‎‏‎"</string>
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‏‏‏‏‎‎Active‎‏‎‎‏‎"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‎‏‎‎‎Saved‎‏‎‎‏‎"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‏‎‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‏‎‎‎‏‎Active, left only‎‏‎‎‏‎"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‏‏‎‎Active, right only‎‏‎‎‏‎"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎Active, left and right‎‏‎‎‏‎"</string>
+    <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‎‎Active (left only)‎‏‎‎‏‎"</string>
+    <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‏‎‏‏‎‏‏‎‏‏‏‏‏‎‏‎‏‎Active (right only)‎‏‎‎‏‎"</string>
+    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‏‎‏‎‏‏‎‏‏‎‏‏‎‏‎‎‏‏‎‏‎Active (left and right)‎‏‎‎‏‎"</string>
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‎‎‎‏‎‎‏‎‏‎‏‏‎‎‏‎Active (media only). ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ battery.‎‏‎‎‏‎"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‎‎‏‎‏‏‏‏‏‏‎‎Active (media only). L: ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎, R: ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎ battery.‎‏‎‎‏‎"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎Connected (supports audio sharing). ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ battery.‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 6a40c42..5142f24 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Activado"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Guardado"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Activo; solo oído izquierdo"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Activo; solo oído derecho"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Activo; oídos izquierdo y derecho"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index ab75219..7dc1225 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batería <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Activo"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Guardado"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Activo, solo oído izquierdo"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Activo, solo oído derecho"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Activo, oídos izquierdo y derecho"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index c730457..a47a218 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> akut"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Akutase: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiivne"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Salvestatud"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiivne, ainult vasak"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiivne, ainult parem"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiivne, vasak ja parem"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 0668fb2..91b9d20be 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktibo"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Gordeta"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktibo, ezkerrekoa soilik"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktibo, eskuinekoa soilik"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktibo, ezkerreko eta eskuineko audifonoak"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 3c7f1f8..7ab13ba 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> شارژ باتری"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"فعال"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"ذخیره‌شده"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index da80499..cafeb1b 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Akun taso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Akku (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>)"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiivinen"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Tallennettu"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiivinen, vain vasen"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiivinen, vain oikea"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiivinen, vasen ja oikea"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 6988384..0d96205 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Actif"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Enregistré"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Actif, gauche seulement"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, droite seulement"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, gauche et droite"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 709477b..1928f32 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batterie"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batterie (<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>)"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Actif"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Enregistré"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Actif, gauche uniquement"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Actif, droit uniquement"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Actifs, gauche et droit"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index e5c7f1e..d0f47a8 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batería: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Activo"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Gardado"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Activo (só o esquerdo)"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Activo (só o dereito)"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Activos (o esquerdo e o dereito)"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index d520536..b750ae5 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"બૅટરી <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"સક્રિય"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"સાચવેલું"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index a81daf7..0f0d516 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"चालू"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"सेव किया गया"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 362393e..db2c318 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterija <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivan"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Spremljeno"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivno, samo lijevo"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivno, samo desno"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivno, lijevo i desno"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index f251464..207e84a 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Akkumulátor: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Akkumulátor: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktív"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Mentve"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktív, csak bal"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktív, csak jobb"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktív, bal és jobb"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 4b6d727..1b8b236 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Ակտիվ է"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Պահված է"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 1594d11..d9730b3 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktif"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Disimpan"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktif, hanya kiri"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktif, hanya kanan"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktif, kiri dan kanan"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index b85f453..60370f5 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlöðuhleðsla"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Rafhlaða <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Virkt"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Vistað"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Virkt, aðeins vinstra"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Virkt, aðeins hægra"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Virkt, vinstra og hægra"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 08a2397..fbae08d 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Batteria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batteria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Attivo"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Dispositivo salvato"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Attiva, solo sinistra"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Attiva, solo destra"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Attivo, destra e sinistra"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 9ecf47b..5a6c751 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"טעינת הסוללה: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"סוללה <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"פעיל"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"בוצעה שמירה"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index a51ba39..aac7223 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"バッテリー <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"バッテリー <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"有効"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"保存済み"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index ba1dae0..79dbbe7 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ბატარეა"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ბატარეა <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"აქტიური"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"შენახული"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index b8f8fa3..eee0ac6 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Батарея қуаты: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Батарея: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Қосулы"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Сақталған"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index d049fd4..447126b 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"សកម្ម"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"បាន​រក្សាទុក"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 70257de..f8d3b73 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ಬ್ಯಾಟರಿ"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಇದೆ"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ಸಕ್ರಿಯ"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"ಸೇವ್ ಮಾಡಲಾಗಿದೆ"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 9ced8a0..b6988ce 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"활성"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"저장됨"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 7be7f38..d084a9bf 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Батареянын деңгээли: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Батареянын кубаты: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Жигердүү"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Сакталган"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index c6a5bd4..19bea08 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ອອນລາຍ"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"ບັນທຶກແລ້ວ"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 94b8173..4f7b350 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Akumuliatoriaus įkrova: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Akumuliatorius: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktyvus"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Išsaugota"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktyvus, tik kairysis"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktyvus, tik dešinysis"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktyvus, kairysis ir dešinysis"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index ff1f3f3..55fa4d3 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktīvs"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Saglabāta"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ierīce aktīva, tikai kreisā auss"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ierīce aktīva, tikai labā auss"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ierīces aktīvas, kreisā un labā auss"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index c5b4a5e..6d3d54c 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Батерија: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Батерија: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активен"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Зачувано"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 0ba9122..914b967 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ബാറ്ററി"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ബാറ്ററി ചാർജ് <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ആണ്"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"സജീവം"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"സംരക്ഷിച്ചു"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index c431857..c39717c 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Батарей <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Идэвхтэй"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Хадгалсан"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index a916a1c..5c5ec07 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"अ‍ॅक्टिव्ह"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"सेव्ह केली आहेत"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index f86206c..b36098b 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktif"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Disimpan"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktif, kiri sahaja"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktif, kanan sahaja"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktif, kiri dan kanan"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 2dde99f..23c892f 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ဖွင့်ထားသည်"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"သိမ်းထားသည်များ"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index d2021ba..d7814eb 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batteri: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Lagret"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, bare venstre"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, bare høyre"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, venstre og høyre"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index d01fc16..a7e01a1 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"ब्याट्रीको स्तर: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ब्याट्री <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"सक्रिय"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"सेभ गरिएको"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 6394cb6..3f2e003 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batterij <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Actief"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Opgeslagen"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Actief, alleen links"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Actief, alleen rechts"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Actief, links en rechts"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index eb31f96..b233b544 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ବେଟେରୀ"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ବେଟେରୀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ସକ୍ରିୟ"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"ସେଭ କରାଯାଇଛି"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
@@ -195,7 +198,7 @@
     <string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"ସୁରକ୍ଷିତ ନେଟ୍‌ୱର୍କ"</string>
     <string name="process_kernel_label" msgid="950292573930336765">"Android OS"</string>
     <string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"କଢ଼ାଯାଇଥିବା ଆପ୍‌ଗୁଡ଼ିକ"</string>
-    <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"ଆପ୍‌ ଏବଂ ଉପଯୋଗକର୍ତ୍ତା ବାହାର କରାଗଲା"</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>
@@ -204,7 +207,7 @@
     <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="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>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 64c4e96..73fe924 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ਬੈਟਰੀ"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"ਬੈਟਰੀ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ਕਿਰਿਆਸ਼ੀਲ"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"ਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index d4d27e1..767b87d 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> naładowania baterii"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Urządzenie aktywne"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Zapisano"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktywne, tylko lewa strona"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktywne, tylko prawa strona"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktywny, lewa i prawa strona"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 38df760..5bc01f1 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Ativo"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Salvo"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ativo, apenas o esquerdo"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ativo, apenas o direito"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ativo, esquerdo e direito"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 9e98623..f0b94bf 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Bateria. <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Ativo"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Guardado"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ativo, apenas esquerdo"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ativo, apenas direito"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ativo, esquerdo e direito"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 38df760..5bc01f1 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Ativo"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Salvo"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ativo, apenas o esquerdo"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ativo, apenas o direito"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ativo, esquerdo e direito"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index dddc116..4d6638a 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Nivelul bateriei: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Activ"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Salvat"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Activ, numai stânga"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Activ, numai dreapta"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Activ, stânga și dreapta"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 9a5a400..e155948 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Уровень заряда: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Батарея <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активно"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Сохранено"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 0fce42b..dff692e 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ක්‍රියාකාරී"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"සුරැකිණි"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 74c9e1f..e85e96d 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Batéria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batéria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktívne"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Uložené"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktívne, iba ľavá strana"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktívne, iba pravá strana"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktívne, ľavá aj pravá strana"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index a6d35c80..6eb655c 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Baterija na <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterija: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivna"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Shranjeno"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivno, samo levo"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivno, samo desno"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivno, levo in desno"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 3f6e803..f112060 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Bateria <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> bateri"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Të ruajtura"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktive, vetëm majtas"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktive, vetëm djathtas"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktive, majtas dhe djathtas"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 135176b..9341616 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Батерија, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активан"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Сачувано"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 7712203..d3370e8 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batteri: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Sparad"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, bara vänster"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, bara höger"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, vänster och höger"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 53d583a..d230022 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Kimeunganishwa"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Imeokoa"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Inatumika, kushoto pekee"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Inatumika, kulia pekee"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Inatumika, kushoto na kulia"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index db11263..8097be0 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> பேட்டரி"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"பேட்டரி <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"செயலில் உள்ளது"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"சேமிக்கப்பட்டது"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index c2faca9..a9d4c03 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> బ్యాటరీ"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"యాక్టివ్‌గా ఉంది"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"సేవ్ చేయబడింది"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 7b03f81..8f59f36 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"ใช้งานอยู่"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"บันทึกแล้ว"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 8eef17e..58b6e84 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterya"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Baterya <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktibo"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Na-save"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktibo, kaliwa lang"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktibo, kanan lang"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktibo, kaliwa at kanan"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index cf5bd2d..0300ddc 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Pil düzeyi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Pil <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Etkin"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Kaydedildi"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Yalnızca sol tarafta etkin"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Yalnızca sağ tarafta etkin"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Sol ve sağ tarafta etkin"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 4b40503..807bc51 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> заряду акумулятора"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Заряд акумулятора: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Активовано"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Збережено"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index a1b2198..cee510b 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> بیٹری"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"بیٹری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"فعال"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"محفوظ ہے"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 82f4576..4415667 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Batareya: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Faol"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Saqlangan"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Faol, faqat chap"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Faol, faqat oʻng"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Faol, chap va oʻng"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 9a1386e..f33d909 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"Mức pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Pin <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Đang hoạt động"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Đã lưu"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Đang hoạt động, chỉ tai bên trái"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Đang hoạt động, chỉ tai phải"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Đang hoạt động, cả tai phải và tai trái"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index d3f8945..816ba8d 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> 的电量"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"电池电量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"使用中"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"已保存的设备"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index b5a1d51..b26efb2 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"使用中"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"已儲存"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index a131c12..149022c 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"使用中"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"已儲存"</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>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index f9bdfbf..7aea126 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -98,9 +98,9 @@
     <skip />
     <!-- no translation found for bluetooth_active_battery_level_untethered (4961338936672922617) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_left (5521405563527657515) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_left (2895644748625343977) -->
     <skip />
-    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7165552824664523336) -->
+    <!-- no translation found for bluetooth_active_battery_level_untethered_right (7407517998880370179) -->
     <skip />
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ibhethri"</string>
     <string name="tv_bluetooth_battery_level" msgid="8786353985605532846">"Ibhethri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -112,9 +112,12 @@
     <skip />
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Iyasebenza"</string>
     <string name="bluetooth_saved_device" msgid="4895871321722311428">"Ilondoloziwe"</string>
-    <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Iyasebenza, ngakwesokunxele kuphela"</string>
-    <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Iyasebenza, ngakwesokudla kuphela"</string>
-    <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Iyasebenza, ngakwesokunxele nakwesokudla"</string>
+    <!-- no translation found for bluetooth_hearing_aid_left_active (8330226430756799572) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_right_active (2244728507170385397) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_left_and_right_active (4294571497939983181) -->
+    <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level (7772517511061834073) -->
     <skip />
     <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (7444753133664620926) -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
index fa27db9..dc40304 100644
--- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
@@ -202,8 +202,8 @@
             dreamInfo.componentName = componentName;
             dreamInfo.isActive = dreamInfo.componentName.equals(activeDream);
 
-            final DreamService.DreamMetadata dreamMetadata = DreamService.getDreamMetadata(mContext,
-                    resolveInfo.serviceInfo);
+            final DreamService.DreamMetadata dreamMetadata = DreamService.getDreamMetadata(
+                    mContext.getPackageManager(), resolveInfo.serviceInfo);
             if (dreamMetadata != null) {
                 dreamInfo.settingsComponentName = dreamMetadata.settingsActivity;
                 dreamInfo.previewImage = dreamMetadata.previewImage;
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-bs/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bs/strings.xml
index 749a6f2..199b0c9 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-bs/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bs/strings.xml
@@ -9,7 +9,7 @@
     <string name="power_label" msgid="7699720321491287839">"Napajanje"</string>
     <string name="power_utterance" msgid="7444296686402104807">"Opcije napajanja"</string>
     <string name="recent_apps_label" msgid="6583276995616385847">"Nedavne aplikacije"</string>
-    <string name="lockscreen_label" msgid="648347953557887087">"Zaključavanje ekrana"</string>
+    <string name="lockscreen_label" msgid="648347953557887087">"Zaključani ekran"</string>
     <string name="quick_settings_label" msgid="2999117381487601865">"Brze postavke"</string>
     <string name="notifications_label" msgid="6829741046963013567">"Obavještenja"</string>
     <string name="screenshot_label" msgid="863978141223970162">"Snimak ekrana"</string>
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index fadef1e..7ae93e5 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -525,6 +525,13 @@
 }
 
 flag {
+   name: "smartspace_lockscreen_viewmodel"
+   namespace: "systemui"
+   description: "Indicate Smartspace lockscreen viewmodel"
+   bug: "331451011"
+}
+
+flag {
    name: "pin_input_field_styled_focus_state"
    namespace: "systemui"
    description: "Enables styled focus states on pin input field if keyboard is connected"
@@ -828,3 +835,13 @@
     description: "Enforce BaseUserRestriction for DISALLOW_CONFIG_BRIGHTNESS."
     bug: "329205638"
 }
+
+flag {
+  name: "ambient_touch_monitor_listen_to_display_changes"
+  namespace: "systemui"
+  description: "listen to display changes and cache window metrics"
+  bug: "330906135"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffect.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffect.kt
deleted file mode 100644
index ffa2b46..0000000
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffect.kt
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.surfaceeffects.revealeffect
-
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
-import android.animation.ValueAnimator
-import android.graphics.RenderEffect
-import androidx.core.graphics.ColorUtils
-import com.android.systemui.surfaceeffects.RenderEffectDrawCallback
-import com.android.systemui.surfaceeffects.utils.MathUtils
-import kotlin.math.max
-import kotlin.math.min
-
-/** Creates a reveal effect with a circular ripple sparkles on top. */
-class RippleRevealEffect(
-    private val config: RippleRevealEffectConfig,
-    private val renderEffectCallback: RenderEffectDrawCallback,
-    private val stateChangedCallback: AnimationStateChangedCallback? = null
-) {
-    private val rippleRevealShader = RippleRevealShader().apply { applyConfig(config) }
-    private val animator: ValueAnimator = ValueAnimator.ofFloat(0f, 1f)
-
-    fun play() {
-        if (animator.isRunning) {
-            return
-        }
-
-        animator.duration = config.duration.toLong()
-        animator.addUpdateListener { updateListener ->
-            val playTime = updateListener.currentPlayTime.toFloat()
-            rippleRevealShader.setTime(playTime * TIME_SCALE_FACTOR)
-
-            // Compute radius.
-            val progress = updateListener.animatedValue as Float
-            val innerRad = MathUtils.lerp(config.innerRadiusStart, config.innerRadiusEnd, progress)
-            val outerRad = MathUtils.lerp(config.outerRadiusStart, config.outerRadiusEnd, progress)
-            rippleRevealShader.setInnerRadius(innerRad)
-            rippleRevealShader.setOuterRadius(outerRad)
-
-            // Compute alphas.
-            val innerAlphaProgress =
-                MathUtils.constrainedMap(
-                    1f,
-                    0f,
-                    config.innerFadeOutStart,
-                    config.duration,
-                    playTime
-                )
-            val outerAlphaProgress =
-                MathUtils.constrainedMap(
-                    1f,
-                    0f,
-                    config.outerFadeOutStart,
-                    config.duration,
-                    playTime
-                )
-            val innerAlpha = MathUtils.lerp(0f, 255f, innerAlphaProgress)
-            val outerAlpha = MathUtils.lerp(0f, 255f, outerAlphaProgress)
-
-            val innerColor = ColorUtils.setAlphaComponent(config.innerColor, innerAlpha.toInt())
-            val outerColor = ColorUtils.setAlphaComponent(config.outerColor, outerAlpha.toInt())
-            rippleRevealShader.setInnerColor(innerColor)
-            rippleRevealShader.setOuterColor(outerColor)
-
-            // Pass in progresses since those functions take in normalized alpha values.
-            rippleRevealShader.setBackgroundAlpha(max(innerAlphaProgress, outerAlphaProgress))
-            rippleRevealShader.setSparkleAlpha(min(innerAlphaProgress, outerAlphaProgress))
-
-            // Trigger draw callback.
-            renderEffectCallback.onDraw(
-                RenderEffect.createRuntimeShaderEffect(
-                    rippleRevealShader,
-                    RippleRevealShader.BACKGROUND_UNIFORM
-                )
-            )
-        }
-        animator.addListener(
-            object : AnimatorListenerAdapter() {
-                override fun onAnimationEnd(animation: Animator) {
-                    stateChangedCallback?.onAnimationEnd()
-                }
-            }
-        )
-        animator.start()
-        stateChangedCallback?.onAnimationStart()
-    }
-
-    interface AnimationStateChangedCallback {
-        fun onAnimationStart()
-        fun onAnimationEnd()
-    }
-
-    private companion object {
-        private const val TIME_SCALE_FACTOR = 0.00175f
-    }
-}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectConfig.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectConfig.kt
deleted file mode 100644
index 9675f19..0000000
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectConfig.kt
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.surfaceeffects.revealeffect
-
-import android.graphics.Color
-
-/** Defines parameters needed for [RippleRevealEffect]. */
-data class RippleRevealEffectConfig(
-    /** Total duration of the animation. */
-    val duration: Float = 0f,
-    /** Timestamp of when the inner mask starts fade out. (Linear fadeout) */
-    val innerFadeOutStart: Float = 0f,
-    /** Timestamp of when the outer mask starts fade out. (Linear fadeout) */
-    val outerFadeOutStart: Float = 0f,
-    /** Center x position of the effect. */
-    val centerX: Float = 0f,
-    /** Center y position of the effect. */
-    val centerY: Float = 0f,
-    /** Start radius of the inner circle. */
-    val innerRadiusStart: Float = 0f,
-    /** End radius of the inner circle. */
-    val innerRadiusEnd: Float = 0f,
-    /** Start radius of the outer circle. */
-    val outerRadiusStart: Float = 0f,
-    /** End radius of the outer circle. */
-    val outerRadiusEnd: Float = 0f,
-    /**
-     * Pixel density of the display. Do not pass a random value. The value must come from
-     * [context.resources.displayMetrics.density].
-     */
-    val pixelDensity: Float = 1f,
-    /**
-     * The amount the circle masks should be softened. Higher value will make the edge of the circle
-     * mask soft.
-     */
-    val blurAmount: Float = 0f,
-    /** Color of the inner circle mask. */
-    val innerColor: Int = Color.WHITE,
-    /** Color of the outer circle mask. */
-    val outerColor: Int = Color.WHITE,
-    /** Multiplier to make the sparkles visible. */
-    val sparkleStrength: Float = SPARKLE_STRENGTH,
-    /** Size of the sparkle. Expected range [0, 1]. */
-    val sparkleScale: Float = SPARKLE_SCALE
-) {
-    /** Default parameters. */
-    companion object {
-        const val SPARKLE_STRENGTH: Float = 0.3f
-        const val SPARKLE_SCALE: Float = 0.8f
-    }
-}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealShader.kt
deleted file mode 100644
index a3f9795..0000000
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealShader.kt
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.surfaceeffects.revealeffect
-
-import android.graphics.RuntimeShader
-import com.android.systemui.surfaceeffects.shaderutil.SdfShaderLibrary
-import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary
-
-/** Circular reveal effect with sparkles. */
-class RippleRevealShader : RuntimeShader(SHADER) {
-    // language=AGSL
-    companion object {
-        const val BACKGROUND_UNIFORM = "in_dst"
-        private const val MAIN =
-            """
-            uniform shader ${BACKGROUND_UNIFORM};
-            uniform half in_dstAlpha;
-            uniform half in_time;
-            uniform vec2 in_center;
-            uniform half in_innerRadius;
-            uniform half in_outerRadius;
-            uniform half in_sparkleStrength;
-            uniform half in_blur;
-            uniform half in_pixelDensity;
-            uniform half in_sparkleScale;
-            uniform half in_sparkleAlpha;
-            layout(color) uniform vec4 in_innerColor;
-            layout(color) uniform vec4 in_outerColor;
-
-            vec4 main(vec2 p) {
-                half innerMask = soften(sdCircle(p - in_center, in_innerRadius), in_blur);
-                half outerMask = soften(sdCircle(p - in_center, in_outerRadius), in_blur);
-
-                // Flip it since we are interested in the circle.
-                innerMask = 1.-innerMask;
-                outerMask = 1.-outerMask;
-
-                // Color two circles using the mask.
-                vec4 inColor = vec4(in_innerColor.rgb, 1.) * in_innerColor.a;
-                vec4 outColor = vec4(in_outerColor.rgb, 1.) * in_outerColor.a;
-                vec4 blend = mix(inColor, outColor, innerMask);
-
-                vec4 dst = vec4(in_dst.eval(p).rgb, 1.);
-                dst *= in_dstAlpha;
-
-                blend *= blend.a;
-                // Do normal blend with the background.
-                blend = blend + dst * (1. - blend.a);
-
-                half sparkle =
-                    sparkles(p - mod(p, in_pixelDensity * in_sparkleScale), in_time);
-                // Add sparkles using additive blending.
-                blend += sparkle * in_sparkleStrength * in_sparkleAlpha;
-
-                // Mask everything at the end.
-                blend *= outerMask;
-
-                return blend;
-            }
-        """
-
-        private const val SHADER =
-            ShaderUtilLibrary.SHADER_LIB +
-                SdfShaderLibrary.SHADER_SDF_OPERATION_LIB +
-                SdfShaderLibrary.CIRCLE_SDF +
-                MAIN
-    }
-
-    fun applyConfig(config: RippleRevealEffectConfig) {
-        setCenter(config.centerX, config.centerY)
-        setInnerRadius(config.innerRadiusStart)
-        setOuterRadius(config.outerRadiusStart)
-        setBlurAmount(config.blurAmount)
-        setPixelDensity(config.pixelDensity)
-        setSparkleScale(config.sparkleScale)
-        setSparkleStrength(config.sparkleStrength)
-        setInnerColor(config.innerColor)
-        setOuterColor(config.outerColor)
-    }
-
-    fun setTime(time: Float) {
-        setFloatUniform("in_time", time)
-    }
-
-    fun setCenter(centerX: Float, centerY: Float) {
-        setFloatUniform("in_center", centerX, centerY)
-    }
-
-    fun setInnerRadius(radius: Float) {
-        setFloatUniform("in_innerRadius", radius)
-    }
-
-    fun setOuterRadius(radius: Float) {
-        setFloatUniform("in_outerRadius", radius)
-    }
-
-    fun setBlurAmount(blurAmount: Float) {
-        setFloatUniform("in_blur", blurAmount)
-    }
-
-    fun setPixelDensity(density: Float) {
-        setFloatUniform("in_pixelDensity", density)
-    }
-
-    fun setSparkleScale(scale: Float) {
-        setFloatUniform("in_sparkleScale", scale)
-    }
-
-    fun setSparkleStrength(strength: Float) {
-        setFloatUniform("in_sparkleStrength", strength)
-    }
-
-    fun setInnerColor(color: Int) {
-        setColorUniform("in_innerColor", color)
-    }
-
-    fun setOuterColor(color: Int) {
-        setColorUniform("in_outerColor", color)
-    }
-
-    /** Sets the background alpha. Range [0,1]. */
-    fun setBackgroundAlpha(alpha: Float) {
-        setFloatUniform("in_dstAlpha", alpha)
-    }
-
-    /** Sets the sparkle alpha. Range [0,1]. */
-    fun setSparkleAlpha(alpha: Float) {
-        setFloatUniform("in_sparkleAlpha", alpha)
-    }
-}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/utils/MathUtils.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/utils/MathUtils.kt
deleted file mode 100644
index 1411c32..0000000
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/utils/MathUtils.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.surfaceeffects.utils
-
-/** Copied from android.utils.MathUtils */
-object MathUtils {
-    fun constrainedMap(
-        rangeMin: Float,
-        rangeMax: Float,
-        valueMin: Float,
-        valueMax: Float,
-        value: Float
-    ): Float {
-        return lerp(rangeMin, rangeMax, lerpInvSat(valueMin, valueMax, value))
-    }
-
-    fun lerp(start: Float, stop: Float, amount: Float): Float {
-        return start + (stop - start) * amount
-    }
-
-    fun lerpInv(a: Float, b: Float, value: Float): Float {
-        return if (a != b) (value - a) / (b - a) else 0.0f
-    }
-
-    fun saturate(value: Float): Float {
-        return constrain(value, 0.0f, 1.0f)
-    }
-
-    fun lerpInvSat(a: Float, b: Float, value: Float): Float {
-        return saturate(lerpInv(a, b, value))
-    }
-
-    fun constrain(amount: Float, low: Float, high: Float): Float {
-        return if (amount < low) low else if (amount > high) high else amount
-    }
-}
diff --git a/packages/SystemUI/checks/Android.bp b/packages/SystemUI/checks/Android.bp
index 1f502e3..addcaf4 100644
--- a/packages/SystemUI/checks/Android.bp
+++ b/packages/SystemUI/checks/Android.bp
@@ -39,7 +39,7 @@
     srcs: ["tests/**/*.kt"],
     data: [
         ":framework",
-        ":androidx.annotation_annotation-nodeps",
+        ":androidx.annotation_annotation",
         ":kotlinx-coroutines-core",
     ],
     static_libs: [
diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/AndroidStubs.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/AndroidStubs.kt
index edfd59a..e1cca88 100644
--- a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/AndroidStubs.kt
+++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/AndroidStubs.kt
@@ -22,7 +22,7 @@
 internal val libraryNames =
     arrayOf(
         "framework.jar",
-        "androidx.annotation_annotation-nodeps.jar",
+        "androidx.annotation_annotation.jar",
         "kotlinx-coroutines-core.jar",
     )
 
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt
index 19d6038..7af8408 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt
@@ -52,7 +52,6 @@
 import com.android.internal.R
 import com.android.systemui.bouncer.ui.viewmodel.PatternBouncerViewModel
 import com.android.systemui.bouncer.ui.viewmodel.PatternDotViewModel
-import kotlin.math.max
 import kotlin.math.min
 import kotlin.math.pow
 import kotlin.math.sqrt
@@ -110,30 +109,14 @@
         remember(dots) {
             dots.associateWith { dot -> with(density) { (80 + (20 * dot.y)).dp.toPx() } }
         }
-    val dotAppearScaleAnimatables = remember(dots) { dots.associateWith { Animatable(0f) } }
     LaunchedEffect(Unit) {
         dotAppearFadeInAnimatables.forEach { (dot, animatable) ->
             scope.launch {
-                // Maps a dot at x and y to an ordinal number to denote the order in which all dots
-                // are visited by the fade-in animation.
-                //
-                // The order is basically starting from the top-left most dot (at 0,0) and ending at
-                // the bottom-right most dot (at 2,2). The visitation order happens
-                // diagonal-by-diagonal. Here's a visual representation of the expected output:
-                // [0][1][3]
-                // [2][4][6]
-                // [5][7][8]
-                //
-                // There's an assumption here that the grid is 3x3. If it's not, this formula needs
-                // to be revisited.
-                check(viewModel.columnCount == 3 && viewModel.rowCount == 3)
-                val staggerOrder = max(0, min(8, 2 * (dot.x + dot.y) + (dot.y - 1)))
-
                 animatable.animateTo(
                     targetValue = 1f,
                     animationSpec =
                         tween(
-                            delayMillis = 33 * staggerOrder,
+                            delayMillis = 33 * dot.y,
                             durationMillis = 450,
                             easing = Easings.LegacyDecelerate,
                         )
@@ -153,19 +136,6 @@
                 )
             }
         }
-        dotAppearScaleAnimatables.forEach { (dot, animatable) ->
-            scope.launch {
-                animatable.animateTo(
-                    targetValue = 1f,
-                    animationSpec =
-                        tween(
-                            delayMillis = 33 * dot.y,
-                            durationMillis = 450,
-                            easing = Easings.LegacyDecelerate,
-                        )
-                )
-            }
-        }
     }
 
     val view = LocalView.current
@@ -401,10 +371,7 @@
                         ),
                     color =
                         dotColor.copy(alpha = checkNotNull(dotAppearFadeInAnimatables[dot]).value),
-                    radius =
-                        dotRadius *
-                            checkNotNull(dotScalingAnimatables[dot]).value *
-                            checkNotNull(dotAppearScaleAnimatables[dot]).value,
+                    radius = dotRadius * checkNotNull(dotScalingAnimatables[dot]).value
                 )
             }
         }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
index 89d4343..338987a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
@@ -132,6 +132,7 @@
 import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel
 import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.communal.ui.viewmodel.PopupType
 import com.android.systemui.communal.widgets.WidgetConfigurator
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.phone.SystemUIDialogFactory
@@ -148,8 +149,7 @@
     onEditDone: (() -> Unit)? = null,
 ) {
     val communalContent by viewModel.communalContent.collectAsState(initial = emptyList())
-    val isPopupOnDismissCtaShowing by
-        viewModel.isPopupOnDismissCtaShowing.collectAsState(initial = false)
+    val currentPopup by viewModel.currentPopup.collectAsState(initial = null)
     var removeButtonCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
     var toolbarSize: IntSize? by remember { mutableStateOf(null) }
     var gridCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
@@ -161,7 +161,6 @@
     val removeButtonEnabled by remember {
         derivedStateOf { selectedKey.value != null || reorderingWidgets }
     }
-    var isButtonToEditWidgetsShowing by remember { mutableStateOf(false) }
     val isEmptyState by viewModel.isEmptyState.collectAsState(initial = false)
 
     val contentPadding = gridContentPadding(viewModel.isEditMode, toolbarSize)
@@ -214,7 +213,7 @@
                                         communalContent[index] is
                                             CommunalContentModel.CtaTileInViewMode
                                 ) {
-                                    isButtonToEditWidgetsShowing = true
+                                    viewModel.onShowCustomizeWidgetButton()
                                 }
                                 val key =
                                     index?.let { keyAtIndexIfEditable(communalContent, index) }
@@ -290,18 +289,22 @@
             )
         }
 
-        if (isPopupOnDismissCtaShowing) {
-            PopupOnDismissCtaTile(viewModel::onHidePopupAfterDismissCta)
-        }
-
-        if (isButtonToEditWidgetsShowing) {
-            ButtonToEditWidgets(
-                onClick = {
-                    isButtonToEditWidgetsShowing = false
-                    viewModel.onOpenWidgetEditor(selectedKey.value)
-                },
-                onHide = { isButtonToEditWidgetsShowing = false },
-            )
+        if (currentPopup != null) {
+            when (currentPopup) {
+                PopupType.CtaTile -> {
+                    PopupOnDismissCtaTile(viewModel::onHidePopup)
+                }
+                PopupType.CustomizeWidgetButton -> {
+                    ButtonToEditWidgets(
+                        onClick = {
+                            viewModel.onHidePopup()
+                            viewModel.onOpenWidgetEditor(selectedKey.value)
+                        },
+                        onHide = { viewModel.onHidePopup()}
+                    )
+                }
+                null -> {}
+            }
         }
 
         if (viewModel is CommunalViewModel && dialogFactory != null) {
@@ -679,11 +682,11 @@
 }
 
 @Composable
-private fun PopupOnDismissCtaTile(onHidePopupAfterDismissCta: () -> Unit) {
+private fun PopupOnDismissCtaTile(onHidePopup: () -> Unit) {
     Popup(
         alignment = Alignment.TopCenter,
         offset = IntOffset(0, 40),
-        onDismissRequest = onHidePopupAfterDismissCta
+        onDismissRequest = onHidePopup
     ) {
         val colors = LocalAndroidColorScheme.current
         Row(
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
index a595c66..f78ed2f 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
@@ -658,12 +658,28 @@
         targetOffset: Float,
         targetScene: SceneKey,
     ): OffsetAnimation {
+        // Skip the animation if we have already reached the target scene and the overscroll does
+        // not animate anything.
+        val hasReachedTargetScene =
+            (targetScene == toScene && progress >= 1f) ||
+                (targetScene == fromScene && progress <= 0f)
+        val skipAnimation =
+            hasReachedTargetScene &&
+                currentOverscrollSpec?.transformationSpec?.transformations?.isEmpty() == true
+
         return startOffsetAnimation {
             val animatable = Animatable(dragOffset, OffsetVisibilityThreshold)
             val isTargetGreater = targetOffset > animatable.value
             val job =
                 coroutineScope
                     .launch {
+                        // TODO(b/327249191): Refactor the code so that we don't even launch a
+                        // coroutine if we don't need to animate.
+                        if (skipAnimation) {
+                            snapToScene(targetScene)
+                            return@launch
+                        }
+
                         try {
                             val swipeSpec =
                                 transformationSpec.swipeSpec
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
index 2ed51eb..1fd1bf4 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
@@ -1007,4 +1007,23 @@
         dragController.onDragStopped(velocity = 0f)
         assertTransition(isUserInputOngoing = false)
     }
+
+    @Test
+    fun emptyOverscrollImmediatelyAbortsSettleAnimationWhenOverProgress() = runGestureTest {
+        // Overscrolling on scene B does nothing.
+        layoutState.transitions = transitions { overscroll(SceneB, Orientation.Vertical) {} }
+
+        // Swipe up to scene B at progress = 200%.
+        val middle = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f)
+        val dragController = onDragStarted(startedPosition = middle, overSlop = up(2f))
+        assertTransition(fromScene = SceneA, toScene = SceneB, progress = 2f)
+
+        // Release the finger.
+        dragController.onDragStopped(velocity = -velocityThreshold)
+
+        // Exhaust all coroutines *without advancing the clock*. Given that we are at progress >=
+        // 100% and that the overscroll on scene B is doing nothing, we are already idle.
+        runCurrent()
+        assertIdle(SceneB)
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
index 779e79ed..c96a8ce 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
@@ -20,9 +20,9 @@
 import android.appwidget.AppWidgetProviderInfo
 import android.content.pm.UserInfo
 import android.os.UserHandle
+import android.platform.test.flag.junit.FlagsParameterization
 import android.provider.Settings
 import android.widget.RemoteViews
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
 import com.android.systemui.SysuiTestCase
@@ -38,9 +38,11 @@
 import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel.Companion.POPUP_AUTO_HIDE_TIMEOUT_MS
+import com.android.systemui.communal.ui.viewmodel.PopupType
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
+import com.android.systemui.flags.andSceneContainer
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
@@ -50,8 +52,9 @@
 import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
 import com.android.systemui.media.controls.ui.view.MediaHost
 import com.android.systemui.settings.fakeUserTracker
-import com.android.systemui.shade.data.repository.fakeShadeRepository
+import com.android.systemui.shade.ShadeTestUtil
 import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.shadeTestUtil
 import com.android.systemui.smartspace.data.repository.FakeSmartspaceRepository
 import com.android.systemui.smartspace.data.repository.fakeSmartspaceRepository
 import com.android.systemui.testKosmos
@@ -70,11 +73,13 @@
 import org.mockito.Mockito
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(AndroidJUnit4::class)
-class CommunalViewModelTest : SysuiTestCase() {
+@RunWith(ParameterizedAndroidJunit4::class)
+class CommunalViewModelTest(flags: FlagsParameterization?) : SysuiTestCase() {
     @Mock private lateinit var mediaHost: MediaHost
     @Mock private lateinit var user: UserInfo
     @Mock private lateinit var providerInfo: AppWidgetProviderInfo
@@ -88,9 +93,14 @@
     private lateinit var smartspaceRepository: FakeSmartspaceRepository
     private lateinit var mediaRepository: FakeCommunalMediaRepository
     private lateinit var userRepository: FakeUserRepository
+    private lateinit var shadeTestUtil: ShadeTestUtil
 
     private lateinit var underTest: CommunalViewModel
 
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags!!)
+    }
+
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
@@ -101,6 +111,7 @@
         smartspaceRepository = kosmos.fakeSmartspaceRepository
         mediaRepository = kosmos.fakeCommunalMediaRepository
         userRepository = kosmos.fakeUserRepository
+        shadeTestUtil = kosmos.shadeTestUtil
 
         kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
         mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB)
@@ -237,7 +248,7 @@
             tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
 
             val communalContent by collectLastValue(underTest.communalContent)
-            val isPopupOnDismissCtaShowing by collectLastValue(underTest.isPopupOnDismissCtaShowing)
+            val currentPopup by collectLastValue(underTest.currentPopup)
 
             assertThat(communalContent?.size).isEqualTo(1)
             assertThat(communalContent?.get(0))
@@ -247,11 +258,11 @@
 
             // hide CTA tile and show the popup
             assertThat(communalContent).isEmpty()
-            assertThat(isPopupOnDismissCtaShowing).isEqualTo(true)
+            assertThat(currentPopup).isEqualTo(PopupType.CtaTile)
 
             // hide popup after time elapsed
             advanceTimeBy(POPUP_AUTO_HIDE_TIMEOUT_MS)
-            assertThat(isPopupOnDismissCtaShowing).isEqualTo(false)
+            assertThat(currentPopup).isNull()
         }
 
     @Test
@@ -259,14 +270,40 @@
         testScope.runTest {
             tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
 
-            val isPopupOnDismissCtaShowing by collectLastValue(underTest.isPopupOnDismissCtaShowing)
+            val currentPopup by collectLastValue(underTest.currentPopup)
 
             underTest.onDismissCtaTile()
-            assertThat(isPopupOnDismissCtaShowing).isEqualTo(true)
+            assertThat(currentPopup).isEqualTo(PopupType.CtaTile)
 
             // dismiss the popup directly
-            underTest.onHidePopupAfterDismissCta()
-            assertThat(isPopupOnDismissCtaShowing).isEqualTo(false)
+            underTest.onHidePopup()
+            assertThat(currentPopup).isNull()
+        }
+
+    @Test
+    fun customizeWidgetButton_showsThenHidesAfterTimeout() =
+        testScope.runTest {
+            tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
+            val currentPopup by collectLastValue(underTest.currentPopup)
+
+            assertThat(currentPopup).isNull()
+            underTest.onShowCustomizeWidgetButton()
+            assertThat(currentPopup).isEqualTo(PopupType.CustomizeWidgetButton)
+            advanceTimeBy(POPUP_AUTO_HIDE_TIMEOUT_MS)
+            assertThat(currentPopup).isNull()
+        }
+
+    @Test
+    fun customizeWidgetButton_onDismiss_hidesImmediately() =
+        testScope.runTest {
+            tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
+            val currentPopup by collectLastValue(underTest.currentPopup)
+
+            underTest.onShowCustomizeWidgetButton()
+            assertThat(currentPopup).isEqualTo(PopupType.CustomizeWidgetButton)
+
+            underTest.onHidePopup()
+            assertThat(currentPopup).isNull()
         }
 
     @Test
@@ -274,7 +311,7 @@
         testScope.runTest {
             // On keyguard without any shade expansion.
             kosmos.fakeKeyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
-            kosmos.fakeShadeRepository.setLockscreenShadeExpansion(0f)
+            shadeTestUtil.setLockscreenShadeExpansion(0f)
             runCurrent()
             assertThat(underTest.canChangeScene()).isTrue()
         }
@@ -284,7 +321,7 @@
         testScope.runTest {
             // On keyguard with shade fully expanded.
             kosmos.fakeKeyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
-            kosmos.fakeShadeRepository.setLockscreenShadeExpansion(1f)
+            shadeTestUtil.setLockscreenShadeExpansion(1f)
             runCurrent()
             assertThat(underTest.canChangeScene()).isFalse()
         }
@@ -297,5 +334,11 @@
 
     private companion object {
         val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN)
+
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return FlagsParameterization.allCombinationsOf().andSceneContainer()
+        }
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
index 11f9e1c..eef2337 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
@@ -17,6 +17,9 @@
 
 import android.content.ComponentName
 import android.content.Intent
+import android.os.RemoteException
+import android.platform.test.annotations.EnableFlags
+import android.service.dreams.Flags
 import android.service.dreams.IDreamOverlay
 import android.service.dreams.IDreamOverlayCallback
 import android.service.dreams.IDreamOverlayClient
@@ -44,7 +47,9 @@
 import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
 import com.android.systemui.communal.data.repository.FakeCommunalRepository
 import com.android.systemui.communal.data.repository.fakeCommunalRepository
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.setCommunalAvailable
 import com.android.systemui.communal.shared.model.CommunalScenes
 import com.android.systemui.complication.ComplicationHostViewController
 import com.android.systemui.complication.ComplicationLayoutEngine
@@ -57,12 +62,14 @@
 import com.android.systemui.touch.TouchInsetManager
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -70,6 +77,9 @@
 import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.isNull
+import org.mockito.Mockito.spy
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
@@ -87,6 +97,8 @@
 
     private lateinit var lifecycleRegistry: FakeLifecycleRegistry
 
+    lateinit var mCommunalInteractor: CommunalInteractor
+
     private lateinit var mWindowParams: WindowManager.LayoutParams
 
     @Mock lateinit var mDreamOverlayCallback: IDreamOverlayCallback
@@ -162,6 +174,9 @@
         whenever(mComplicationComponent.getComplicationHostViewController())
             .thenReturn(mComplicationHostViewController)
         whenever(mLifecycleOwner.registry).thenReturn(lifecycleRegistry)
+
+        mCommunalInteractor = Mockito.spy(kosmos.communalInteractor)
+
         whenever(mComplicationComponentFactory.create(any(), any(), any(), any()))
             .thenReturn(mComplicationComponent)
         whenever(mComplicationComponent.getVisibilityController())
@@ -192,7 +207,7 @@
                 mStateController,
                 mKeyguardUpdateMonitor,
                 mScrimManager,
-                kosmos.communalInteractor,
+                mCommunalInteractor,
                 mSystemDialogsCloser,
                 mUiEventLogger,
                 mTouchInsetManager,
@@ -605,6 +620,57 @@
             .isTrue()
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT)
+    @kotlin.Throws(RemoteException::class)
+    fun testTransitionToGlanceableHub() =
+        testScope.runTest {
+            // Inform the overlay service of dream starting. Do not show dream complications.
+            client.startDream(
+                mWindowParams,
+                mDreamOverlayCallback,
+                DREAM_COMPONENT,
+                false /*shouldShowComplication*/
+            )
+            mMainExecutor.runAllReady()
+
+            verify(mDreamOverlayCallback).onRedirectWake(false)
+            clearInvocations(mDreamOverlayCallback)
+            kosmos.setCommunalAvailable(true)
+            mMainExecutor.runAllReady()
+            runCurrent()
+            verify(mDreamOverlayCallback).onRedirectWake(true)
+            client.onWakeRequested()
+            verify(mCommunalInteractor).changeScene(eq(CommunalScenes.Communal), isNull())
+        }
+
+    @Test
+    @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT)
+    @Throws(RemoteException::class)
+    fun testRedirectExit() =
+        testScope.runTest {
+            // Inform the overlay service of dream starting. Do not show dream complications.
+            client.startDream(
+                mWindowParams,
+                mDreamOverlayCallback,
+                DREAM_COMPONENT,
+                false /*shouldShowComplication*/
+            )
+            // Set communal available, verify that overlay callback is informed.
+            kosmos.setCommunalAvailable(true)
+            mMainExecutor.runAllReady()
+            runCurrent()
+            verify(mDreamOverlayCallback).onRedirectWake(true)
+
+            clearInvocations(mDreamOverlayCallback)
+
+            // Set communal unavailable, verify that overlay callback is informed.
+            kosmos.setCommunalAvailable(false)
+            mMainExecutor.runAllReady()
+            runCurrent()
+            verify(mDreamOverlayCallback).onRedirectWake(false)
+        }
+
     // Tests that the bouncer closes when DreamOverlayService is told that the dream is coming to
     // the front.
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt
similarity index 92%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt
index 6f17c55..d702330 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt
@@ -36,7 +36,6 @@
 import android.platform.test.annotations.EnableFlags
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.internal.widget.lockPatternUtils
 import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -54,16 +53,15 @@
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.whenever
 import junit.framework.Assert.assertEquals
-import kotlin.test.Test
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
+import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.spy
 
@@ -93,6 +91,7 @@
         // Transition to AOD and set the power interactor asleep.
         powerInteractor.setAsleepForTest()
         runBlocking {
+            kosmos.fakeKeyguardRepository.setKeyguardShowing(false)
             transitionRepository.sendTransitionSteps(
                 from = KeyguardState.LOCKSCREEN,
                 to = KeyguardState.AOD,
@@ -108,7 +107,7 @@
     fun testTransitionToLockscreen_onWakeup() =
         testScope.runTest {
             powerInteractor.setAwakeForTest()
-            runCurrent()
+            advanceTimeBy(100) // account for debouncing
 
             // Under default conditions, we should transition to LOCKSCREEN when waking up.
             assertThat(transitionRepository)
@@ -124,7 +123,7 @@
         testScope.runTest {
             kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true)
             powerInteractor.setAwakeForTest()
-            runCurrent()
+            advanceTimeBy(100) // account for debouncing
 
             // Waking with a SHOW_WHEN_LOCKED activity on top should transition to OCCLUDED.
             assertThat(transitionRepository)
@@ -140,7 +139,7 @@
         testScope.runTest {
             powerInteractor.onCameraLaunchGestureDetected()
             powerInteractor.setAwakeForTest()
-            runCurrent()
+            advanceTimeBy(100) // account for debouncing
 
             // We should head back to GONE since we started there.
             assertThat(transitionRepository)
@@ -154,7 +153,7 @@
             kosmos.fakeKeyguardRepository.setKeyguardDismissible(true)
             powerInteractor.onCameraLaunchGestureDetected()
             powerInteractor.setAwakeForTest()
-            runCurrent()
+            advanceTimeBy(100) // account for debouncing
 
             // We should head back to GONE since we started there.
             assertThat(transitionRepository)
@@ -191,7 +190,7 @@
             reset(transitionRepository)
             powerInteractor.onCameraLaunchGestureDetected()
             powerInteractor.setAwakeForTest()
-            runCurrent()
+            advanceTimeBy(100) // account for debouncing
 
             // We should head back to GONE since we started there.
             assertThat(transitionRepository)
@@ -225,7 +224,7 @@
             reset(transitionRepository)
             powerInteractor.onCameraLaunchGestureDetected()
             powerInteractor.setAwakeForTest()
-            runCurrent()
+            advanceTimeBy(100) // account for debouncing
 
             // We should go to OCCLUDED - we came from GONE, but we finished in AOD, so this is no
             // longer an insecure camera launch and it would be bad if we unlocked now.
@@ -266,7 +265,7 @@
             reset(transitionRepository)
             powerInteractor.onCameraLaunchGestureDetected()
             powerInteractor.setAwakeForTest()
-            runCurrent()
+            advanceTimeBy(100) // account for debouncing
 
             // We should head back to GONE since we started there.
             assertThat(transitionRepository)
@@ -286,7 +285,7 @@
             assertThat(transitionRepository).noTransitionsStarted()
 
             underTest.dismissAod()
-            runCurrent()
+            advanceTimeBy(100) // account for debouncing
 
             assertThat(transitionRepository)
                 .startedTransition(from = KeyguardState.AOD, to = KeyguardState.GONE)
@@ -297,7 +296,7 @@
         testScope.runTest {
             kosmos.fakeKeyguardRepository.setKeyguardOccluded(true)
             powerInteractor.setAwakeForTest()
-            runCurrent()
+            advanceTimeBy(100) // account for debouncing
 
             // Waking up from AOD while occluded should transition to OCCLUDED.
             assertThat(transitionRepository)
@@ -307,11 +306,10 @@
     @Test
     fun testTransitionToGone_onWakeUpFromAod_dismissibleKeyguard_securityNone() =
         testScope.runTest {
-            whenever(kosmos.lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true)
+            kosmos.fakeKeyguardRepository.setKeyguardShowing(false)
             kosmos.fakeKeyguardRepository.setKeyguardDismissible(true)
             powerInteractor.setAwakeForTest()
-            testScope.testScheduler.advanceTimeBy(100) // account for debouncing
-            runCurrent()
+            advanceTimeBy(100) // account for debouncing
 
             // We should head back to GONE since we started there.
             assertThat(transitionRepository)
@@ -319,15 +317,13 @@
         }
 
     @Test
-    fun testTransitionToGone_onWakeUpFromAod_dismissibleKeyguard_securitySwipe() =
+    fun testTransitionToLockscreen_onWakeUpFromAod_dismissibleKeyguard_securitySwipe() =
         testScope.runTest {
-            whenever(kosmos.lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false)
+            kosmos.fakeKeyguardRepository.setKeyguardShowing(true)
             kosmos.fakeKeyguardRepository.setKeyguardDismissible(true)
             powerInteractor.setAwakeForTest()
-            testScope.testScheduler.advanceTimeBy(100) // account for debouncing
-            runCurrent()
+            advanceTimeBy(100) // account for debouncing
 
-            // We should head back to GONE since we started there.
             assertThat(transitionRepository)
                 .startedTransition(from = KeyguardState.AOD, to = KeyguardState.LOCKSCREEN)
         }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/SmartspaceViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/SmartspaceViewModelTest.kt
new file mode 100644
index 0000000..ffbbeb90
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/SmartspaceViewModelTest.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.smartspace
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
+import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.smartspace.ui.viewmodel.SmartspaceViewModel
+import com.android.systemui.smartspace.viewmodel.smartspaceViewModelFactory
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.firstOrNull
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.withTimeoutOrNull
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SmartspaceViewModelTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+
+    private val powerInteractor = kosmos.powerInteractor
+    private val smartspaceViewModelFactory = kosmos.smartspaceViewModelFactory
+
+    private lateinit var underTest: SmartspaceViewModel
+
+    @Test
+    fun dateVew_isAwakeTrue_true() =
+        testScope.runTest {
+            underTest = smartspaceViewModelFactory.create(SmartspaceViewModel.SURFACE_DATE_VIEW)
+
+            powerInteractor.setAwakeForTest()
+            val isAwake by collectLastValue(underTest.isAwake)
+
+            assertThat(isAwake).isTrue()
+        }
+
+    @Test
+    fun dateVew_isAwakeFalse_false() =
+        testScope.runTest {
+            underTest = smartspaceViewModelFactory.create(SmartspaceViewModel.SURFACE_DATE_VIEW)
+
+            powerInteractor.setAsleepForTest()
+            val isAwake by collectLastValue(underTest.isAwake)
+
+            assertThat(isAwake).isFalse()
+        }
+
+    @Test
+    fun dateVew_isAwakeMultipleTimes_correctResults() =
+        testScope.runTest {
+            underTest = smartspaceViewModelFactory.create(SmartspaceViewModel.SURFACE_DATE_VIEW)
+            val isAwake by collectLastValue(underTest.isAwake)
+
+            powerInteractor.setAsleepForTest()
+
+            assertThat(isAwake).isFalse()
+
+            powerInteractor.setAwakeForTest()
+
+            assertThat(isAwake).isTrue()
+
+            powerInteractor.setAsleepForTest()
+
+            assertThat(isAwake).isFalse()
+
+            powerInteractor.setAwakeForTest()
+
+            assertThat(isAwake).isTrue()
+        }
+
+    @Test
+    fun weatherView_isAwakeTrue_doesNotEmit() =
+        testScope.runTest {
+            underTest = smartspaceViewModelFactory.create(SmartspaceViewModel.SURFACE_WEATHER_VIEW)
+
+            powerInteractor.setAwakeForTest()
+            val isAwake = withTimeoutOrNull(100) { underTest.isAwake.firstOrNull() }
+
+            assertThat(isAwake).isNull()
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/EventsTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/EventsTest.java
similarity index 96%
rename from packages/SystemUI/tests/src/com/android/systemui/volume/EventsTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/volume/EventsTest.java
index c69f5c8..87e1f86 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/EventsTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/EventsTest.java
@@ -34,12 +34,15 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Queue;
 
+import platform.test.runner.parameterized.Parameter;
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
 /**
  * Parameterized unit test for Events.logEvent.
  *
@@ -51,7 +54,7 @@
  * either SysuiTestCase or SysUiBaseFragmentTest.
  *
  */
-@RunWith(Parameterized.class)
+@RunWith(ParameterizedAndroidJunit4.class)
 @SmallTest
 public class EventsTest extends SysuiTestCase {
     private FakeMetricsLogger mLegacyLogger;
@@ -66,23 +69,23 @@
     }
 
     // Parameters for calling writeEvent with arbitrary args.
-    @Parameterized.Parameter
+    @Parameter
     public int mTag;
 
-    @Parameterized.Parameter(1)
+    @Parameter(1)
     public Object[] mArgs;
 
     // Expect returned string exactly matches.
-    @Parameterized.Parameter(2)
+    @Parameter(2)
     public String mExpectedMessage;
 
     // Expect these MetricsLogger calls.
 
-    @Parameterized.Parameter(3)
+    @Parameter(3)
     public int[] mExpectedMetrics;
 
     // Expect this UiEvent (use null if there isn't one).
-    @Parameterized.Parameter(4)
+    @Parameter(4)
     public UiEventLogger.UiEventEnum mUiEvent;
 
     @Test
@@ -108,7 +111,10 @@
         }
     }
 
-    @Parameterized.Parameters(name = "{index}: {2}")
+    /**
+     * Collection of parameters for the test.
+     */
+    @Parameters(name = "{index}: {2}")
     public static Collection<Object[]> data() {
         return Arrays.asList(new Object[][]{
                 {Events.EVENT_SETTINGS_CLICK, null,
@@ -217,4 +223,3 @@
         });
     }
 }
-
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/UtilTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/UtilTest.java
similarity index 95%
rename from packages/SystemUI/tests/src/com/android/systemui/volume/UtilTest.java
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/volume/UtilTest.java
index 483dc0c..d6c63af 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/UtilTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/UtilTest.java
@@ -19,13 +19,16 @@
 
 import android.media.MediaMetadata;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @SmallTest
+@RunWith(AndroidJUnit4.class)
 public class UtilTest extends SysuiTestCase {
 
     @Test
diff --git a/packages/SystemUI/res-product/values-or/strings.xml b/packages/SystemUI/res-product/values-or/strings.xml
index 5d9345b..a89dd7b 100644
--- a/packages/SystemUI/res-product/values-or/strings.xml
+++ b/packages/SystemUI/res-product/values-or/strings.xml
@@ -30,9 +30,9 @@
     <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_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>
diff --git a/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml
index 8e3cf4d..91ca69e 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml
@@ -47,7 +47,7 @@
         android:layout_height="wrap_content"
         android:fillViewport="true"
         android:fadeScrollbars="false"
-        android:paddingBottom="36dp"
+        android:paddingBottom="24dp"
         android:paddingHorizontal="24dp"
         android:paddingTop="24dp"
         app:layout_constrainedHeight="true"
diff --git a/packages/SystemUI/res/raw/keep.xml b/packages/SystemUI/res/raw/keep.xml
new file mode 100644
index 0000000..645e3c5
--- /dev/null
+++ b/packages/SystemUI/res/raw/keep.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<resources xmlns:tools="http://schemas.android.com/tools"
+    tools:keep="@drawable/homecontrols_sq" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 63c6132..799b88a 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -458,8 +458,7 @@
     <string name="work_mode_off_title" msgid="5794818421357835873">"Hervat werkapps?"</string>
     <string name="work_mode_turn_on" msgid="907813741770247267">"Hervat"</string>
     <string name="accessibility_action_label_close_communal_hub" msgid="6790396569621032333">"Maak legstukke op sluitskerm toe"</string>
-    <!-- no translation found for accessibility_action_label_edit_widgets (3821868581348322346) -->
-    <skip />
+    <string name="accessibility_action_label_edit_widgets" msgid="3821868581348322346">"Pasmaak legstukke"</string>
     <string name="accessibility_content_description_for_communal_hub" msgid="1670220840599380118">"Legstukke op sluitskerm"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Wissel gebruiker"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"aftrekkieslys"</string>
@@ -656,6 +655,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelliet, swak verbinding"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliet, goeie toestand"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliet, verbinding is beskikbaar"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Werkprofiel"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Pret vir party mense, maar nie vir almal nie"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Stelsel-UI-ontvanger gee jou ekstra maniere om die Android-gebruikerkoppelvlak in te stel en te pasmaak. Hierdie eksperimentele kenmerke kan in toekomstige uitreikings verander, breek of verdwyn. Gaan versigtig voort."</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 1c80547..6db4e02 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ሳተላይት፣ ደካማ ግንኙነት"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ሳተላይት፣ ጥሩ ግንኙነት"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ሳተላይት፣ ግንኙነት አለ"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"የስራ መገለጫ"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"ለአንዳንዶች አስደሳች ቢሆንም ለሁሉም አይደለም"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"የስርዓት በይነገጽ መቃኛ የAndroid ተጠቃሚ በይነገጹን የሚነካኩበት እና የሚያበጁበት ተጨማሪ መንገዶች ይሰጠዎታል። እነዚህ የሙከራ ባህሪዎች ወደፊት በሚኖሩ ልቀቶች ላይ ሊለወጡ፣ ሊሰበሩ ወይም ሊጠፉ ይችላሉ። ከጥንቃቄ ጋር ወደፊት ይቀጥሉ።"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index c92a32b..7f89ab49 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"قمر صناعي، الاتصال ضعيف"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"قمر صناعي، الاتصال جيد"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"قمر صناعي، الاتصال متوفّر"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"ملف العمل"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"متعة للبعض وليس للجميع"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"‏توفر لك أداة ضبط واجهة مستخدم النظام طرقًا إضافية لتعديل واجهة مستخدم Android وتخصيصها. ويمكن أن تطرأ تغييرات على هذه الميزات التجريبية أو يمكن أن تتعطل هذه الميزات أو تختفي في الإصدارات المستقبلية. عليك متابعة الاستخدام مع توخي الحذر."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index f1291a0..c2dc3b0 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"উপগ্ৰহ, বেয়া সংযোগ"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"উপগ্ৰহ, ভাল সংযোগ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"উপগ্ৰহ, সংযোগ উপলব্ধ"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"কিছুমানৰ বাবে আমোদজনক হয় কিন্তু সকলোৰে বাবে নহয়"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tunerএ আপোনাক Android ব্যৱহাৰকাৰী ইণ্টাৰফেইচ সলনি কৰিবলৈ আৰু নিজৰ উপযোগিতা অনুসৰি ব্যৱহাৰ কৰিবলৈ অতিৰিক্ত সুবিধা প্ৰদান কৰে। এই পৰীক্ষামূলক সুবিধাসমূহ সলনি হ\'ব পাৰে, সেইবোৰে কাম নকৰিব পাৰে বা আগন্তুক সংস্কৰণসমূহত সেইবোৰ অন্তৰ্ভুক্ত কৰা নহ’ব পাৰে। সাৱধানেৰে আগবাঢ়ক।"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index b12d822..853a020 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Peyk, bağlantı zəifdir"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Peyk, bağlantı yaxşıdır"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Peyk, bağlantı var"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"İş profili"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Hamı üçün deyil, bəziləri üçün əyləncəli"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner Android istifadəçi interfeysini dəyişdirmək və fərdiləşdirmək üçün Sizə ekstra yollar təklif edir."</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 221d16c..80cc48f 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -371,8 +371,7 @@
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Slušni aparati"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Upari novi uređaj"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da biste uparili nov uređaj"</string>
-    <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
-    <skip />
+    <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje zadatih podešavanja nije uspelo"</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>
@@ -656,6 +655,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, veza je loša"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, veza je dobra"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index d1c4a98..d64ffe8 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Спадарожнікавая сувязь, дрэннае падключэнне"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спадарожнікавая сувязь, добрае падключэнне"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Спадарожнікавая сувязь, падключэнне даступнае"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Працоўны профіль"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Цікава для некаторых, але не для ўсіх"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Наладка сістэмнага інтэрфейсу карыстальніка дае вам дадатковыя спосабы наладжвання і дапасоўвання карыстальніцкага інтэрфейсу Android. Гэтыя эксперыментальныя функцыі могуць змяніцца, перастаць працаваць або знікнуць у будучых версіях. Карыстайцеся з асцярожнасцю."</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 62d3fed..b3321f5 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Сателит, лоша връзка"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Сателит, добра връзка"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Сателит, налице е връзка"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Потребителски профил в Work"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Забавно – но не за всички"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Тунерът на системния потребителски интерфейс ви предоставя допълнителни възможности за прецизиране и персонализиране на практическата работа с Android. Тези експериментални функции може да се променят, повредят или да изчезнат в бъдещите версии. Действайте внимателно."</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 81e3fc4..5c3d96b 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"স্যাটেলাইট, খারাপ কানেকশন"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"স্যাটেলাইট, ভালো কানেকশন"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"স্যাটেলাইট, কানেকশন উপলভ্য আছে"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 7d66851..f3ffe26 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -235,8 +235,8 @@
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Obavještenja sa sjenčenjem."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Brze postavke."</string>
     <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Brze postavke i lokacija za obavještenja."</string>
-    <string name="accessibility_desc_lock_screen" msgid="409034672704273634">"Zaključavanje ekrana"</string>
-    <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Zaključan ekran radnog profila"</string>
+    <string name="accessibility_desc_lock_screen" msgid="409034672704273634">"Zaključani ekran"</string>
+    <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Zaključani ekran radnog profila"</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>
@@ -643,7 +643,7 @@
     <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Ažuriranje"</string>
     <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Otključajte da koristite"</string>
     <string name="wallet_error_generic" msgid="257704570182963611">"Došlo je do problema prilikom preuzimanja vaših kartica. Pokušajte ponovo kasnije"</string>
-    <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Postavke zaključavanja ekrana"</string>
+    <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Postavke 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žuriranje"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Radni profil"</string>
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, slaba veza"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra veza"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Radni profil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Zabava za neke, ali ne za sve"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Podešavač za korisnički interfejs sistema vam omogućava dodatne načine da podesite i prilagodite Androidov interfejs. Ove eksperimentalne funkcije se u budućim verzijama mogu mijenjati, kvariti ili nestati. Budite oprezni."</string>
@@ -775,7 +779,7 @@
     <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Otvaranje liste aplikacija"</string>
     <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otvaranje postavki"</string>
     <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvaranje Asistenta"</string>
-    <string name="group_system_lock_screen" msgid="7391191300363416543">"Zaključavanje ekrana"</string>
+    <string name="group_system_lock_screen" msgid="7391191300363416543">"Zaključani ekran"</string>
     <string name="group_system_quick_memo" msgid="3764560265935722903">"Pisanje bilješke"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Multitasking"</string>
     <string name="system_multitasking_rhs" msgid="8714224917276297810">"Korištenje podijeljenog ekrana s trenutnom aplikacijom na desnoj strani"</string>
@@ -1275,8 +1279,8 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pređite na radni profil"</string>
     <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalirajte poslovnu aplikaciju za telefon"</string>
     <string name="call_from_work_profile_close" msgid="5830072964434474143">"Otkaži"</string>
-    <string name="lock_screen_settings" msgid="6152703934761402399">"Prilagodi zaključavanje ekrana"</string>
-    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Otključajte da prilagodite zaključavanje ekrana"</string>
+    <string name="lock_screen_settings" msgid="6152703934761402399">"Prilagodi zaključani ekran"</string>
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Otključajte da prilagodite zaključani ekran"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"WiFi mreža nije dostupna"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera je blokirana"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera i mikrofon su blokirani"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 87af353..341dca5 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -371,8 +371,7 @@
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Audiòfons"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Vincula un dispositiu nou"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fes clic per vincular un dispositiu nou"</string>
-    <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
-    <skip />
+    <string name="hearing_devices_presets_error" msgid="350363093458408536">"No s\'ha pogut actualitzar el valor predefinit"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vols desbloquejar el micròfon del dispositiu?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vols desbloquejar la càmera del dispositiu?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vols desbloquejar la càmera i el micròfon del dispositiu?"</string>
@@ -656,6 +655,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satèl·lit, connexió deficient"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satèl·lit, bona connexió"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satèl·lit, connexió disponible"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de treball"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversió per a uns quants, però no per a tothom"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"El Personalitzador d\'interfície d\'usuari presenta opcions addicionals per canviar i personalitzar la interfície d\'usuari d\'Android. És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució."</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 102768f..ad5a76ac 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, špatné připojení"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobré připojení"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, připojení je k dispozici"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Pracovní profil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Zábava, která není pro každého"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Nástroj na ladění uživatelského rozhraní systému vám nabízí další způsoby, jak si vyladit a přizpůsobit uživatelské rozhraní Android. Tyto experimentální funkce mohou v dalších verzích chybět, nefungovat nebo být změněny. Postupujte proto prosím opatrně."</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index d3138ab..f65364f 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellit – dårlig forbindelse"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit – god forbindelse"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit – forbindelsen er tilgængelig"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Arbejdsprofil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Sjovt for nogle, men ikke for alle"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner giver dig flere muligheder for at justere og tilpasse Android-brugerfladen. Disse eksperimentelle funktioner kan ændres, gå i stykker eller forsvinde i fremtidige udgivelser. Vær forsigtig, hvis du fortsætter."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 03d04a6..3161b86 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellit, Verbindung schlecht"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit, Verbindung gut"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit, Verbindung verfügbar"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Arbeitsprofil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Für einige ein Vergnügen, aber nicht für alle"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Mit System UI Tuner erhältst du zusätzliche Möglichkeiten, die Android-Benutzeroberfläche anzupassen. Achtung: Diese Testfunktionen können sich ändern, abstürzen oder in zukünftigen Versionen verschwinden."</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 89092ad..33dc496 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Δορυφορική, κακή σύνδεση"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Δορυφορική, καλή σύνδεση"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Δορυφορική, διαθέσιμη σύνδεση"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Προφίλ εργασίας"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Διασκέδαση για ορισμένους, αλλά όχι για όλους"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Το System UI Tuner σάς προσφέρει επιπλέον τρόπους για να τροποποιήσετε και να προσαρμόσετε τη διεπαφή χρήστη Android. Αυτές οι πειραματικές λειτουργίες ενδέχεται να τροποποιηθούν, να παρουσιάσουν σφάλματα ή να καταργηθούν σε μελλοντικές εκδόσεις. Συνεχίστε με προσοχή."</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 459de64..e0786ce 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, poor connection"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 4879850..8b71d4b 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -654,6 +654,8 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, poor connection"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string>
+    <string name="satellite_connected_carrier_text" msgid="7942466244369263272">"Connected to satellite"</string>
+    <string name="satellite_not_connected_carrier_text" msgid="3471375076594005077">"Not connected to satellite"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customize the Android user interface. These experimental features may change, break, or disappear in future releases. Proceed with caution."</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 459de64..e0786ce 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, poor connection"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 459de64..e0786ce 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, poor connection"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work profile"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Fun for some but not for all"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index a2340bd..f32b774 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -654,6 +654,8 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎Satellite, poor connection‎‏‎‎‏‎"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎Satellite, good connection‎‏‎‎‏‎"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‎‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎Satellite, connection available‎‏‎‎‏‎"</string>
+    <string name="satellite_connected_carrier_text" msgid="7942466244369263272">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎‎‏‎‏‎‏‎‏‎‏‎‏‎‎‎‎Connected to satellite‎‏‎‎‏‎"</string>
+    <string name="satellite_not_connected_carrier_text" msgid="3471375076594005077">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‏‎Not connected to satellite‎‏‎‎‏‎"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎Work profile‎‏‎‎‏‎"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‎‏‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‏‏‎Fun for some but not for all‎‏‎‎‏‎"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‎‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎System UI Tuner gives you extra ways to tweak and customize the Android user interface. These experimental features may change, break, or disappear in future releases. Proceed with caution.‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 202bd93..3b6f249 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, conexión inestable"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, buena conexión"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión disponible"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabajo"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversión para algunos, pero no para todos"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"El sintonizador de IU del sistema te brinda más formas para editar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, dejar de funcionar o no incluirse en futuras versiones. Procede con precaución."</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 88fab2d..42d403d 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, mala conexión"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, buena conexión"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión disponible"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabajo"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversión solo para algunos"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"El configurador de UI del sistema te ofrece otras formas de modificar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, fallar o desaparecer en futuras versiones. Te recomendamos que tengas cuidado."</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 1b4cea7..f3c75a4 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -371,8 +371,7 @@
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Kuuldeseadmed"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Uue seadme sidumine"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Uue seadme sidumiseks klõpsake"</string>
-    <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
-    <skip />
+    <string name="hearing_devices_presets_error" msgid="350363093458408536">"Eelseadistust ei saanud värskendada"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kas tühistada seadme mikrofoni blokeerimine?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kas tühistada seadme kaamera blokeerimine?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Kas tühistada seadme kaamera ja mikrofoni blokeerimine?"</string>
@@ -656,6 +655,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelliit, kehv ühendus"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliit, hea ühendus"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliit, ühendus on saadaval"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Tööprofiil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Kõik ei pruugi sellest rõõmu tunda"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Süsteemi kasutajaliidese tuuner pakub täiendavaid võimalusi Androidi kasutajaliidese muutmiseks ja kohandamiseks. Need katselised funktsioonid võivad muutuda, rikki minna või tulevastest versioonidest kaduda. Olge jätkamisel ettevaatlik."</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index b69ef30..da885b7 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelitea, konexio ahula"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelitea, konexio ona"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelitea, konexioa erabilgarri"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Laneko profila"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Dibertsioa batzuentzat, baina ez guztientzat"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Sistemaren erabiltzaile-interfazearen konfiguratzaileak Android erabiltzaile-interfazea moldatzeko eta pertsonalizatzeko modu gehiago eskaintzen dizkizu. Baliteke eginbide esperimental horiek hurrengo kaleratzeetan aldatuta, etenda edo desagertuta egotea. Kontuz erabili."</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 94fb12f..b63ec78 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ماهواره، اتصال ضعیف است"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ماهواره، اتصال خوب است"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ماهواره، اتصال دردسترس است"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"نمایه کاری"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"برای بعضی افراد سرگرم‌کننده است اما نه برای همه"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"‏«تنظیم‌کننده واسط کاربری سیستم» روش‌های بیشتری برای تنظیم دقیق و سفارشی کردن واسط کاربری Android در اختیار شما قرار می‌دهد. ممکن است این ویژگی‌های آزمایشی تغییر کنند، خراب شوند یا در نسخه‌های آینده جود نداشته باشند. با احتیاط ادامه دهید."</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index a7754b0..21df7c7 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -371,8 +371,7 @@
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Kuulolaitteet"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Muodosta uusi laitepari"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Muodosta uusi laitepari klikkaamalla"</string>
-    <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
-    <skip />
+    <string name="hearing_devices_presets_error" msgid="350363093458408536">"Esiasetusta ei voitu muuttaa"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kumotaanko laitteen mikrofonin esto?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kumotaanko laitteen kameran esto?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Kumotaanko laitteen kameran ja mikrofonin esto?"</string>
@@ -656,6 +655,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelliitti, huono yhteys"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliitti, hyvä yhteys"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliitti, yhteys saatavilla"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Työprofiili"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Ei sovellu kaikkien käyttöön"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner antaa lisämahdollisuuksia Android-käyttöliittymän muokkaamiseen. Nämä kokeelliset ominaisuudet voivat muuttua, lakata toimimasta tai kadota milloin tahansa. Jatka omalla vastuullasi."</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 5bacaaa..850f977 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Connexion satellite faible"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Bonne connexion satellite"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Connexion satellite accessible"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil professionnel"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Divertissant pour certains, mais pas pour tous"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner vous propose de nouvelles manières d\'adapter et de personnaliser l\'interface utilisateur d\'Android. Ces fonctionnalités expérimentales peuvent être modifiées, cesser de fonctionner ou disparaître dans les versions futures. À utiliser avec prudence."</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index a4a039f1..0df8988 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -371,8 +371,7 @@
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Appareils auditifs"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Associer un nouvel appareil"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Cliquer pour associer un nouvel appareil"</string>
-    <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
-    <skip />
+    <string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossible de mettre à jour les préréglages"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le micro de l\'appareil ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer la caméra de l\'appareil ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Débloquer l\'appareil photo et le micro de l\'appareil ?"</string>
@@ -656,6 +655,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Mauvaise connexion satellite"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Bonne connexion satellite"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Connexion satellite disponible"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil professionnel"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Divertissant pour certains, mais pas pour tous"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner vous propose de nouvelles manières d\'adapter et de personnaliser l\'interface utilisateur Android. Ces fonctionnalités expérimentales peuvent être modifiées, cesser de fonctionner ou disparaître dans les versions futures. À utiliser avec prudence."</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index e2b1e53..10e8601 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, mala conexión"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, boa conexión"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión dispoñible"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de traballo"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversión só para algúns"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"O configurador da IU do sistema ofréceche formas adicionais de modificar e personalizar a interface de usuario de Android. Estas funcións experimentais poden cambiar, interromperse ou desaparecer en futuras versións. Continúa con precaución."</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 2883cc5..ebfe6f7 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"સૅટલાઇટ, નબળું કનેક્શન"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"સૅટલાઇટ, સારું કનેક્શન"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"સૅટલાઇટ, કનેક્શન ઉપલબ્ધ છે"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index f30957d..ea50302 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -371,8 +371,7 @@
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"कान की मशीनें"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"नया डिवाइस जोड़ें"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नया डिवाइस जोड़ने के लिए क्लिक करें"</string>
-    <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
-    <skip />
+    <string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रीसेट अपडेट नहीं किया जा सका"</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>
@@ -656,6 +655,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"सैटलाइट कनेक्शन खराब है"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"सैटलाइट कनेक्शन अच्छा है"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"सैटलाइट कनेक्शन उपलब्ध है"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"वर्क प्रोफ़ाइल"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"कुछ के लिए मज़ेदार लेकिन सबके लिए नहीं"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"सिस्टम यूज़र इंटरफ़ेस (यूआई) ट्यूनर, आपको Android यूज़र इंटरफ़ेस में सुधार लाने और उसे अपनी पसंद के हिसाब से बदलने के कुछ और तरीके देता है. प्रयोग के तौर पर इस्तेमाल हो रहीं ये सुविधाएं आगे चल कर रिलीज़ की जा सकती हैं, रोकी जा सकती हैं या दिखाई देना बंद हो सकती हैं. सावधानी से आगे बढ़ें."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index bada67e..b1849c5 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, slaba veza"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra veza"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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">"Ugađanje korisničkog sučelja sustava pruža vam dodatne načine za prilagodbu korisničkog sučelja Androida. Te se eksperimentalne značajke mogu promijeniti, prekinuti ili nestati u budućim izdanjima. Nastavite uz oprez."</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index d216fa4..ddae886 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -371,8 +371,7 @@
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Hallókészülékek"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Új eszköz párosítása"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kattintson új eszköz párosításához"</string>
-    <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
-    <skip />
+    <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nem sikerült frissíteni a beállításkészletet"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Feloldja az eszköz mikrofonjának letiltását?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Feloldja az eszköz kamerájának letiltását?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Feloldja az eszköz kamerájának és mikrofonjának letiltását?"</string>
@@ -656,6 +655,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Műhold, gyenge kapcsolat"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Műhold, jó kapcsolat"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Műhold, van rendelkezésre álló kapcsolat"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Munkaprofil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Egyeseknek tetszik, másoknak nem"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"A Kezelőfelület-hangoló az Android felhasználói felületének szerkesztéséhez és testreszabásához nyújt további megoldásokat. Ezek a kísérleti funkciók változhatnak vagy megsérülhetnek a későbbi kiadásokban, illetve eltűnhetnek azokból. Körültekintően járjon el."</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 034ac1a..717732d 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Արբանյակային թույլ կապ"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Արբանյակային լավ կապ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Հասանելի է արբանյակային կապ"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Աշխատանքային պրոֆիլ"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Զվարճանք մեկ՝ որոշակի մարդու համար"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Համակարգի ՕՄ-ի կարգավորիչը հնարավորություն է տալիս հարմարեցնել Android-ի օգտատիրոջ միջերեսը: Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index d428ef8..d5e353a 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, koneksi buruk"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, koneksi baik"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, koneksi tersedia"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil kerja"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Tidak semua orang menganggapnya baik"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Penyetel Antarmuka Pengguna Sistem memberikan cara tambahan untuk mengubah dan menyesuaikan antarmuka pengguna Android. Fitur eksperimental ini dapat berubah, rusak, atau menghilang dalam rilis di masa mendatang. Lanjutkan dengan hati-hati."</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 4b97299..2087907 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -371,8 +371,7 @@
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Heyrnartæki"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Para nýtt tæki"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Smelltu til að para nýtt tæki"</string>
-    <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
-    <skip />
+    <string name="hearing_devices_presets_error" msgid="350363093458408536">"Tókst ekki að uppfæra forstillingu"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Opna fyrir hljóðnema tækisins?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Opna fyrir myndavél tækisins?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Opna fyrir myndavél og hljóðnema tækisins?"</string>
@@ -656,6 +655,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Gervihnöttur, léleg tenging"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Gervihnöttur, góð tenging"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Gervihnöttur, tenging tiltæk"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Vinnusnið"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Þetta er ekki allra"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Fínstillingar kerfisviðmóts gera þér kleift að fínstilla og sérsníða notendaviðmót Android. Þessir tilraunaeiginleikar geta breyst, bilað eða horfið í síðari útgáfum. Gakktu því hægt um gleðinnar dyr."</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 30bdfae..32f72fd 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellitare, connessione debole"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellitare, connessione buona"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellitare, connessione disponibile"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profilo di lavoro"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Il divertimento riservato a pochi eletti"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"L\'Ottimizzatore UI di sistema mette a disposizione altri metodi per modificare e personalizzare l\'interfaccia utente di Android. Queste funzioni sperimentali potrebbero cambiare, interrompersi o scomparire nelle versioni successive. Procedi con cautela."</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index bc1d91f..13f2e50 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"לוויין, חיבור באיכות ירודה"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"לוויין, חיבור באיכות טובה"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"לוויין, יש חיבור זמין"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"פרופיל עבודה"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"מהנה בשביל חלק מהאנשים, אבל לא בשביל כולם"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"‏התכונה System UI Tuner מספקת לך דרכים נוספות להתאים אישית את ממשק המשתמש של Android. התכונות הניסיוניות האלה עשויות להשתנות, לא לעבוד כראוי או להיעלם בגרסאות עתידיות. יש להמשיך בזהירות."</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index b587f40..b31c01c 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"衛生、接続不安定"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛生、接続状態良好"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛生、接続利用可能"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index ff11d85..654acef 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"სუსტი სატელიტური კავშირი"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"კარგი სატელიტური კავშირი"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ხელმისაწვდომია სატელიტური კავშირი"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 995a796..0fda9f1 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Жерсерік, байланыс нашар."</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Жерсерік, байланыс жақсы."</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Жерсерік, байланыс бар."</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Жұмыс профилі"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Кейбіреулерге қызық, бірақ барлығына емес"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Жүйелік пайдаланушылық интерфейс тюнері Android пайдаланушылық интерфейсін реттеудің қосымша жолдарын береді. Бұл эксперименттік мүмкіндіктер болашақ шығарылымдарда өзгеруі, бұзылуы немесе жоғалуы мүмкін. Сақтықпен жалғастырыңыз."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index adcd3d6..262d87b 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ផ្កាយរណប ការតភ្ជាប់ខ្សោយ"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ផ្កាយរណប មានការតភ្ជាប់ល្អ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ផ្កាយរណប អាចតភ្ជាប់បាន"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index ca22ba1..14644cf 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -371,8 +371,7 @@
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"ಹಿಯರಿಂಗ್ ಸಾಧನಗಳು"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"ಹೊಸ ಸಾಧನವನ್ನು ಪೇರ್ ಮಾಡಿ"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಲು ಕ್ಲಿಕ್ ಮಾಡಿ"</string>
-    <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
-    <skip />
+    <string name="hearing_devices_presets_error" msgid="350363093458408536">"ಪ್ರಿಸೆಟ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</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>
@@ -656,6 +655,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ಸ್ಯಾಟಲೈಟ್‌, ಕನೆಕ್ಷನ್ ಕಳಪೆಯಾಗಿದೆ"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ಸ್ಯಾಟಲೈಟ್‌, ಕನೆಕ್ಷನ್ ಉತ್ತಮವಾಗಿದೆ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ಸ್ಯಾಟಲೈಟ್, ಕನೆಕ್ಷನ್ ಲಭ್ಯವಿದೆ"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 4e7c4d0..94cddf0 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"위성, 연결 상태 나쁨"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"위성, 연결 상태 양호"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"위성, 연결 가능"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 1d005fb..1561ac3 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Спутник, байланыш начар"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спутник, байланыш жакшы"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Спутник, байланыш бар"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Жумуш профили"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Баарына эле жага бербейт"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner Android колдонуучу интерфейсин жөнгө салып жана ыңгайлаштыруунун кошумча ыкмаларын сунуштайт. Бул сынамык функциялар кийинки чыгарылыштарда өзгөрүлүп, бузулуп же жоголуп кетиши мүмкүн. Абайлап колдонуңуз."</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index f95bb8e..0370454 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ດາວທຽມ, ການເຊື່ອມຕໍ່ບໍ່ດີ"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ດາວທຽມ, ການເຊື່ອມຕໍ່ດີ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ດາວທຽມ, ການເຊື່ອມຕໍ່ທີ່ພ້ອມນຳໃຊ້"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"​ໂປຣ​ໄຟລ໌​ບ່ອນ​ເຮັດ​ວຽກ"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"ມ່ວນຊື່ນສຳລັບບາງຄົນ ແຕ່ບໍ່ແມ່ນສຳລັບທຸກຄົນ"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner ໃຫ້ທ່ານມີວິທີພິເສດຕື່ມອີກໃນການປັບປ່ຽນ ແລະຕົບແຕ່ງສ່ວນຕໍ່ປະສານຜູ້ໃຊ້ຂອງ Android. ຄຸນສົມບັດທົດລອງໃຊ້ເຫຼົ່ານີ້ອາດຈະປ່ຽນແປງ, ຢຸດເຊົາ ຫຼືຫາຍໄປໃນການວາງຈຳໜ່າຍໃນອະນາຄົດ. ຈົ່ງດຳເນີນຕໍ່ດ້ວຍຄວາມລະມັດລະວັງ."</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 040294f..088a9fc 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Palydovas, prastas ryšys"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Palydovas, geras ryšys"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Palydovas, pasiekiamas ryšys"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Darbo profilis"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Smagu, bet ne visada"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Sistemos naudotojo sąsajos derinimo priemonė suteikia papildomų galimybių pagerinti ir tinkinti „Android“ naudotojo sąsają. Šios eksperimentinės funkcijos gali pasikeisti, nutrūkti ar išnykti iš būsimų laidų. Tęskite atsargiai."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index da58f33..09f0050 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelīts, vājš savienojums"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelīts, labs savienojums"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelīts, ir pieejams savienojums"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Darba profils"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Jautri dažiem, bet ne visiem"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Sistēmas saskarnes regulators sniedz papildu veidus, kā mainīt un pielāgot Android lietotāja saskarni. Nākamajās versijās šīs eksperimentālās funkcijas var tikt mainītas, bojātas vai to darbība var tikt pārtraukta. Turpinot esiet uzmanīgs."</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 2faf243..abac1ad 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Слаба сателитска врска"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Добра сателитска врска"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Достапна е сателитска врска"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Работен профил"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Забава за некои, но не за сите"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Адаптерот на УИ на системот ви дава дополнителни начини за дотерување и приспособување на корисничкиот интерфејс на Android. Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост."</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 2fd4411..5bf98b5 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"സാറ്റലൈറ്റ്, മോശം കണക്ഷൻ"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"സാറ്റലൈറ്റ്, മികച്ച കണക്ഷൻ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"സാറ്റലൈറ്റ്, കണക്ഷൻ ലഭ്യമാണ്"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"ചിലർക്ക് വിനോദം, എന്നാൽ എല്ലാവർക്കുമില്ല"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Android ഉപയോക്തൃ ഇന്റർഫേസ് ആവശ്യമുള്ള രീതിയിൽ മാറ്റുന്നതിനും ഇഷ്ടാനുസൃതമാക്കുന്നതിനും സിസ്റ്റം UI ട്യൂണർ നിങ്ങൾക്ക് അധിക വഴികൾ നൽകുന്നു. ഭാവി റിലീസുകളിൽ ഈ പരീക്ഷണാത്മക ഫീച്ചറുകൾ മാറ്റുകയോ നിർത്തുകയോ അപ്രത്യക്ഷമാവുകയോ ചെയ്തേക്കാം. ശ്രദ്ധയോടെ മുന്നോട്ടുപോകുക."</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 94cdf4c..608492a 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Хиймэл дагуул, холболт муу байна"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Хиймэл дагуул, холболт сайн байна"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Хиймэл дагуул, холболт боломжтой"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Ажлын профайл"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Зарим хүнд хөгжилтэй байж болох ч бүх хүнд тийм биш"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Системийн UI Tохируулагч нь Android хэрэглэгчийн интерфэйсийг тааруулах, өөрчлөх нэмэлт аргыг зааж өгөх болно. Эдгээр туршилтын тохиргоо нь цаашид өөрчлөгдөх, эвдрэх, алга болох магадлалтай. Үйлдлийг болгоомжтой хийнэ үү."</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index dd53db5..e83cc4e 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"सॅटेलाइट, खराब कनेक्शन"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"सॅटेलाइट, चांगले कनेक्शन"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"सॅटेलाइट, कनेक्शन उपलब्ध"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 6b858a4..ad0c440 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, sambungan yang lemah"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, sambungan yang baik"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, sambungan tersedia"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil kerja"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Menarik untuk sesetengah orang tetapi bukan untuk semua"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Penala UI Sistem memberi anda cara tambahan untuk mengolah dan menyesuaikan antara muka Android. Ciri eksperimen ini boleh berubah, rosak atau hilang dalam keluaran masa hadapan. Teruskan dengan berhati-hati."</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 2472d1f..078bfd7 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ဂြိုဟ်တု၊ ချိတ်ဆက်မှု မကောင်းပါ"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ဂြိုဟ်တု၊ ချိတ်ဆက်မှု ကောင်းသည်"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ဂြိုဟ်တု၊ ချိတ်ဆက်မှု ရနိုင်သည်"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"အလုပ် ပရိုဖိုင်"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"အချို့သူများ အတွက် ပျော်စရာ ဖြစ်ပေမဲ့ အားလုံး အတွက် မဟုတ်ပါ"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"စနစ် UI Tuner က သင့်အတွက် Android အသုံးပြုသူ အင်တာဖေ့စ်ကို ပြောင်းရန်နှင့် စိတ်ကြိုက်ပြုလုပ်ရန် နည်းလမ်း အပိုများကို သင့်အတွက် စီစဉ်ပေးသည်။ အနာဂတ်ဗားရှင်းများတွင် ဤစမ်းသပ်အင်္ဂါရပ်များမှာ ပြောင်းလဲ၊ ပျက်စီး သို့မဟုတ် ပျောက်ကွယ်သွားနိုင်သည်။ သတိဖြင့် ရှေ့ဆက်ပါ။"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 5bc2fe5..2634bd3 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellitt – dårlig tilkobling"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellitt – god tilkobling"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellitt – tilkobling tilgjengelig"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Work-profil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Gøy for noen – ikke for alle"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Med System UI Tuner har du flere måter å justere og tilpasse Android-brukergrensesnittet på. Disse eksperimentelle funksjonene kan endres, avbrytes eller fjernes i fremtidige utgivelser. Fortsett med forbehold."</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index f52466c..7f81a5f 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"स्याटलाइट, खराब कनेक्सन"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"स्याटलाइट, राम्रो कनेक्सन"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"स्याटलाइट, कनेक्सन उपलब्ध छ"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 7a37aa0..78566b8 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -656,6 +656,8 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelliet, slechte verbinding"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliet, goede verbinding"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliet, verbinding beschikbaar"</string>
+    <string name="satellite_connected_carrier_text" msgid="7942466244369263272">"Verbonden met satelliet"</string>
+    <string name="satellite_not_connected_carrier_text" msgid="3471375076594005077">"Niet verbonden met satelliet"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Werkprofiel"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Leuk voor sommige gebruikers, maar niet voor iedereen"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Met Systeem-UI-tuner beschikt u over extra manieren om de Android-gebruikersinterface aan te passen. Deze experimentele functies kunnen veranderen, vastlopen of verdwijnen in toekomstige releases. Ga voorzichtig verder."</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 7e8ee6f..03c7cf5 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ସାଟେଲାଇଟ, ଦୁର୍ବଳ କନେକ୍ସନ"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ସାଟେଲାଇଟ, ଭଲ କନେକ୍ସନ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ସାଟେଲାଇଟ, କନେକ୍ସନ ଉପଲବ୍ଧ"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"ୱର୍କ ପ୍ରୋଫାଇଲ୍‌"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"କେତେକଙ୍କ ପାଇଁ ମଜାଦାର, କିନ୍ତୁ ସମସ୍ତଙ୍କ ପାଇଁ ନୁହେଁ"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Android ୟୁଜର୍‍ ଇଣ୍ଟରଫେସ୍‍ ବଦଳାଇବାକୁ ତଥା ନିଜ ପସନ୍ଦ ଅନୁଯାୟୀ କରିବାକୁ ସିଷ୍ଟମ୍‍ UI ଟ୍ୟୁନର୍‍ ଆପଣଙ୍କୁ ଅତିରିକ୍ତ ଉପାୟ ପ୍ରଦାନ କରେ। ଏହି ପରୀକ୍ଷାମୂଳକ ସୁବିଧାମାନ ବଦଳିପାରେ, ଭାଙ୍ଗିପାରେ କିମ୍ବା ଭବିଷ୍ୟତର ରିଲିଜ୍‌ଗୁଡ଼ିକରେ ନଦେଖାଯାଇପାରେ। ସତର୍କତାର ସହ ଆଗକୁ ବଢ଼ନ୍ତୁ।"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index df823cf..6b88f29 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ਸੈਟੇਲਾਈਟ, ਕਨੈਕਸ਼ਨ ਖਰਾਬ ਹੈ"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ਸੈਟੇਲਾਈਟ, ਕਨੈਕਸ਼ਨ ਵਧੀਆ ਹੈ"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ਸੈਟੇਲਾਈਟ, ਕਨੈਕਸ਼ਨ ਉਪਲਬਧ ਹੈ"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index f6468af..d10d5f8 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -371,8 +371,7 @@
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Urządzenia słuchowe"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Sparuj nowe urządzenie"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknij, aby sparować nowe urządzenie"</string>
-    <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
-    <skip />
+    <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nie udało się zaktualizować gotowego ustawienia"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokować mikrofon urządzenia?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokować aparat urządzenia?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Odblokować aparat i mikrofon urządzenia?"</string>
@@ -656,6 +655,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelita – połączenie słabe"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelita – połączenie dobre"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelita – połączenie dostępne"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil służbowy"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Dobra zabawa, ale nie dla każdego"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Kalibrator System UI udostępnia dodatkowe sposoby dostrajania i dostosowywania interfejsu Androida. Te eksperymentalne funkcje mogą się zmienić, popsuć lub zniknąć w przyszłych wersjach. Zachowaj ostrożność."</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index a1c72dc..d0f70ed 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, conexão ruim"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, conexão boa"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexão disponível"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabalho"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversão para alguns, mas não para todos"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"O sintonizador System UI fornece maneiras adicionais de ajustar e personalizar a interface do usuário do Android. Esses recursos experimentais podem mudar, falhar ou desaparecer nas versões futuras. Prossiga com cuidado."</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index eadb5e54..7889e0b 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -656,6 +656,8 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, ligação fraca"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, boa ligação"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, ligação disponível"</string>
+    <string name="satellite_connected_carrier_text" msgid="7942466244369263272">"Ligação de satélite estabelecida"</string>
+    <string name="satellite_not_connected_carrier_text" msgid="3471375076594005077">"Não tem uma ligação de satélite estabelecida"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabalho"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversão para alguns, mas não para todos"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"O Sintonizador da interface do sistema disponibiliza-lhe formas adicionais ajustar e personalizar a interface do utilizador do Android. Estas funcionalidades experimentais podem ser alteradas, deixar de funcionar ou desaparecer em versões futuras. Prossiga com cuidado."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index a1c72dc..d0f70ed 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satélite, conexão ruim"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, conexão boa"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexão disponível"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Perfil de trabalho"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diversão para alguns, mas não para todos"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"O sintonizador System UI fornece maneiras adicionais de ajustar e personalizar a interface do usuário do Android. Esses recursos experimentais podem mudar, falhar ou desaparecer nas versões futuras. Prossiga com cuidado."</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index e53b4a4..8e4b752 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, conexiune slabă"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, conexiune bună"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, conexiune disponibilă"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil de serviciu"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Distractiv pentru unii, dar nu pentru toată lumea"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner oferă modalități suplimentare de a ajusta și a personaliza interfața de utilizare Android. Aceste funcții experimentale pot să se schimbe, să se blocheze sau să dispară din versiunile viitoare. Continuă cu prudență."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 8f6d7a8..d8d038e 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Спутниковая связь, плохое качество соединения"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спутниковая связь, хорошее качество соединения"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Доступно соединение по спутниковой связи"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Рабочий профиль"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Внимание!"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner позволяет настраивать интерфейс устройства Android по вашему вкусу. В будущем эта экспериментальная функция может измениться, перестать работать или исчезнуть."</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index afb5755..5082174 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"චන්ද්‍රිකාව, දුර්වල සම්බන්ධතාවය"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"චන්ද්‍රිකාව, හොඳ සම්බන්ධතාවයක්"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"චන්ද්‍රිකාව, සම්බන්ධතාවය තිබේ"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 453dd44..ffc9f27 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, slabá kvalita pripojenia"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobrá kvalita pripojenia"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, pripojenie je k dispozícii"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Pracovný profil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Pri používaní tuneru postupujte opatrne"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Tuner používateľského rozhrania systému poskytujte ďalšie spôsoby ladenia a prispôsobenia používateľského rozhrania Android. Tieto experimentálne funkcie sa môžu v budúcich verziách zmeniť, ich poskytovanie môže byť prerušené alebo môžu byť odstránené. Pokračujte opatrne."</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 27c376a..515286c 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satelit, slaba povezava"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra povezava"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, povezava je na voljo"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Delovni profil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Zabavno za nekatere, a ne za vse"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Uglaševalnik uporabniškega vmesnika sistema vam omogoča dodatne načine za spreminjanje in prilagajanje uporabniškega vmesnika Android. Te poskusne funkcije lahko v prihodnjih izdajah kadar koli izginejo, se spremenijo ali pokvarijo. Bodite previdni."</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 071eda7..99e5a7b 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Sateliti. Lidhje e dobët"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Sateliti. Lidhje e mirë"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Sateliti. Ofrohet lidhje"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profili i punës"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Argëtim për disa, por jo për të gjithë!"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit të jep mënyra shtesë për të tërhequr dhe personalizuar ndërfaqen Android të përdoruesit. Këto funksione eksperimentale mund të ndryshojnë, prishen ose zhduken në versionet e ardhshme. Vazhdo me kujdes."</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 233e516..e96d493 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -371,8 +371,7 @@
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Слушни апарати"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Упари нови уређај"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликните да бисте упарили нов уређај"</string>
-    <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
-    <skip />
+    <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ажурирање задатих подешавања није успело"</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>
@@ -656,6 +655,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Сателит, веза је лоша"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Сателит, веза је добра"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Сателит, веза је доступна"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Пословни профил"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Забава за неке, али не за све"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Тјунер за кориснички интерфејс система вам пружа додатне начине за подешавање и прилагођавање Android корисничког интерфејса. Ове експерименталне функције могу да се промене, откажу или нестану у будућим издањима. Будите опрезни."</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 579f526..7a5fa65 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellit, dålig anslutning"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit, bra anslutning"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit, anslutning tillgänglig"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Jobbprofil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Kul för vissa, inte för alla"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Du kan använda inställningarna för systemgränssnitt för att justera användargränssnittet i Android. Dessa experimentfunktioner kan när som helst ändras, sluta fungera eller försvinna. Använd med försiktighet."</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index bc7b016..9dae421 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -371,8 +371,7 @@
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Vifaa vya kusikilizia"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Unganisha kifaa kipya"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Bofya ili uunganishe kifaa kipya"</string>
-    <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
-    <skip />
+    <string name="hearing_devices_presets_error" msgid="350363093458408536">"Imeshindwa kusasisha mipangilio iliyowekwa mapema"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Ungependa kuwacha kuzuia maikrofoni ya kifaa?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Ungependa kuacha kuzuia kamera ya kifaa?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Ungependa kuwacha kuzuia kamera na maikrofoni ya kifaa?"</string>
@@ -656,6 +655,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Setilaiti, muunganisho hafifu"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Setilaiti, muunganisho thabiti"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Setilaiti, muunganisho unapatikana"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Wasifu wa kazini"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Kinafurahisha kwa baadhi ya watu lakini si wote"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Kirekebishi cha kiolesura cha mfumo kinakupa njia zaidi za kugeuza na kubadilisha kiolesura cha Android ili kikufae. Vipengele hivi vya majaribio vinaweza kubadilika, kuharibika au kupotea katika matoleo ya siku zijazo. Endelea kwa uangalifu."</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index b2c83dc..b418396 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"சாட்டிலைட், மோசமான இணைப்பு"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"சாட்டிலைட், நிலையான இணைப்பு"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"சாட்டிலைட், இணைப்பு கிடைக்கிறது"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"பணிக் கணக்கு"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"சில வேடிக்கையாக இருந்தாலும் கவனம் தேவை"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner, Android பயனர் இடைமுகத்தை மாற்றவும் தனிப்பயனாக்கவும் கூடுதல் வழிகளை வழங்குகிறது. இந்தப் பரிசோதனைக்குரிய அம்சங்கள் எதிர்கால வெளியீடுகளில் மாற்றப்படலாம், இடைநிறுத்தப்படலாம் அல்லது தோன்றாமல் போகலாம். கவனத்துடன் தொடரவும்."</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 5cd1341..a0a29d0 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"శాటిలైట్, కనెక్షన్ సరిగా లేదు"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"శాటిలైట్, కనెక్షన్ బాగుంది"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"శాటిలైట్, కనెక్షన్ అందుబాటులో ఉంది"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 544844d..0ef447e 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"ดาวเทียม, การเชื่อมต่อไม่ดี"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ดาวเทียม, การเชื่อมต่อดี"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ดาวเทียม, การเชื่อมต่อที่พร้อมใช้งาน"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 13e4bf8..975820a 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Satellite, mahina ang koneksyon"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, malakas ang koneksyon"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, may koneksyon"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profile sa trabaho"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Masaya para sa ilan ngunit hindi para sa lahat"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Nagbibigay sa iyo ang Tuner ng System UI ng mga karagdagang paraan upang baguhin at i-customize ang user interface ng Android. Ang mga pang-eksperimentong feature na ito ay maaaring magbago, masira o mawala sa mga pagpapalabas sa hinaharap. Magpatuloy nang may pag-iingat."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 30b6ce4..5b10259 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Uydu, bağlantı zayıf"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Uydu, bağlantı güçlü"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Uydu, bağlantı mevcut"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"İş profili"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Bazıları için eğlenceliyken diğerleri için olmayabilir"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Sistem Kullanıcı Arayüzü Ayarlayıcı, Android kullanıcı arayüzünde değişiklikler yapmanız ve arayüzü özelleştirmeniz için ekstra yollar sağlar. Bu deneysel özellikler değişebilir, bozulabilir veya gelecekteki sürümlerde yer almayabilir. Dikkatli bir şekilde devam edin."</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index e1d768e..071313f 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Погане з’єднання із супутником"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Хороше з’єднання із супутником"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Доступне з’єднання із супутником"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Робочий профіль"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Це цікаво, але будьте обачні"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner пропонує нові способи налаштувати та персоналізувати інтерфейс користувача Android. Ці експериментальні функції можуть змінюватися, не працювати чи зникати в майбутніх версіях. Будьте обачні."</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 16b40bf..e1b1fa4 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"سیٹلائٹ، کنکشن خراب ہے"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"سیٹلائٹ، کنکشن اچھا ہے"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"سیٹلائٹ، کنکشن دستیاب ہے"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <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>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 76694df..27145a6 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -371,8 +371,7 @@
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Eshitish qurilmalari"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Yangi qurilmani ulash"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yangi qurilmani ulash uchun bosing"</string>
-    <!-- no translation found for hearing_devices_presets_error (350363093458408536) -->
-    <skip />
+    <string name="hearing_devices_presets_error" msgid="350363093458408536">"Andoza yangilanmadi"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Qurilma mikrofoni blokdan chiqarilsinmi?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Qurilma kamerasi blokdan chiqarilsinmi?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Qurilma kamerasi va mikrofoni blokdan chiqarilsinmi?"</string>
@@ -656,6 +655,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Sputnik, aloqa sifati past"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Sputnik, aloqa sifati yaxshi"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Sputnik, aloqa mavjud"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Ish profili"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Diqqat!"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"System UI Tuner yordamida siz Android foydalanuvchi interfeysini tuzatish va o‘zingizga moslashtirishingiz mumkin. Ushbu tajribaviy funksiyalar o‘zgarishi, buzilishi yoki keyingi versiyalarda olib tashlanishi mumkin. Ehtiyot bo‘lib davom eting."</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 41066f9..84447fa 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Kết nối vệ tinh kém"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Kết nối vệ tinh tốt"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Hiện có kết nối vệ tinh"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Hồ sơ công việc"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Thú vị đối với một số người nhưng không phải tất cả"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Bộ điều hướng giao diện người dùng hệ thống cung cấp thêm cho bạn những cách chỉnh sửa và tùy chỉnh giao diện người dùng Android. Những tính năng thử nghiệm này có thể thay đổi, hỏng hoặc biến mất trong các phiên bản tương lai. Hãy thận trọng khi tiếp tục."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 60a46d60..eb928f0 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"卫星,连接质量不佳"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"卫星,连接质量良好"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"卫星,可连接"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"工作资料"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"并不适合所有用户"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"系统界面调节工具可让您以更多方式调整及定制 Android 界面。在日后推出的版本中,这些实验性功能可能会变更、失效或消失。操作时请务必谨慎。"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 995129e..4ec1b58 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"衛星,連線質素唔好"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛星,連線質素好"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛星,可以連線"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"工作設定檔"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"這只是測試版本,並不包含完整功能"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"使用者介面調諧器讓你以更多方法修改和自訂 Android 使用者介面。但請小心,這些實驗功能可能會在日後發佈時更改、分拆或消失。"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index d18f828..52a1917 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"衛星,連線品質不佳"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛星,連線品質良好"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛星,可連線"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"工作資料夾"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"有趣與否,見仁見智"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"系統使用者介面調整精靈可讓你透過其他方式,調整及自訂 Android 使用者介面。這些實驗性功能隨著版本更新可能會變更、損壞或消失,執行時請務必謹慎。"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index a5caa3d..c96be0e 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -656,6 +656,10 @@
     <string name="accessibility_status_bar_satellite_poor_connection" msgid="5231478574952724160">"Isathelayithi, uxhumano olungalungile"</string>
     <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Isethelayithi, uxhumano oluhle"</string>
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Isethelayithi, uxhumano luyatholakala"</string>
+    <!-- no translation found for satellite_connected_carrier_text (7942466244369263272) -->
+    <skip />
+    <!-- no translation found for satellite_not_connected_carrier_text (3471375076594005077) -->
+    <skip />
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"Iphrofayela yomsebenzi"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Kuyajabulisa kwabanye kodwa hhayi bonke"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Isishuni se-UI sesistimu sikunika izindlela ezingeziwe zokuhlobisa nokwenza ngezifiso isixhumanisi sokubona se-Android. Lezi zici zesilingo zingashintsha, zephuke, noma zinyamalale ekukhishweni kwangakusasa. Qhubeka ngokuqaphela."</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1b2362d..1a85f8d4 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1094,9 +1094,9 @@
     <dimen name="remote_input_history_extra_height">60dp</dimen>
 
     <!-- Biometric Dialog values -->
-    <dimen name="biometric_dialog_face_icon_size">54dp</dimen>
-    <dimen name="biometric_dialog_fingerprint_icon_width">80dp</dimen>
-    <dimen name="biometric_dialog_fingerprint_icon_height">80dp</dimen>
+    <dimen name="biometric_dialog_face_icon_size">68dp</dimen>
+    <dimen name="biometric_dialog_fingerprint_icon_width">100dp</dimen>
+    <dimen name="biometric_dialog_fingerprint_icon_height">100dp</dimen>
     <dimen name="biometric_dialog_button_negative_max_width">160dp</dimen>
     <dimen name="biometric_dialog_button_positive_max_width">136dp</dimen>
     <dimen name="biometric_dialog_corner_size">28dp</dimen>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 519622e..167ab90 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -30,6 +30,8 @@
 import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_PERMANENT;
 import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_TIMED;
 import static android.hardware.biometrics.BiometricConstants.LockoutMode;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
 import static android.hardware.biometrics.BiometricSourceType.FACE;
 import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
 import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
@@ -1238,9 +1240,9 @@
         boolean cameraPrivacyEnabled = mSensorPrivacyManager.isSensorPrivacyEnabled(
                 SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE, SensorPrivacyManager.Sensors.CAMERA);
 
-        final boolean isHwUnavailable = msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE;
+        final boolean isHwUnavailable = msgId == FACE_ERROR_HW_UNAVAILABLE;
 
-        if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
+        if (msgId == FACE_ERROR_LOCKOUT_PERMANENT) {
             if (getFaceAuthInteractor() != null && getFaceAuthInteractor().isFaceAuthStrong()) {
                 updateFingerprintListeningState(BIOMETRIC_ACTION_STOP);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt b/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
index b8ff0c0..99be762 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
@@ -112,6 +112,7 @@
         const val COLOR_INVERSION_TILE_SPEC = "inversion"
         const val FONT_SCALING_TILE_SPEC = "font_scaling"
         const val REDUCE_BRIGHTNESS_TILE_SPEC = "reduce_brightness"
+        const val ONE_HANDED_TILE_SPEC = "onehanded"
 
         @Provides
         @IntoMap
@@ -241,5 +242,19 @@
                     mapper,
                 )
             else StubQSTileViewModel
+
+        @Provides
+        @IntoMap
+        @StringKey(ONE_HANDED_TILE_SPEC)
+        fun provideOneHandedTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+            QSTileConfig(
+                tileSpec = TileSpec.create(ONE_HANDED_TILE_SPEC),
+                uiConfig =
+                    QSTileUIConfig.Resource(
+                        iconRes = com.android.internal.R.drawable.ic_qs_one_handed_mode,
+                        labelRes = R.string.quick_settings_onehanded_label,
+                    ),
+                instanceId = uiEventLogger.getNewInstanceId(),
+            )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java b/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java
index e7e12ba..227e4db 100644
--- a/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java
@@ -19,6 +19,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 
 import static com.android.systemui.shared.Flags.bouncerAreaExclusion;
+import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
 
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -37,7 +38,9 @@
 import androidx.lifecycle.LifecycleObserver;
 import androidx.lifecycle.LifecycleOwner;
 
+import com.android.systemui.Flags;
 import com.android.systemui.ambient.touch.dagger.InputSessionComponent;
+import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.DisplayId;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -69,6 +72,9 @@
     public String TAG = "DreamOverlayTouchMonitor";
     private final Executor mMainExecutor;
     private final Executor mBackgroundExecutor;
+
+    private final ConfigurationInteractor mConfigurationInteractor;
+
     private final Lifecycle mLifecycle;
     private Rect mExclusionRect = null;
 
@@ -82,6 +88,8 @@
                 }
             };
 
+    private Consumer<Rect> mMaxBoundsConsumer = rect -> mMaxBounds = rect;
+
 
     /**
      * Adds a new {@link TouchSessionImpl} to participate in receiving future touches and gestures.
@@ -262,6 +270,7 @@
      */
     private void startMonitoring() {
         stopMonitoring(true);
+
         if (bouncerAreaExclusion()) {
             mBackgroundExecutor.execute(() -> {
                 try {
@@ -340,8 +349,13 @@
                             if (!handler.isEnabled()) {
                                 continue;
                             }
-                            final Rect maxBounds = mDisplayHelper.getMaxBounds(ev.getDisplayId(),
-                                    TYPE_APPLICATION_OVERLAY);
+
+                            final Rect maxBounds =
+                                    Flags.ambientTouchMonitorListenToDisplayChanges()
+                                            ? mMaxBounds
+                                            : mDisplayHelper.getMaxBounds(ev.getDisplayId(),
+                                                    TYPE_APPLICATION_OVERLAY);
+
                             final Region initiationRegion = Region.obtain();
                             Rect exclusionRect = null;
                             if (bouncerAreaExclusion()) {
@@ -478,6 +492,8 @@
     private final int mDisplayId;
     private final IWindowManager mWindowManagerService;
 
+    private Rect mMaxBounds;
+
 
     /**
      * Designated constructor for {@link TouchMonitor}
@@ -500,6 +516,7 @@
             Lifecycle lifecycle,
             InputSessionComponent.Factory inputSessionFactory,
             DisplayHelper displayHelper,
+            ConfigurationInteractor configurationInteractor,
             Set<TouchHandler> handlers,
             IWindowManager windowManagerService,
             @DisplayId int displayId) {
@@ -511,6 +528,7 @@
         mLifecycle = lifecycle;
         mDisplayHelper = displayHelper;
         mWindowManagerService = windowManagerService;
+        mConfigurationInteractor = configurationInteractor;
     }
 
     /**
@@ -518,6 +536,9 @@
      */
     public void init() {
         mLifecycle.addObserver(mLifecycleObserver);
+        if (Flags.ambientTouchMonitorListenToDisplayChanges()) {
+            collectFlow(mLifecycle, mConfigurationInteractor.getMaxBounds(), mMaxBoundsConsumer);
+        }
     }
 
     private void isolate(Set<TouchSessionImpl> sessions) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index ea5c5da..1c17beb 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -230,9 +230,13 @@
         @Override
         public void onUseDeviceCredential() {
             mConfig.mCallback.onDeviceCredentialPressed(getRequestId());
-            mHandler.postDelayed(() -> {
+            if (constraintBp()) {
                 addCredentialView(false /* animatePanel */, true /* animateContents */);
-            }, mConfig.mSkipAnimation ? 0 : ANIMATE_CREDENTIAL_START_DELAY_MS);
+            } else {
+                mHandler.postDelayed(() -> {
+                    addCredentialView(false /* animatePanel */, true /* animateContents */);
+                }, mConfig.mSkipAnimation ? 0 : ANIMATE_CREDENTIAL_START_DELAY_MS);
+            }
 
             // TODO(b/313469218): Remove Config
             mConfig.mPromptInfo.setAuthenticators(Authenticators.DEVICE_CREDENTIAL);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index 072fe47..a211147 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -87,7 +87,9 @@
          *
          * TODO(b/288175072): May be able to remove this once constraint layout is implemented
          */
-        view.visibility = View.INVISIBLE
+        if (!constraintBp()) {
+            view.visibility = View.INVISIBLE
+        }
         val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!!
 
         val textColorError =
@@ -102,6 +104,12 @@
         val descriptionView = view.requireViewById<TextView>(R.id.description)
         val customizedViewContainer =
             view.requireViewById<LinearLayout>(R.id.customized_view_container)
+        val udfpsGuidanceView =
+            if (constraintBp()) {
+                view.requireViewById<View>(R.id.panel)
+            } else {
+                backgroundView
+            }
 
         // set selected to enable marquee unless a screen reader is enabled
         logoView.isSelected =
@@ -226,8 +234,8 @@
             }
 
             lifecycleScope.launch {
-                viewModel.showBpWithoutIconForCredential.collect {
-                    if (!it) {
+                viewModel.showBpWithoutIconForCredential.collect { showWithoutIcon ->
+                    if (!showWithoutIcon) {
                         PromptIconViewBinder.bind(
                             iconView,
                             iconOverlayView,
@@ -428,7 +436,7 @@
                 }
 
                 // Talkback directional guidance
-                backgroundView.setOnHoverListener { _, event ->
+                udfpsGuidanceView.setOnHoverListener { _, event ->
                     launch {
                         viewModel.onAnnounceAccessibilityHint(
                             event,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
index f380746..d1ad783 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
@@ -20,6 +20,7 @@
 import android.animation.AnimatorSet
 import android.animation.ValueAnimator
 import android.graphics.Outline
+import android.graphics.Rect
 import android.transition.AutoTransition
 import android.transition.TransitionManager
 import android.util.TypedValue
@@ -36,7 +37,6 @@
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.constraintlayout.widget.Guideline
 import androidx.core.animation.addListener
-import androidx.core.view.doOnAttach
 import androidx.core.view.doOnLayout
 import androidx.core.view.isGone
 import androidx.lifecycle.lifecycleScope
@@ -106,6 +106,52 @@
                     )
                     .toInt()
 
+            var currentSize: PromptSize? = null
+            var currentPosition: PromptPosition = PromptPosition.Bottom
+            panelView.outlineProvider =
+                object : ViewOutlineProvider() {
+                    override fun getOutline(view: View, outline: Outline) {
+                        when (currentPosition) {
+                            PromptPosition.Right -> {
+                                outline.setRoundRect(
+                                    0,
+                                    0,
+                                    view.width + cornerRadiusPx,
+                                    view.height,
+                                    cornerRadiusPx.toFloat()
+                                )
+                            }
+                            PromptPosition.Left -> {
+                                outline.setRoundRect(
+                                    -cornerRadiusPx,
+                                    0,
+                                    view.width,
+                                    view.height,
+                                    cornerRadiusPx.toFloat()
+                                )
+                            }
+                            PromptPosition.Top -> {
+                                outline.setRoundRect(
+                                    0,
+                                    -cornerRadiusPx,
+                                    view.width,
+                                    view.height,
+                                    cornerRadiusPx.toFloat()
+                                )
+                            }
+                            PromptPosition.Bottom -> {
+                                outline.setRoundRect(
+                                    0,
+                                    0,
+                                    view.width,
+                                    view.height + cornerRadiusPx,
+                                    cornerRadiusPx.toFloat()
+                                )
+                            }
+                        }
+                    }
+                }
+
             // ConstraintSets for animating between prompt sizes
             val mediumConstraintSet = ConstraintSet()
             mediumConstraintSet.clone(view as ConstraintLayout)
@@ -115,7 +161,9 @@
 
             val largeConstraintSet = ConstraintSet()
             largeConstraintSet.clone(mediumConstraintSet)
-            largeConstraintSet.constrainMaxWidth(R.id.panel, view.width)
+            largeConstraintSet.constrainMaxWidth(R.id.panel, 0)
+            largeConstraintSet.setGuidelineBegin(R.id.leftGuideline, 0)
+            largeConstraintSet.setGuidelineEnd(R.id.rightGuideline, 0)
 
             // TODO: Investigate better way to handle 180 rotations
             val flipConstraintSet = ConstraintSet()
@@ -138,65 +186,134 @@
                     }
                 }
 
-                fun roundCorners(size: PromptSize, position: PromptPosition) {
-                    var left = 0
-                    var top = 0
-                    var right = 0
-                    var bottom = 0
-                    when (size) {
-                        PromptSize.SMALL,
-                        PromptSize.MEDIUM ->
-                            when (position) {
-                                PromptPosition.Right -> {
-                                    left = 0
-                                    top = 0
-                                    right = view.width + cornerRadiusPx
-                                    bottom = view.height
+                view.repeatWhenAttached {
+                    lifecycleScope.launch {
+                        viewModel.iconPosition.collect { position ->
+                            if (position != Rect()) {
+                                val iconParams =
+                                    iconHolderView.layoutParams as ConstraintLayout.LayoutParams
+
+                                if (position.left != 0) {
+                                    iconParams.endToEnd = ConstraintSet.UNSET
+                                    iconParams.leftMargin = position.left
+                                    mediumConstraintSet.clear(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.END
+                                    )
+                                    mediumConstraintSet.connect(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.START,
+                                        ConstraintSet.PARENT_ID,
+                                        ConstraintSet.START
+                                    )
+                                    mediumConstraintSet.setMargin(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.START,
+                                        position.left
+                                    )
+                                    smallConstraintSet.clear(R.id.biometric_icon, ConstraintSet.END)
+                                    smallConstraintSet.connect(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.START,
+                                        ConstraintSet.PARENT_ID,
+                                        ConstraintSet.START
+                                    )
+                                    smallConstraintSet.setMargin(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.START,
+                                        position.left
+                                    )
                                 }
-                                PromptPosition.Left -> {
-                                    left = -cornerRadiusPx
-                                    top = 0
-                                    right = view.width
-                                    bottom = view.height
+                                if (position.top != 0) {
+                                    iconParams.bottomToBottom = ConstraintSet.UNSET
+                                    iconParams.topMargin = position.top
+                                    mediumConstraintSet.clear(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.BOTTOM
+                                    )
+                                    mediumConstraintSet.setMargin(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.TOP,
+                                        position.top
+                                    )
+                                    smallConstraintSet.clear(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.BOTTOM
+                                    )
+                                    smallConstraintSet.setMargin(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.TOP,
+                                        position.top
+                                    )
                                 }
-                                PromptPosition.Top -> {
-                                    left = 0
-                                    top = -cornerRadiusPx
-                                    right = panelView.width
-                                    bottom = view.height
+                                if (position.right != 0) {
+                                    iconParams.startToStart = ConstraintSet.UNSET
+                                    iconParams.rightMargin = position.right
+                                    mediumConstraintSet.clear(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.START
+                                    )
+                                    mediumConstraintSet.connect(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.END,
+                                        ConstraintSet.PARENT_ID,
+                                        ConstraintSet.END
+                                    )
+                                    mediumConstraintSet.setMargin(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.END,
+                                        position.right
+                                    )
+                                    smallConstraintSet.clear(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.START
+                                    )
+                                    smallConstraintSet.connect(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.END,
+                                        ConstraintSet.PARENT_ID,
+                                        ConstraintSet.END
+                                    )
+                                    smallConstraintSet.setMargin(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.END,
+                                        position.right
+                                    )
                                 }
-                                PromptPosition.Bottom -> {
-                                    left = 0
-                                    top = 0
-                                    right = panelView.width
-                                    bottom = view.height + cornerRadiusPx
+                                if (position.bottom != 0) {
+                                    iconParams.topToTop = ConstraintSet.UNSET
+                                    iconParams.bottomMargin = position.bottom
+                                    mediumConstraintSet.clear(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.TOP
+                                    )
+                                    mediumConstraintSet.setMargin(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.BOTTOM,
+                                        position.bottom
+                                    )
+                                    smallConstraintSet.clear(R.id.biometric_icon, ConstraintSet.TOP)
+                                    smallConstraintSet.setMargin(
+                                        R.id.biometric_icon,
+                                        ConstraintSet.BOTTOM,
+                                        position.bottom
+                                    )
                                 }
+                                iconHolderView.layoutParams = iconParams
                             }
-                        PromptSize.LARGE -> {
-                            left = 0
-                            top = 0
-                            right = view.width
-                            bottom = view.height
                         }
                     }
-
-                    // Round the panel outline
-                    panelView.outlineProvider =
-                        object : ViewOutlineProvider() {
-                            override fun getOutline(view: View, outline: Outline) {
-                                outline.setRoundRect(
-                                    left,
-                                    top,
-                                    right,
-                                    bottom,
-                                    cornerRadiusPx.toFloat()
-                                )
-                            }
+                    lifecycleScope.launch {
+                        viewModel.iconSize.collect { iconSize ->
+                            iconHolderView.layoutParams.width = iconSize.first
+                            iconHolderView.layoutParams.height = iconSize.second
+                            mediumConstraintSet.constrainWidth(R.id.biometric_icon, iconSize.first)
+                            mediumConstraintSet.constrainHeight(
+                                R.id.biometric_icon,
+                                iconSize.second
+                            )
                         }
-                }
-
-                view.repeatWhenAttached {
-                    var currentSize: PromptSize? = null
+                    }
 
                     lifecycleScope.launch {
                         viewModel.guidelineBounds.collect { bounds ->
@@ -249,87 +366,77 @@
                     lifecycleScope.launch {
                         combine(viewModel.position, viewModel.size, ::Pair).collect {
                             (position, size) ->
-                            view.doOnAttach {
-                                setVisibilities(size)
+                            setVisibilities(size)
 
-                                if (position.isLeft) {
-                                    if (size.isSmall) {
-                                        flipConstraintSet.clone(smallConstraintSet)
-                                    } else {
-                                        flipConstraintSet.clone(mediumConstraintSet)
-                                    }
-
-                                    // Move all content to other panel
-                                    flipConstraintSet.connect(
-                                        R.id.scrollView,
-                                        ConstraintSet.START,
-                                        R.id.midGuideline,
-                                        ConstraintSet.START
-                                    )
-                                    flipConstraintSet.connect(
-                                        R.id.scrollView,
-                                        ConstraintSet.END,
-                                        R.id.rightGuideline,
-                                        ConstraintSet.END
-                                    )
+                            if (position.isLeft) {
+                                if (size.isSmall) {
+                                    flipConstraintSet.clone(smallConstraintSet)
+                                } else {
+                                    flipConstraintSet.clone(mediumConstraintSet)
                                 }
 
-                                roundCorners(size, position)
-
-                                when {
-                                    size.isSmall -> {
-                                        if (position.isLeft) {
-                                            flipConstraintSet.applyTo(view)
-                                        } else {
-                                            smallConstraintSet.applyTo(view)
-                                        }
-                                    }
-                                    size.isMedium && currentSize.isSmall -> {
-                                        val autoTransition = AutoTransition()
-                                        autoTransition.setDuration(
-                                            ANIMATE_SMALL_TO_MEDIUM_DURATION_MS.toLong()
-                                        )
-
-                                        TransitionManager.beginDelayedTransition(
-                                            view,
-                                            autoTransition
-                                        )
-
-                                        if (position.isLeft) {
-                                            flipConstraintSet.applyTo(view)
-                                        } else {
-                                            mediumConstraintSet.applyTo(view)
-                                        }
-                                    }
-                                    size.isMedium -> {
-                                        if (position.isLeft) {
-                                            flipConstraintSet.applyTo(view)
-                                        } else {
-                                            mediumConstraintSet.applyTo(view)
-                                        }
-                                    }
-                                    size.isLarge -> {
-                                        val autoTransition = AutoTransition()
-                                        autoTransition.setDuration(
-                                            ANIMATE_MEDIUM_TO_LARGE_DURATION_MS.toLong()
-                                        )
-
-                                        TransitionManager.beginDelayedTransition(
-                                            view,
-                                            autoTransition
-                                        )
-                                        largeConstraintSet.applyTo(view)
-                                    }
-                                }
-
-                                currentSize = size
-                                view.visibility = View.VISIBLE
-                                viewModel.setIsIconViewLoaded(false)
-                                notifyAccessibilityChanged()
-
-                                view.invalidate()
-                                view.requestLayout()
+                                // Move all content to other panel
+                                flipConstraintSet.connect(
+                                    R.id.scrollView,
+                                    ConstraintSet.START,
+                                    R.id.midGuideline,
+                                    ConstraintSet.START
+                                )
+                                flipConstraintSet.connect(
+                                    R.id.scrollView,
+                                    ConstraintSet.END,
+                                    R.id.rightGuideline,
+                                    ConstraintSet.END
+                                )
                             }
+
+                            when {
+                                size.isSmall -> {
+                                    if (position.isLeft) {
+                                        flipConstraintSet.applyTo(view)
+                                    } else {
+                                        smallConstraintSet.applyTo(view)
+                                    }
+                                }
+                                size.isMedium && currentSize.isSmall -> {
+                                    val autoTransition = AutoTransition()
+                                    autoTransition.setDuration(
+                                        ANIMATE_SMALL_TO_MEDIUM_DURATION_MS.toLong()
+                                    )
+
+                                    TransitionManager.beginDelayedTransition(view, autoTransition)
+
+                                    if (position.isLeft) {
+                                        flipConstraintSet.applyTo(view)
+                                    } else {
+                                        mediumConstraintSet.applyTo(view)
+                                    }
+                                }
+                                size.isMedium -> {
+                                    if (position.isLeft) {
+                                        flipConstraintSet.applyTo(view)
+                                    } else {
+                                        mediumConstraintSet.applyTo(view)
+                                    }
+                                }
+                                size.isLarge && currentSize.isMedium -> {
+                                    val autoTransition = AutoTransition()
+                                    autoTransition.setDuration(
+                                        ANIMATE_MEDIUM_TO_LARGE_DURATION_MS.toLong()
+                                    )
+
+                                    TransitionManager.beginDelayedTransition(view, autoTransition)
+                                    largeConstraintSet.applyTo(view)
+                                }
+                            }
+
+                            currentSize = size
+                            currentPosition = position
+                            notifyAccessibilityChanged()
+
+                            panelView.invalidateOutline()
+                            view.invalidate()
+                            view.requestLayout()
                         }
                     }
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
index d9d3715..9e836c3 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
@@ -17,12 +17,9 @@
 
 package com.android.systemui.biometrics.ui.binder
 
-import android.graphics.Rect
 import android.graphics.drawable.Animatable2
 import android.graphics.drawable.AnimatedVectorDrawable
 import android.graphics.drawable.Drawable
-import androidx.constraintlayout.widget.ConstraintLayout
-import androidx.constraintlayout.widget.ConstraintSet
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.airbnb.lottie.LottieAnimationView
@@ -77,83 +74,60 @@
                         }
                     }
 
-                launch {
-                    var lottieOnCompositionLoadedListener: LottieOnCompositionLoadedListener? = null
+                if (!constraintBp()) {
+                    launch {
+                        var lottieOnCompositionLoadedListener: LottieOnCompositionLoadedListener? =
+                            null
 
-                    combine(viewModel.activeAuthType, viewModel.iconSize, ::Pair).collect {
-                        (activeAuthType, iconSize) ->
-                        // Every time after bp shows, [isIconViewLoaded] is set to false in
-                        // [BiometricViewSizeBinder]. Then when biometric prompt view is redrew
-                        // (when size or activeAuthType changes), we need to update
-                        // [isIconViewLoaded] here to keep it correct.
-                        when (activeAuthType) {
-                            AuthType.Fingerprint,
-                            AuthType.Coex -> {
-                                /**
-                                 * View is only set visible in BiometricViewSizeBinder once
-                                 * PromptSize is determined that accounts for iconView size, to
-                                 * prevent prompt resizing being visible to the user.
-                                 *
-                                 * TODO(b/288175072): May be able to remove this once constraint
-                                 *   layout is implemented
-                                 */
-                                if (lottieOnCompositionLoadedListener != null) {
-                                    iconView.removeLottieOnCompositionLoadedListener(
+                        combine(viewModel.activeAuthType, viewModel.iconSize, ::Pair).collect {
+                            (activeAuthType, iconSize) ->
+                            // Every time after bp shows, [isIconViewLoaded] is set to false in
+                            // [BiometricViewSizeBinder]. Then when biometric prompt view is redrew
+                            // (when size or activeAuthType changes), we need to update
+                            // [isIconViewLoaded] here to keep it correct.
+                            when (activeAuthType) {
+                                AuthType.Fingerprint,
+                                AuthType.Coex -> {
+                                    /**
+                                     * View is only set visible in BiometricViewSizeBinder once
+                                     * PromptSize is determined that accounts for iconView size, to
+                                     * prevent prompt resizing being visible to the user.
+                                     *
+                                     * TODO(b/288175072): May be able to remove this once constraint
+                                     *   layout is implemented
+                                     */
+                                    if (lottieOnCompositionLoadedListener != null) {
+                                        iconView.removeLottieOnCompositionLoadedListener(
+                                            lottieOnCompositionLoadedListener!!
+                                        )
+                                    }
+                                    lottieOnCompositionLoadedListener =
+                                        LottieOnCompositionLoadedListener {
+                                            promptViewModel.setIsIconViewLoaded(true)
+                                        }
+                                    iconView.addLottieOnCompositionLoadedListener(
                                         lottieOnCompositionLoadedListener!!
                                     )
                                 }
-                                lottieOnCompositionLoadedListener =
-                                    LottieOnCompositionLoadedListener {
-                                        promptViewModel.setIsIconViewLoaded(true)
-                                    }
-                                iconView.addLottieOnCompositionLoadedListener(
-                                    lottieOnCompositionLoadedListener!!
-                                )
+                                AuthType.Face -> {
+                                    /**
+                                     * Set to true by default since face icon is a drawable, which
+                                     * doesn't have a LottieOnCompositionLoadedListener equivalent.
+                                     *
+                                     * TODO(b/318569643): To be updated once face assets are updated
+                                     *   from drawables
+                                     */
+                                    promptViewModel.setIsIconViewLoaded(true)
+                                }
                             }
-                            AuthType.Face -> {
-                                /**
-                                 * Set to true by default since face icon is a drawable, which
-                                 * doesn't have a LottieOnCompositionLoadedListener equivalent.
-                                 *
-                                 * TODO(b/318569643): To be updated once face assets are updated
-                                 *   from drawables
-                                 */
-                                promptViewModel.setIsIconViewLoaded(true)
-                            }
-                        }
 
-                        if (iconViewLayoutParamSizeOverride == null) {
-                            iconView.layoutParams.width = iconSize.first
-                            iconView.layoutParams.height = iconSize.second
+                            if (iconViewLayoutParamSizeOverride == null) {
+                                iconView.layoutParams.width = iconSize.first
+                                iconView.layoutParams.height = iconSize.second
 
-                            iconOverlayView.layoutParams.width = iconSize.first
-                            iconOverlayView.layoutParams.height = iconSize.second
-                        }
-                    }
-                }
-
-                launch {
-                    viewModel.iconPosition.collect { position ->
-                        if (constraintBp() && position != Rect()) {
-                            val iconParams = iconView.layoutParams as ConstraintLayout.LayoutParams
-
-                            if (position.left != 0) {
-                                iconParams.endToEnd = ConstraintSet.UNSET
-                                iconParams.leftMargin = position.left
+                                iconOverlayView.layoutParams.width = iconSize.first
+                                iconOverlayView.layoutParams.height = iconSize.second
                             }
-                            if (position.top != 0) {
-                                iconParams.bottomToBottom = ConstraintSet.UNSET
-                                iconParams.topMargin = position.top
-                            }
-                            if (position.right != 0) {
-                                iconParams.startToStart = ConstraintSet.UNSET
-                                iconParams.rightMargin = position.right
-                            }
-                            if (position.bottom != 0) {
-                                iconParams.topToTop = ConstraintSet.UNSET
-                                iconParams.bottomMargin = position.bottom
-                            }
-                            iconView.layoutParams = iconParams
                         }
                     }
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
index 8dbed5f..bde3e99 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
@@ -66,10 +66,9 @@
      */
     val activeAuthType: Flow<AuthType> =
         combine(
-            promptViewModel.size,
             promptViewModel.modalities.distinctUntilChanged(),
             promptViewModel.faceMode.distinctUntilChanged()
-        ) { _, modalities, faceMode ->
+        ) { modalities, faceMode ->
             if (modalities.hasFaceAndFingerprint && !faceMode) {
                 AuthType.Coex
             } else if (modalities.hasFaceOnly || faceMode) {
@@ -103,68 +102,6 @@
             }
             .distinctUntilChanged()
 
-    val iconPosition: Flow<Rect> =
-        combine(
-                udfpsSensorBounds,
-                promptViewModel.size,
-                promptViewModel.position,
-                promptViewModel.modalities
-            ) { sensorBounds, size, position, modalities ->
-                when (position) {
-                    PromptPosition.Bottom ->
-                        if (size.isSmall) {
-                            Rect(0, 0, 0, promptViewModel.portraitSmallBottomPadding)
-                        } else if (size.isMedium && modalities.hasUdfps) {
-                            Rect(0, 0, 0, sensorBounds.bottom)
-                        } else if (size.isMedium) {
-                            Rect(0, 0, 0, promptViewModel.portraitMediumBottomPadding)
-                        } else {
-                            // Large screen
-                            Rect(0, 0, 0, promptViewModel.portraitLargeScreenBottomPadding)
-                        }
-                    PromptPosition.Right ->
-                        if (size.isSmall || modalities.hasFaceOnly) {
-                            Rect(
-                                0,
-                                0,
-                                promptViewModel.landscapeSmallHorizontalPadding,
-                                promptViewModel.landscapeSmallBottomPadding
-                            )
-                        } else if (size.isMedium && modalities.hasUdfps) {
-                            Rect(0, 0, sensorBounds.right, sensorBounds.bottom)
-                        } else {
-                            // SFPS
-                            Rect(
-                                0,
-                                0,
-                                promptViewModel.landscapeMediumHorizontalPadding,
-                                promptViewModel.landscapeMediumBottomPadding
-                            )
-                        }
-                    PromptPosition.Left ->
-                        if (size.isSmall || modalities.hasFaceOnly) {
-                            Rect(
-                                promptViewModel.landscapeSmallHorizontalPadding,
-                                0,
-                                0,
-                                promptViewModel.landscapeSmallBottomPadding
-                            )
-                        } else if (size.isMedium && modalities.hasUdfps) {
-                            Rect(sensorBounds.left, 0, 0, sensorBounds.bottom)
-                        } else {
-                            // SFPS
-                            Rect(
-                                promptViewModel.landscapeMediumHorizontalPadding,
-                                0,
-                                0,
-                                promptViewModel.landscapeMediumBottomPadding
-                            )
-                        }
-                    PromptPosition.Top -> Rect()
-                }
-            }
-            .distinctUntilChanged()
-
     /** Whether an error message is currently being shown. */
     val showingError = promptViewModel.showingError
 
@@ -215,8 +152,8 @@
         combine(
             promptViewModel.position,
             activeAuthType,
-            promptViewModel.fingerprintSensorWidth,
-            promptViewModel.fingerprintSensorHeight,
+            promptViewModel.legacyFingerprintSensorWidth,
+            promptViewModel.legacyFingerprintSensorHeight,
         ) { _, activeAuthType, fingerprintSensorWidth, fingerprintSensorHeight ->
             if (activeAuthType == AuthType.Face) {
                 Pair(promptViewModel.faceIconWidth, promptViewModel.faceIconHeight)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
index 4e9acbd..2104f3e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -27,6 +27,7 @@
 import android.hardware.biometrics.Flags.customBiometricPrompt
 import android.hardware.biometrics.PromptContentView
 import android.util.Log
+import android.util.RotationUtils
 import android.view.HapticFeedbackConstants
 import android.view.MotionEvent
 import com.android.systemui.Flags.bpTalkback
@@ -120,7 +121,28 @@
             R.dimen.biometric_prompt_landscape_medium_horizontal_padding
         )
 
-    val fingerprintSensorWidth: Flow<Int> =
+    private val udfpsSensorBounds: Flow<Rect> =
+        combine(
+                udfpsOverlayInteractor.udfpsOverlayParams,
+                displayStateInteractor.currentRotation
+            ) { params, rotation ->
+                val rotatedBounds = Rect(params.sensorBounds)
+                RotationUtils.rotateBounds(
+                    rotatedBounds,
+                    params.naturalDisplayWidth,
+                    params.naturalDisplayHeight,
+                    rotation.ordinal
+                )
+                Rect(
+                    rotatedBounds.left,
+                    rotatedBounds.top,
+                    params.logicalDisplayWidth - rotatedBounds.right,
+                    params.logicalDisplayHeight - rotatedBounds.bottom
+                )
+            }
+            .distinctUntilChanged()
+
+    val legacyFingerprintSensorWidth: Flow<Int> =
         combine(modalities, udfpsOverlayInteractor.udfpsOverlayParams) { modalities, overlayParams
             ->
             if (modalities.hasUdfps) {
@@ -130,7 +152,7 @@
             }
         }
 
-    val fingerprintSensorHeight: Flow<Int> =
+    val legacyFingerprintSensorHeight: Flow<Int> =
         combine(modalities, udfpsOverlayInteractor.udfpsOverlayParams) { modalities, overlayParams
             ->
             if (modalities.hasUdfps) {
@@ -140,6 +162,12 @@
             }
         }
 
+    val fingerprintSensorWidth: Int =
+        udfpsOverlayInteractor.udfpsOverlayParams.value.sensorBounds.width()
+
+    val fingerprintSensorHeight: Int =
+        udfpsOverlayInteractor.udfpsOverlayParams.value.sensorBounds.height()
+
     private val _accessibilityHint = MutableSharedFlow<String>()
 
     /** Hint for talkback directional guidance */
@@ -276,40 +304,54 @@
             R.dimen.biometric_prompt_medium_mid_guideline_padding
         )
 
-    /**
-     * Rect for positioning prompt guidelines (left, top, right, mid)
-     *
-     * Negative values are used to signify that guideline measuring should be flipped, measuring
-     * from opposite side of the screen
-     */
-    val guidelineBounds: Flow<Rect> =
-        combine(size, position, modalities) { size, position, modalities ->
-                if (position.isBottom) {
-                    Rect(0, 0, 0, 0)
-                } else if (position.isRight) {
-                    if (size.isSmall) {
-                        Rect(-smallHorizontalGuidelinePadding, 0, 0, 0)
-                    } else if (modalities.hasUdfps) {
-                        Rect(udfpsHorizontalGuidelinePadding, 0, 0, udfpsMidGuidelinePadding)
-                    } else if (modalities.isEmpty) {
-                        // TODO: Temporary fix until no biometric landscape layout is added
-                        Rect(-mediumHorizontalGuidelinePadding, 0, 0, 6)
-                    } else {
-                        Rect(-mediumHorizontalGuidelinePadding, 0, 0, mediumMidGuidelinePadding)
-                    }
-                } else if (position.isLeft) {
-                    if (size.isSmall) {
-                        Rect(0, 0, -smallHorizontalGuidelinePadding, 0)
-                    } else if (modalities.hasUdfps) {
-                        Rect(0, 0, udfpsHorizontalGuidelinePadding, -udfpsMidGuidelinePadding)
-                    } else if (modalities.isEmpty) {
-                        // TODO: Temporary fix until no biometric landscape layout is added
-                        Rect(0, 0, -mediumHorizontalGuidelinePadding, -6)
-                    } else {
-                        Rect(0, 0, -mediumHorizontalGuidelinePadding, -mediumMidGuidelinePadding)
-                    }
-                } else {
-                    Rect()
+    /** Rect for positioning biometric icon */
+    val iconPosition: Flow<Rect> =
+        combine(udfpsSensorBounds, size, position, modalities) {
+                sensorBounds,
+                size,
+                position,
+                modalities ->
+                when (position) {
+                    PromptPosition.Bottom ->
+                        if (size.isSmall) {
+                            Rect(0, 0, 0, portraitSmallBottomPadding)
+                        } else if (size.isMedium && modalities.hasUdfps) {
+                            Rect(0, 0, 0, sensorBounds.bottom)
+                        } else if (size.isMedium) {
+                            Rect(0, 0, 0, portraitMediumBottomPadding)
+                        } else {
+                            // Large screen
+                            Rect(0, 0, 0, portraitLargeScreenBottomPadding)
+                        }
+                    PromptPosition.Right ->
+                        if (size.isSmall || modalities.hasFaceOnly) {
+                            Rect(0, 0, landscapeSmallHorizontalPadding, landscapeSmallBottomPadding)
+                        } else if (size.isMedium && modalities.hasUdfps) {
+                            Rect(0, 0, sensorBounds.right, sensorBounds.bottom)
+                        } else {
+                            // SFPS
+                            Rect(
+                                0,
+                                0,
+                                landscapeMediumHorizontalPadding,
+                                landscapeMediumBottomPadding
+                            )
+                        }
+                    PromptPosition.Left ->
+                        if (size.isSmall || modalities.hasFaceOnly) {
+                            Rect(landscapeSmallHorizontalPadding, 0, 0, landscapeSmallBottomPadding)
+                        } else if (size.isMedium && modalities.hasUdfps) {
+                            Rect(sensorBounds.left, 0, 0, sensorBounds.bottom)
+                        } else {
+                            // SFPS
+                            Rect(
+                                landscapeMediumHorizontalPadding,
+                                0,
+                                0,
+                                landscapeMediumBottomPadding
+                            )
+                        }
+                    PromptPosition.Top -> Rect()
                 }
             }
             .distinctUntilChanged()
@@ -373,6 +415,62 @@
         _isIconViewLoaded.value = iconViewLoaded
     }
 
+    /** The size of the biometric icon */
+    val iconSize: Flow<Pair<Int, Int>> =
+        combine(iconViewModel.activeAuthType, modalities) { activeAuthType, modalities ->
+            if (activeAuthType == PromptIconViewModel.AuthType.Face) {
+                Pair(faceIconWidth, faceIconHeight)
+            } else {
+                if (modalities.hasUdfps) {
+                    Pair(fingerprintSensorWidth, fingerprintSensorHeight)
+                } else {
+                    Pair(fingerprintIconWidth, fingerprintIconHeight)
+                }
+            }
+        }
+
+    /**
+     * Rect for positioning prompt guidelines (left, top, right, mid)
+     *
+     * Negative values are used to signify that guideline measuring should be flipped, measuring
+     * from opposite side of the screen
+     */
+    val guidelineBounds: Flow<Rect> =
+        combine(iconPosition, size, position, modalities) { _, size, position, modalities ->
+                when (position) {
+                    PromptPosition.Bottom -> Rect(0, 0, 0, 0)
+                    PromptPosition.Right ->
+                        if (size.isSmall) {
+                            Rect(-smallHorizontalGuidelinePadding, 0, 0, 0)
+                        } else if (modalities.hasUdfps) {
+                            Rect(udfpsHorizontalGuidelinePadding, 0, 0, udfpsMidGuidelinePadding)
+                        } else if (modalities.isEmpty) {
+                            // TODO: Temporary fix until no biometric landscape layout is added
+                            Rect(-mediumHorizontalGuidelinePadding, 0, 0, 6)
+                        } else {
+                            Rect(-mediumHorizontalGuidelinePadding, 0, 0, mediumMidGuidelinePadding)
+                        }
+                    PromptPosition.Left ->
+                        if (size.isSmall) {
+                            Rect(0, 0, -smallHorizontalGuidelinePadding, 0)
+                        } else if (modalities.hasUdfps) {
+                            Rect(0, 0, udfpsHorizontalGuidelinePadding, -udfpsMidGuidelinePadding)
+                        } else if (modalities.isEmpty) {
+                            // TODO: Temporary fix until no biometric landscape layout is added
+                            Rect(0, 0, -mediumHorizontalGuidelinePadding, -6)
+                        } else {
+                            Rect(
+                                0,
+                                0,
+                                -mediumHorizontalGuidelinePadding,
+                                -mediumMidGuidelinePadding
+                            )
+                        }
+                    PromptPosition.Top -> Rect()
+                }
+            }
+            .distinctUntilChanged()
+
     /** Padding for prompt UI elements */
     val promptPadding: Flow<Rect> =
         combine(size, displayStateInteractor.currentRotation) { size, rotation ->
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractor.kt b/packages/SystemUI/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractor.kt
index 638af58..e0e1971 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractor.kt
@@ -48,6 +48,12 @@
             }
         }
 
+    /** Returns the unadjusted screen size. */
+    val maxBounds: Flow<Rect> =
+        repository.configurationValues
+            .map { Rect(it.windowConfiguration.maxBounds) }
+            .distinctUntilChanged()
+
     /**
      * Returns screen size adjusted to rotation, so returned screen sizes are stable across all
      * rotations, could be useful if you need to react to screen resize (e.g. fold/unfold on
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
index 4ac43bc..511bdc4 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
@@ -88,14 +88,14 @@
     /** Whether in edit mode for the communal hub. */
     open val isEditMode = false
 
-    /** Whether the popup message triggered by dismissing the CTA tile is showing. */
-    open val isPopupOnDismissCtaShowing: Flow<Boolean> = flowOf(false)
+    /** Whether the type of popup currently showing */
+    open val currentPopup: Flow<PopupType?> = flowOf(null)
 
     /** Whether the communal hub is empty with no widget available. */
     open val isEmptyState: Flow<Boolean> = flowOf(false)
 
-    /** Hide the popup message triggered by dismissing the CTA tile. */
-    open fun onHidePopupAfterDismissCta() {}
+    /** Called as the UI request to dismiss the any displaying popup */
+    open fun onHidePopup() {}
 
     /** Called as the UI requests deleting a widget. */
     open fun onDeleteWidget(id: Int) {}
@@ -127,6 +127,9 @@
     /** Called as the user cancels dragging a widget to reorder. */
     open fun onReorderWidgetCancel() {}
 
+    /** Called as the user request to show the customize widget button. */
+    open fun onShowCustomizeWidgetButton() {}
+
     /** Set the key of the currently selected item */
     fun setSelectedKey(key: String?) {
         _selectedKey.value = key
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index f13b5759..9dacf8c 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -90,9 +90,8 @@
             .distinctUntilChanged()
             .onEach { logger.d("isEmptyState: $it") }
 
-    private val _isPopupOnDismissCtaShowing: MutableStateFlow<Boolean> = MutableStateFlow(false)
-    override val isPopupOnDismissCtaShowing: Flow<Boolean> =
-        _isPopupOnDismissCtaShowing.asStateFlow()
+    private val _currentPopup: MutableStateFlow<PopupType?> = MutableStateFlow(null)
+    override val currentPopup: Flow<PopupType?> = _currentPopup.asStateFlow()
 
     private val _isEnableWidgetDialogShowing: MutableStateFlow<Boolean> = MutableStateFlow(false)
     val isEnableWidgetDialogShowing: Flow<Boolean> = _isEnableWidgetDialogShowing.asStateFlow()
@@ -124,14 +123,16 @@
     override fun onDismissCtaTile() {
         scope.launch {
             communalInteractor.dismissCtaTile()
-            setPopupOnDismissCtaVisibility(true)
-            schedulePopupHiding()
+            setCurrentPopupType(PopupType.CtaTile)
         }
     }
 
-    override fun onHidePopupAfterDismissCta() {
-        cancelDelayedPopupHiding()
-        setPopupOnDismissCtaVisibility(false)
+    override fun onShowCustomizeWidgetButton() {
+        setCurrentPopupType(PopupType.CustomizeWidgetButton)
+    }
+
+    override fun onHidePopup() {
+        setCurrentPopupType(null)
     }
 
     override fun onOpenEnableWidgetDialog() {
@@ -168,25 +169,22 @@
         _isEnableWorkProfileDialogShowing.value = isVisible
     }
 
-    private fun setPopupOnDismissCtaVisibility(isVisible: Boolean) {
-        _isPopupOnDismissCtaShowing.value = isVisible
+    private fun setCurrentPopupType(popupType: PopupType?) {
+        _currentPopup.value = popupType
+        delayedHideCurrentPopupJob?.cancel()
+
+        if (popupType != null) {
+            delayedHideCurrentPopupJob =
+                scope.launch {
+                    delay(POPUP_AUTO_HIDE_TIMEOUT_MS)
+                    setCurrentPopupType(null)
+                }
+        } else {
+            delayedHideCurrentPopupJob = null
+        }
     }
 
-    private var delayedHidePopupJob: Job? = null
-
-    private fun schedulePopupHiding() {
-        cancelDelayedPopupHiding()
-        delayedHidePopupJob =
-            scope.launch {
-                delay(POPUP_AUTO_HIDE_TIMEOUT_MS)
-                onHidePopupAfterDismissCta()
-            }
-    }
-
-    private fun cancelDelayedPopupHiding() {
-        delayedHidePopupJob?.cancel()
-        delayedHidePopupJob = null
-    }
+    private var delayedHideCurrentPopupJob: Job? = null
 
     /** Whether we can transition to a new scene based on a user gesture. */
     fun canChangeScene(): Boolean {
@@ -197,3 +195,8 @@
         const val POPUP_AUTO_HIDE_TIMEOUT_MS = 12000L
     }
 }
+
+sealed class PopupType {
+    object CtaTile : PopupType()
+    object CustomizeWidgetButton : PopupType()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
index 2af49aa..db7ffc1 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
@@ -20,8 +20,6 @@
 import android.content.pm.PackageManager
 import com.android.systemui.controls.ControlsMetricsLogger
 import com.android.systemui.controls.ControlsMetricsLoggerImpl
-import com.android.systemui.controls.settings.ControlsSettingsRepository
-import com.android.systemui.controls.settings.ControlsSettingsRepositoryImpl
 import com.android.systemui.controls.controller.ControlsBindingController
 import com.android.systemui.controls.controller.ControlsBindingControllerImpl
 import com.android.systemui.controls.controller.ControlsController
@@ -40,14 +38,20 @@
 import com.android.systemui.controls.panels.SelectedComponentRepositoryImpl
 import com.android.systemui.controls.settings.ControlsSettingsDialogManager
 import com.android.systemui.controls.settings.ControlsSettingsDialogManagerImpl
+import com.android.systemui.controls.settings.ControlsSettingsRepository
+import com.android.systemui.controls.settings.ControlsSettingsRepositoryImpl
 import com.android.systemui.controls.ui.ControlActionCoordinator
 import com.android.systemui.controls.ui.ControlActionCoordinatorImpl
 import com.android.systemui.controls.ui.ControlsActivity
 import com.android.systemui.controls.ui.ControlsUiController
 import com.android.systemui.controls.ui.ControlsUiControllerImpl
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.qs.tiles.DeviceControlsTile
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
 import dagger.Binds
 import dagger.BindsOptionalOf
 import dagger.Module
@@ -75,6 +79,22 @@
         fun providesControlsFeatureEnabled(pm: PackageManager): Boolean {
             return pm.hasSystemFeature(PackageManager.FEATURE_CONTROLS)
         }
+
+        const val DEVICE_CONTROLS_SPEC = "controls"
+
+        @Provides
+        @IntoMap
+        @StringKey(DEVICE_CONTROLS_SPEC)
+        fun provideDeviceControlsTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+                QSTileConfig(
+                        tileSpec = TileSpec.create(DEVICE_CONTROLS_SPEC),
+                        uiConfig =
+                        QSTileUIConfig.Resource(
+                                iconRes = com.android.systemui.res.R.drawable.controls_icon,
+                                labelRes = com.android.systemui.res.R.string.quick_controls_title
+                        ),
+                        instanceId = uiEventLogger.getNewInstanceId(),
+                )
     }
 
     @Binds
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractor.kt
index 98deda09..ffe392a 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/FaceHelpMessageDeferralInteractor.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.deviceentry.domain.interactor
 
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_START
 import android.hardware.face.FaceManager
 import com.android.systemui.biometrics.FaceHelpMessageDeferralFactory
 import com.android.systemui.dagger.SysUISingleton
@@ -86,7 +87,7 @@
                     }
                 }
                 .collect {
-                    if (it.acquiredInfo == FaceManager.FACE_ACQUIRED_START) {
+                    if (it.acquiredInfo == FACE_ACQUIRED_START) {
                         faceHelpMessageDeferral.reset()
                     }
                     faceHelpMessageDeferral.processFrame(it.acquiredInfo)
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/FaceAuthenticationModels.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/FaceAuthenticationModels.kt
index 5f1667a..3365340 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/FaceAuthenticationModels.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/FaceAuthenticationModels.kt
@@ -16,6 +16,12 @@
 
 package com.android.systemui.deviceentry.shared.model
 
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_CANCELED
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS
 import android.hardware.face.FaceManager
 import android.os.SystemClock.elapsedRealtime
 
@@ -62,24 +68,22 @@
      * Method that checks if [msgId] is a lockout error. A lockout error means that face
      * authentication is locked out.
      */
-    fun isLockoutError() =
-        msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT || msgId == FaceManager.FACE_ERROR_LOCKOUT
+    fun isLockoutError() = msgId == FACE_ERROR_LOCKOUT_PERMANENT || msgId == FACE_ERROR_LOCKOUT
 
     /**
      * Method that checks if [msgId] is a cancellation error. This means that face authentication
      * was cancelled before it completed.
      */
-    fun isCancellationError() = msgId == FaceManager.FACE_ERROR_CANCELED
+    fun isCancellationError() = msgId == FACE_ERROR_CANCELED
 
-    fun isUnableToProcessError() = msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS
+    fun isUnableToProcessError() = msgId == FACE_ERROR_UNABLE_TO_PROCESS
 
     /** Method that checks if [msgId] is a hardware error. */
     fun isHardwareError() =
-        msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE ||
-            msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS
+        msgId == FACE_ERROR_HW_UNAVAILABLE || msgId == FACE_ERROR_UNABLE_TO_PROCESS
 
     /** Method that checks if [msgId] is a timeout error. */
-    fun isTimeoutError() = msgId == FaceManager.FACE_ERROR_TIMEOUT
+    fun isTimeoutError() = msgId == FACE_ERROR_TIMEOUT
 
     companion object {
         /**
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index c618e92..aa7a7da 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.dreams;
 
+import static android.service.dreams.Flags.dreamWakeRedirect;
+
 import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_WINDOW_TITLE;
 import static com.android.systemui.dreams.dagger.DreamModule.DREAM_TOUCH_INSET_MANAGER;
 import static com.android.systemui.dreams.dagger.DreamModule.HOME_CONTROL_PANEL_DREAM_COMPONENT;
@@ -149,6 +151,14 @@
 
     private final CommunalInteractor mCommunalInteractor;
 
+    private boolean mCommunalAvailable;
+
+    final Consumer<Boolean> mIsCommunalAvailableCallback =
+            isAvailable -> {
+                mCommunalAvailable = isAvailable;
+                updateRedirectWakeup();
+            };
+
     private final SystemDialogsCloser mSystemDialogsCloser;
 
     private final KeyguardUpdateMonitorCallback mKeyguardCallback =
@@ -287,6 +297,8 @@
 
         mExecutor.execute(() -> setLifecycleStateLocked(Lifecycle.State.CREATED));
 
+        collectFlow(getLifecycle(), mCommunalInteractor.isCommunalAvailable(),
+                mIsCommunalAvailableCallback);
         collectFlow(getLifecycle(), communalInteractor.isCommunalVisible(),
                 mCommunalVisibleConsumer);
         collectFlow(getLifecycle(), keyguardInteractor.primaryBouncerShowing,
@@ -374,6 +386,16 @@
 
         mDreamOverlayCallbackController.onStartDream();
         mStarted = true;
+
+        updateRedirectWakeup();
+    }
+
+    private void updateRedirectWakeup() {
+        if (!mStarted || !dreamWakeRedirect()) {
+            return;
+        }
+
+        redirectWake(mCommunalAvailable);
     }
 
     @Override
@@ -381,6 +403,11 @@
         resetCurrentDreamOverlayLocked();
     }
 
+    @Override
+    public void onWakeRequested() {
+        mCommunalInteractor.changeScene(CommunalScenes.Communal, null);
+    }
+
     private Lifecycle.State getLifecycleStateLocked() {
         return mLifecycleRegistry.getCurrentState();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
index 516b8c5..b0d134f 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
@@ -36,6 +36,11 @@
 import com.android.systemui.dreams.homecontrols.DreamActivityProvider;
 import com.android.systemui.dreams.homecontrols.DreamActivityProviderImpl;
 import com.android.systemui.dreams.homecontrols.HomeControlsDreamService;
+import com.android.systemui.qs.QsEventLogger;
+import com.android.systemui.qs.pipeline.shared.TileSpec;
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig;
+import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy;
+import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig;
 import com.android.systemui.res.R;
 import com.android.systemui.touch.TouchInsetManager;
 
@@ -44,6 +49,7 @@
 import dagger.Provides;
 import dagger.multibindings.ClassKey;
 import dagger.multibindings.IntoMap;
+import dagger.multibindings.StringKey;
 
 import java.util.Optional;
 import java.util.concurrent.Executor;
@@ -70,6 +76,7 @@
     String DREAM_SUPPORTED = "dream_supported";
     String DREAM_OVERLAY_WINDOW_TITLE = "dream_overlay_window_title";
     String HOME_CONTROL_PANEL_DREAM_COMPONENT = "home_control_panel_dream_component";
+    String DREAM_TILE_SPEC = "dream";
 
     /**
      * Provides the dream component
@@ -178,6 +185,23 @@
         return resources.getString(R.string.app_label);
     }
 
+    /** Provides config for the dream tile */
+    @Provides
+    @IntoMap
+    @StringKey(DREAM_TILE_SPEC)
+    static QSTileConfig provideDreamTileConfig(QsEventLogger uiEventLogger) {
+        TileSpec tileSpec = TileSpec.create(DREAM_TILE_SPEC);
+        return new QSTileConfig(tileSpec,
+                new QSTileUIConfig.Resource(
+                        R.drawable.ic_qs_screen_saver,
+                        R.string.quick_settings_screensaver_label),
+                uiEventLogger.getNewInstanceId(),
+                tileSpec.getSpec(),
+                QSTilePolicy.NoRestrictions.INSTANCE
+                );
+    }
+
+
     /** Provides activity for dream service */
     @Binds
     DreamActivityProvider bindActivityProvider(DreamActivityProviderImpl impl);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
index c415081..1fba737 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
@@ -19,7 +19,6 @@
 import android.animation.ValueAnimator
 import com.android.app.animation.Interpolators
 import com.android.app.tracing.coroutines.launch
-import com.android.internal.widget.LockPatternUtils
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
@@ -29,12 +28,13 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
 import com.android.systemui.power.domain.interactor.PowerInteractor
-import com.android.systemui.user.domain.interactor.SelectedUserInteractor
 import com.android.systemui.util.kotlin.Utils.Companion.sample
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.debounce
 
 @SysUISingleton
@@ -49,8 +49,6 @@
     private val keyguardInteractor: KeyguardInteractor,
     powerInteractor: PowerInteractor,
     keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
-    private val lockPatternUtils: LockPatternUtils,
-    private val selectedUserInteractor: SelectedUserInteractor,
 ) :
     TransitionInteractor(
         fromState = KeyguardState.AOD,
@@ -65,10 +63,18 @@
         listenForAodToAwake()
         listenForAodToOccluded()
         listenForAodToPrimaryBouncer()
-        listenForAodToGone()
         listenForTransitionToCamera(scope, keyguardInteractor)
     }
 
+    private val canDismissLockscreen: Flow<Boolean> =
+        combine(
+            keyguardInteractor.isKeyguardShowing,
+            keyguardInteractor.isKeyguardDismissible,
+            keyguardInteractor.biometricUnlockState,
+        ) { isKeyguardShowing, isKeyguardDismissible, biometricUnlockState ->
+            (isWakeAndUnlock(biometricUnlockState) || (!isKeyguardShowing && isKeyguardDismissible))
+        }
+
     /**
      * Listen for the signal that we're waking up and figure what state we need to transition to.
      */
@@ -79,12 +85,13 @@
         scope.launch("$TAG#listenForAodToAwake") {
             powerInteractor.detailedWakefulness
                 .filterRelevantKeyguardStateAnd { wakefulness -> wakefulness.isAwake() }
+                .debounce(50L)
                 .sample(
                     startedKeyguardTransitionStep,
                     keyguardInteractor.biometricUnlockState,
                     keyguardInteractor.primaryBouncerShowing,
                     keyguardInteractor.isKeyguardOccluded,
-                    selectedUserInteractor.selectedUser,
+                    canDismissLockscreen,
                 )
                 .collect {
                     (
@@ -93,10 +100,9 @@
                         biometricUnlockState,
                         primaryBouncerShowing,
                         isKeyguardOccludedLegacy,
-                        currentUser,
+                        canDismissLockscreen,
                     ) ->
                     if (!maybeHandleInsecurePowerGesture()) {
-                        val securityNone = lockPatternUtils.isLockScreenDisabled(currentUser)
                         val shouldTransitionToLockscreen =
                             if (KeyguardWmStateRefactor.isEnabled) {
                                 // Check with the superclass to see if an occlusion transition is
@@ -105,13 +111,11 @@
                                 // completes.
                                 !maybeStartTransitionToOccludedOrInsecureCamera() &&
                                     !isWakeAndUnlock(biometricUnlockState) &&
-                                    !primaryBouncerShowing &&
-                                    !securityNone
+                                    !primaryBouncerShowing
                             } else {
                                 !isKeyguardOccludedLegacy &&
                                     !isWakeAndUnlock(biometricUnlockState) &&
-                                    !primaryBouncerShowing &&
-                                    !securityNone
+                                    !primaryBouncerShowing
                             }
 
                         // With the refactor enabled, maybeStartTransitionToOccludedOrInsecureCamera
@@ -119,7 +123,11 @@
                         val shouldTransitionToOccluded =
                             !KeyguardWmStateRefactor.isEnabled && isKeyguardOccludedLegacy
 
-                        if (shouldTransitionToLockscreen) {
+                        if (canDismissLockscreen) {
+                            startTransitionTo(
+                                toState = KeyguardState.GONE,
+                            )
+                        } else if (shouldTransitionToLockscreen) {
                             val modeOnCanceled =
                                 if (startedStep.from == KeyguardState.LOCKSCREEN) {
                                     TransitionModeOnCanceled.REVERSE
@@ -181,35 +189,6 @@
         }
     }
 
-    private fun listenForAodToGone() {
-        if (KeyguardWmStateRefactor.isEnabled) {
-            // Handled via #dismissAod.
-            return
-        }
-
-        scope.launch("$TAG#listenForAodToGone") {
-            powerInteractor.isAwake
-                .debounce(50L)
-                .filterRelevantKeyguardState()
-                .sample(
-                    keyguardInteractor.biometricUnlockState,
-                    keyguardInteractor.isKeyguardShowing,
-                    keyguardInteractor.isKeyguardDismissible,
-                )
-                .collect { (isAwake, biometricUnlockState, isKeyguardShowing, isKeyguardDismissible)
-                    ->
-                    KeyguardWmStateRefactor.assertInLegacyMode()
-                    if (
-                        isAwake &&
-                            (isWakeAndUnlock(biometricUnlockState) ||
-                                (!isKeyguardShowing && isKeyguardDismissible))
-                    ) {
-                        startTransitionTo(KeyguardState.GONE)
-                    }
-                }
-        }
-    }
-
     /**
      * Dismisses AOD and transitions to GONE. This is called whenever authentication occurs while on
      * AOD.
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 141cca3..e711edc 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
@@ -101,12 +101,6 @@
         }
 
         scope.launch {
-            keyguardInteractor.isKeyguardDismissible.collect {
-                logger.log(TAG, VERBOSE, "isKeyguardDismissable", it)
-            }
-        }
-
-        scope.launch {
             keyguardInteractor.isAbleToDream.collect {
                 logger.log(TAG, VERBOSE, "isAbleToDream", it)
             }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt
index 0bc60c4..7c29b39 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt
@@ -21,6 +21,7 @@
 import android.animation.ValueAnimator
 import android.graphics.Rect
 import android.transition.Transition
+import android.transition.TransitionListenerAdapter
 import android.transition.TransitionSet
 import android.transition.TransitionValues
 import android.util.Log
@@ -169,6 +170,18 @@
                     return@OnPreDrawListener true
                 }
 
+                this@VisibilityBoundsTransition.addListener(
+                    object : TransitionListenerAdapter() {
+                        override fun onTransitionStart(t: Transition) {
+                            toView.viewTreeObserver.addOnPreDrawListener(predrawCallback)
+                        }
+
+                        override fun onTransitionEnd(t: Transition) {
+                            toView.viewTreeObserver.removeOnPreDrawListener(predrawCallback)
+                        }
+                    }
+                )
+
                 val listener =
                     object : AnimatorListenerAdapter() {
                         override fun onAnimationStart(anim: Animator) {
@@ -178,26 +191,11 @@
                         override fun onAnimationEnd(anim: Animator) {
                             assignAnimValues("end", 1f, toVis)
                             if (sendToBack) toView.translationZ = 0f
-                            toView.viewTreeObserver.removeOnPreDrawListener(predrawCallback)
-                        }
-
-                        override fun onAnimationPause(anim: Animator) {
-                            toView.viewTreeObserver.removeOnPreDrawListener(predrawCallback)
-                        }
-
-                        override fun onAnimationResume(anim: Animator) {
-                            toView.viewTreeObserver.addOnPreDrawListener(predrawCallback)
                         }
                     }
 
-                anim.duration = duration
-                anim.startDelay = startDelay
-                anim.interpolator = interpolator
                 anim.addListener(listener)
-                anim.addPauseListener(listener)
-
                 assignAnimValues("init", 0f, fromVis)
-                toView.viewTreeObserver.addOnPreDrawListener(predrawCallback)
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt b/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
index df3a974..9719c02 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
@@ -16,24 +16,64 @@
 
 package com.android.systemui.media.controls.data.repository
 
+import android.content.Context
 import com.android.internal.logging.InstanceId
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.media.controls.data.model.MediaSortKeyModel
 import com.android.systemui.media.controls.shared.model.MediaCommonModel
 import com.android.systemui.media.controls.shared.model.MediaData
 import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel
+import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.time.SystemClock
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import java.util.Locale
 import java.util.TreeMap
 import javax.inject.Inject
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
 
 /** A repository that holds the state of filtered media data on the device. */
 @SysUISingleton
-class MediaFilterRepository @Inject constructor(private val systemClock: SystemClock) {
+class MediaFilterRepository
+@Inject
+constructor(
+    @Application applicationContext: Context,
+    private val systemClock: SystemClock,
+    private val configurationController: ConfigurationController,
+) {
+
+    val onAnyMediaConfigurationChange: Flow<Unit> = conflatedCallbackFlow {
+        val callback =
+            object : ConfigurationController.ConfigurationListener {
+                override fun onDensityOrFontScaleChanged() {
+                    trySend(Unit)
+                }
+
+                override fun onThemeChanged() {
+                    trySend(Unit)
+                }
+
+                override fun onUiModeChanged() {
+                    trySend(Unit)
+                }
+
+                override fun onLocaleListChanged() {
+                    if (locale != applicationContext.resources.configuration.locales.get(0)) {
+                        locale = applicationContext.resources.configuration.locales.get(0)
+                        trySend(Unit)
+                    }
+                }
+            }
+        configurationController.addCallback(callback)
+        trySend(Unit)
+        awaitClose { configurationController.removeCallback(callback) }
+    }
 
     /** Instance id of media control that recommendations card reactivated. */
     private val _reactivatedId: MutableStateFlow<InstanceId?> = MutableStateFlow(null)
@@ -76,6 +116,7 @@
     val isMediaFromRec: StateFlow<Boolean> = _isMediaFromRec.asStateFlow()
 
     private var mediaFromRecPackageName: String? = null
+    private var locale: Locale = applicationContext.resources.configuration.locales.get(0)
 
     fun addMediaEntry(key: String, data: MediaData) {
         val entries = LinkedHashMap<String, MediaData>(_allUserEntries.value)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
index 13f934e..33c0b19 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
@@ -157,7 +157,7 @@
 
         // Set up links back into the pipeline for listeners that need to send events upstream.
         mediaTimeoutListener.timeoutCallback = { key: String, timedOut: Boolean ->
-            setInactive(key, timedOut)
+            mediaDataProcessor.setInactive(key, timedOut)
         }
         mediaTimeoutListener.stateCallback = { key: String, state: PlaybackState ->
             mediaDataProcessor.updateState(key, state)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt
index c0bb628..9f2d132 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt
@@ -83,6 +83,8 @@
             .pairwiseBy(initialValue = false) { wasPlaying, isPlaying -> !wasPlaying && isPlaying }
             .distinctUntilChanged()
 
+    val onAnyMediaConfigurationChange: Flow<Unit> = repository.onAnyMediaConfigurationChange
+
     fun removeMediaControl(
         token: MediaSession.Token?,
         instanceId: InstanceId,
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt
index dea5810..dd6b264 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt
@@ -65,6 +65,8 @@
             .distinctUntilChanged()
             .stateIn(applicationScope, SharingStarted.WhileSubscribed(), false)
 
+    val onAnyMediaConfigurationChange: Flow<Unit> = repository.onAnyMediaConfigurationChange
+
     fun removeMediaRecommendations(key: String, dismissIntent: Intent?, delayMs: Long) {
         mediaDataProcessor.dismissSmartspaceRecommendation(key, delayMs)
         if (dismissIntent == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
index 8dd3379..73fb558 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
@@ -100,7 +100,7 @@
         }
     }
 
-    private suspend fun bindMediaCard(
+    suspend fun bindMediaCard(
         viewHolder: MediaViewHolder,
         viewController: MediaViewController,
         viewModel: MediaPlayerViewModel,
@@ -333,7 +333,7 @@
                 }
             }
         }
-        updateSeekBarVisibility(viewController.expandedLayout, isSeekBarEnabled = false)
+        updateSeekBarVisibility(viewController.expandedLayout, viewController.isSeekBarEnabled)
     }
 
     private fun bindButtonCommon(
@@ -472,6 +472,7 @@
                             if (viewModel.shouldAddGradient) 333 else 80
                         )
                     }
+                        ?: albumView.setImageDrawable(artwork)
                 }
                 viewController.isArtworkBound = viewModel.shouldAddGradient
                 viewController.prevArtwork = artwork
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt
index fe13da6..bd4d435 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt
@@ -68,7 +68,7 @@
         }
     }
 
-    private fun bindRecsCard(
+    fun bindRecsCard(
         viewHolder: RecommendationViewHolder,
         viewModel: MediaRecsCardViewModel,
         mediaViewController: MediaViewController,
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
index d2dd289..0478178 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
@@ -35,6 +35,7 @@
 import androidx.annotation.VisibleForTesting
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import androidx.recyclerview.widget.DiffUtil
 import com.android.app.tracing.traceSection
 import com.android.internal.logging.InstanceId
 import com.android.keyguard.KeyguardUpdateMonitor
@@ -53,12 +54,18 @@
 import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
 import com.android.systemui.media.controls.shared.model.MediaData
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
+import com.android.systemui.media.controls.ui.binder.MediaControlViewBinder
+import com.android.systemui.media.controls.ui.binder.MediaRecommendationsViewBinder
 import com.android.systemui.media.controls.ui.controller.MediaControlPanel.SMARTSPACE_CARD_DISMISS_EVENT
+import com.android.systemui.media.controls.ui.util.MediaViewModelCallback
+import com.android.systemui.media.controls.ui.util.MediaViewModelListUpdateCallback
 import com.android.systemui.media.controls.ui.view.MediaCarouselScrollHandler
 import com.android.systemui.media.controls.ui.view.MediaHostState
 import com.android.systemui.media.controls.ui.view.MediaScrollView
 import com.android.systemui.media.controls.ui.view.MediaViewHolder
 import com.android.systemui.media.controls.ui.view.RecommendationViewHolder
+import com.android.systemui.media.controls.ui.viewmodel.MediaCarouselViewModel
+import com.android.systemui.media.controls.ui.viewmodel.MediaCommonViewModel
 import com.android.systemui.media.controls.util.MediaFlags
 import com.android.systemui.media.controls.util.MediaUiEventLogger
 import com.android.systemui.media.controls.util.SmallHash
@@ -118,12 +125,13 @@
     private val mediaHostStatesManager: MediaHostStatesManager,
     private val activityStarter: ActivityStarter,
     private val systemClock: SystemClock,
+    @Main private val mainDispatcher: CoroutineDispatcher,
     @Main executor: DelayableExecutor,
     @Background private val bgExecutor: Executor,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
     private val mediaManager: MediaDataManager,
     configurationController: ConfigurationController,
-    falsingManager: FalsingManager,
+    private val falsingManager: FalsingManager,
     dumpManager: DumpManager,
     private val logger: MediaUiEventLogger,
     private val debugLogger: MediaCarouselControllerLogger,
@@ -132,6 +140,8 @@
     private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
     private val globalSettings: GlobalSettings,
     private val secureSettings: SecureSettings,
+    private val mediaCarouselViewModel: MediaCarouselViewModel,
+    private val mediaViewControllerFactory: Provider<MediaViewController>,
 ) : Dumpable {
     /** The current width of the carousel */
     var currentCarouselWidth: Int = 0
@@ -182,7 +192,6 @@
         private set
     private val mediaContent: ViewGroup
     @VisibleForTesting var pageIndicator: PageIndicator
-    private val visualStabilityCallback: OnReorderingAllowedListener
     private var needsReordering: Boolean = false
     private var keysNeedRemoval = mutableSetOf<String>()
     var shouldScrollToKey: Boolean = false
@@ -201,7 +210,11 @@
     private val animationScaleObserver: ContentObserver =
         object : ContentObserver(null) {
             override fun onChange(selfChange: Boolean) {
-                MediaPlayerData.players().forEach { it.updateAnimatorDurationScale() }
+                if (!mediaFlags.isMediaControlsRefactorEnabled()) {
+                    MediaPlayerData.players().forEach { it.updateAnimatorDurationScale() }
+                } else {
+                    controllerByViewModel.values.forEach { it.updateAnimatorDurationScale() }
+                }
             }
         }
 
@@ -297,6 +310,9 @@
     private var widthInSceneContainerPx = 0
     private var heightInSceneContainerPx = 0
 
+    private val controllerByViewModel = mutableMapOf<MediaCommonViewModel, MediaViewController>()
+    private val commonViewModels = mutableListOf<MediaCommonViewModel>()
+
     init {
         dumpManager.registerDumpable(TAG, this)
         mediaFrame = inflateMediaCarousel()
@@ -320,7 +336,48 @@
         inflateSettingsButton()
         mediaContent = mediaCarousel.requireViewById(R.id.media_carousel)
         configurationController.addCallback(configListener)
-        visualStabilityCallback = OnReorderingAllowedListener {
+        if (!mediaFlags.isMediaControlsRefactorEnabled()) {
+            setUpListeners()
+        }
+        mediaFrame.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
+            // The pageIndicator is not laid out yet when we get the current state update,
+            // Lets make sure we have the right dimensions
+            updatePageIndicatorLocation()
+        }
+        mediaHostStatesManager.addCallback(
+            object : MediaHostStatesManager.Callback {
+                override fun onHostStateChanged(
+                    @MediaLocation location: Int,
+                    mediaHostState: MediaHostState
+                ) {
+                    updateUserVisibility()
+                    if (location == desiredLocation) {
+                        onDesiredLocationChanged(desiredLocation, mediaHostState, animate = false)
+                    }
+                }
+            }
+        )
+        keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
+        mediaCarousel.repeatWhenAttached {
+            repeatOnLifecycle(Lifecycle.State.STARTED) {
+                listenForAnyStateToGoneKeyguardTransition(this)
+                listenForAnyStateToLockscreenTransition(this)
+                listenForLockscreenSettingChanges(this)
+
+                if (!mediaFlags.isMediaControlsRefactorEnabled()) return@repeatOnLifecycle
+                listenForMediaItemsChanges(this)
+            }
+        }
+
+        // Notifies all active players about animation scale changes.
+        globalSettings.registerContentObserver(
+            Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE),
+            animationScaleObserver
+        )
+    }
+
+    private fun setUpListeners() {
+        val visualStabilityCallback = OnReorderingAllowedListener {
             if (needsReordering) {
                 needsReordering = false
                 reorderAllPlayers(previousVisiblePlayerKey = null)
@@ -530,35 +587,6 @@
                 }
             }
         )
-        mediaFrame.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
-            // The pageIndicator is not laid out yet when we get the current state update,
-            // Lets make sure we have the right dimensions
-            updatePageIndicatorLocation()
-        }
-        mediaHostStatesManager.addCallback(
-            object : MediaHostStatesManager.Callback {
-                override fun onHostStateChanged(location: Int, mediaHostState: MediaHostState) {
-                    updateUserVisibility()
-                    if (location == desiredLocation) {
-                        onDesiredLocationChanged(desiredLocation, mediaHostState, animate = false)
-                    }
-                }
-            }
-        )
-        keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
-        mediaCarousel.repeatWhenAttached {
-            repeatOnLifecycle(Lifecycle.State.STARTED) {
-                listenForAnyStateToGoneKeyguardTransition(this)
-                listenForAnyStateToLockscreenTransition(this)
-                listenForLockscreenSettingChanges(this)
-            }
-        }
-
-        // Notifies all active players about animation scale changes.
-        globalSettings.registerContentObserver(
-            Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE),
-            animationScaleObserver
-        )
     }
 
     private fun inflateSettingsButton() {
@@ -642,6 +670,125 @@
         }
     }
 
+    private fun listenForMediaItemsChanges(scope: CoroutineScope): Job {
+        return scope.launch {
+            mediaCarouselViewModel.mediaItems.collectLatest {
+                val diffUtilCallback = MediaViewModelCallback(commonViewModels, it)
+                val listUpdateCallback =
+                    MediaViewModelListUpdateCallback(
+                        old = commonViewModels,
+                        new = it,
+                        onAdded = this@MediaCarouselController::onAdded,
+                        onUpdated = this@MediaCarouselController::onUpdated,
+                        onRemoved = this@MediaCarouselController::onRemoved,
+                        onMoved = this@MediaCarouselController::onMoved,
+                    )
+                DiffUtil.calculateDiff(diffUtilCallback).dispatchUpdatesTo(listUpdateCallback)
+                setNewViewModelsList(it)
+            }
+        }
+    }
+
+    private fun onAdded(commonViewModel: MediaCommonViewModel, position: Int) {
+        val viewController = mediaViewControllerFactory.get()
+        viewController.sizeChangedListener = this::updateCarouselDimensions
+        val lp =
+            LinearLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT
+            )
+        when (commonViewModel) {
+            is MediaCommonViewModel.MediaControl -> {
+                val viewHolder = MediaViewHolder.create(LayoutInflater.from(context), mediaContent)
+                if (mediaFlags.isSceneContainerEnabled()) {
+                    viewController.widthInSceneContainerPx = widthInSceneContainerPx
+                    viewController.heightInSceneContainerPx = heightInSceneContainerPx
+                }
+                viewController.attachPlayer(viewHolder)
+                viewController.mediaViewHolder.player.layoutParams = lp
+                MediaControlViewBinder.bind(
+                    viewHolder,
+                    commonViewModel.controlViewModel,
+                    viewController,
+                    falsingManager,
+                    backgroundDispatcher,
+                    mainDispatcher,
+                    mediaFlags
+                )
+                mediaContent.addView(viewHolder.player, position)
+            }
+            is MediaCommonViewModel.MediaRecommendations -> {
+                val viewHolder =
+                    RecommendationViewHolder.create(LayoutInflater.from(context), mediaContent)
+                viewController.attachRecommendations(viewHolder)
+                viewController.recommendationViewHolder.recommendations.layoutParams = lp
+                MediaRecommendationsViewBinder.bind(
+                    viewHolder,
+                    commonViewModel.recsViewModel,
+                    viewController,
+                    falsingManager,
+                )
+                mediaContent.addView(viewHolder.recommendations, position)
+            }
+        }
+        viewController.setListening(mediaCarouselScrollHandler.visibleToUser && currentlyExpanded)
+        updateViewControllerToState(viewController, noAnimation = true)
+        updatePageIndicator()
+        mediaCarouselScrollHandler.onPlayersChanged()
+        mediaFrame.requiresRemeasuring = true
+        commonViewModel.onAdded(commonViewModel)
+        controllerByViewModel[commonViewModel] = viewController
+    }
+
+    private fun onUpdated(commonViewModel: MediaCommonViewModel) {
+        commonViewModel.onUpdated(commonViewModel)
+        updatePageIndicator()
+        mediaCarouselScrollHandler.onPlayersChanged()
+    }
+
+    private fun onRemoved(commonViewModel: MediaCommonViewModel) {
+        controllerByViewModel.remove(commonViewModel)?.let {
+            when (commonViewModel) {
+                is MediaCommonViewModel.MediaControl -> {
+                    mediaCarouselScrollHandler.onPrePlayerRemoved(it.mediaViewHolder.player)
+                    mediaContent.removeView(it.mediaViewHolder.player)
+                }
+                is MediaCommonViewModel.MediaRecommendations -> {
+                    mediaContent.removeView(it.recommendationViewHolder.recommendations)
+                }
+            }
+            it.onDestroy()
+            mediaCarouselScrollHandler.onPlayersChanged()
+            updatePageIndicator()
+            commonViewModel.onRemoved(true)
+        }
+    }
+
+    private fun onMoved(commonViewModel: MediaCommonViewModel, from: Int, to: Int) {
+        controllerByViewModel[commonViewModel]?.let {
+            mediaContent.removeViewAt(from)
+            when (commonViewModel) {
+                is MediaCommonViewModel.MediaControl -> {
+                    mediaContent.addView(it.mediaViewHolder.player, to)
+                }
+                is MediaCommonViewModel.MediaRecommendations -> {
+                    mediaContent.addView(it.recommendationViewHolder.recommendations, to)
+                }
+            }
+        }
+        updatePageIndicator()
+        mediaCarouselScrollHandler.onPlayersChanged()
+    }
+
+    private fun setNewViewModelsList(viewModels: List<MediaCommonViewModel>) {
+        commonViewModels.clear()
+        commonViewModels.addAll(viewModels)
+
+        // Ensure we only show the needed UMOs in media carousel.
+        val viewSet = viewModels.toHashSet()
+        controllerByViewModel.filter { !viewSet.contains(it.key) }.forEach { onRemoved(it.key) }
+    }
+
     private suspend fun getMediaLockScreenSetting(): Boolean {
         return withContext(backgroundDispatcher) {
             secureSettings.getBoolForUser(
@@ -758,7 +905,7 @@
                     isSsReactivated,
                     debugLogger
                 )
-                updatePlayerToState(newPlayer.mediaViewController, noAnimation = true)
+                updateViewControllerToState(newPlayer.mediaViewController, noAnimation = true)
                 // Media data added from a recommendation card should starts playing.
                 if (
                     (shouldScrollToKey && data.isPlaying == true) ||
@@ -856,7 +1003,7 @@
                 systemClock,
                 debugLogger,
             )
-            updatePlayerToState(newRecs.mediaViewController, noAnimation = true)
+            updateViewControllerToState(newRecs.mediaViewController, noAnimation = true)
             reorderAllPlayers(curVisibleMediaKey)
             updatePageIndicator()
             mediaFrame.requiresRemeasuring = true
@@ -905,6 +1052,10 @@
     }
 
     private fun updatePlayers(recreateMedia: Boolean) {
+        if (mediaFlags.isMediaControlsRefactorEnabled()) {
+            updateMediaPlayers(recreateMedia)
+            return
+        }
         pageIndicator.tintList =
             ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
         val previousVisibleKey =
@@ -940,6 +1091,28 @@
         }
     }
 
+    private fun updateMediaPlayers(recreateMedia: Boolean) {
+        pageIndicator.tintList =
+            ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+        if (recreateMedia) {
+            mediaContent.removeAllViews()
+            commonViewModels.forEach { viewModel ->
+                when (viewModel) {
+                    is MediaCommonViewModel.MediaControl -> {
+                        controllerByViewModel[viewModel]?.mediaViewHolder?.let {
+                            mediaContent.addView(it.player)
+                        }
+                    }
+                    is MediaCommonViewModel.MediaRecommendations -> {
+                        controllerByViewModel[viewModel]?.recommendationViewHolder?.let {
+                            mediaContent.addView(it.recommendations)
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     private fun updatePageIndicator() {
         val numPages = mediaContent.getChildCount()
         pageIndicator.setNumPages(numPages)
@@ -979,8 +1152,14 @@
             currentStartLocation = startLocation
             currentEndLocation = endLocation
             currentTransitionProgress = progress
-            for (mediaPlayer in MediaPlayerData.players()) {
-                updatePlayerToState(mediaPlayer.mediaViewController, immediately)
+            if (!mediaFlags.isMediaControlsRefactorEnabled()) {
+                for (mediaPlayer in MediaPlayerData.players()) {
+                    updateViewControllerToState(mediaPlayer.mediaViewController, immediately)
+                }
+            } else {
+                controllerByViewModel.values.forEach {
+                    updateViewControllerToState(it, immediately)
+                }
             }
             maybeResetSettingsCog()
             updatePageIndicatorAlpha()
@@ -1035,8 +1214,14 @@
 
     /** Update listening to seekbar. */
     private fun updateSeekbarListening(visibleToUser: Boolean) {
-        for (player in MediaPlayerData.players()) {
-            player.setListening(visibleToUser && currentlyExpanded)
+        if (!mediaFlags.isMediaControlsRefactorEnabled()) {
+            for (player in MediaPlayerData.players()) {
+                player.setListening(visibleToUser && currentlyExpanded)
+            }
+        } else {
+            controllerByViewModel.values.forEach {
+                it.setListening(visibleToUser && currentlyExpanded)
+            }
         }
     }
 
@@ -1044,12 +1229,22 @@
     private fun updateCarouselDimensions() {
         var width = 0
         var height = 0
-        for (mediaPlayer in MediaPlayerData.players()) {
-            val controller = mediaPlayer.mediaViewController
-            // When transitioning the view to gone, the view gets smaller, but the translation
-            // Doesn't, let's add the translation
-            width = Math.max(width, controller.currentWidth + controller.translationX.toInt())
-            height = Math.max(height, controller.currentHeight + controller.translationY.toInt())
+        if (!mediaFlags.isMediaControlsRefactorEnabled()) {
+            for (mediaPlayer in MediaPlayerData.players()) {
+                val controller = mediaPlayer.mediaViewController
+                // When transitioning the view to gone, the view gets smaller, but the translation
+                // Doesn't, let's add the translation
+                width = Math.max(width, controller.currentWidth + controller.translationX.toInt())
+                height =
+                    Math.max(height, controller.currentHeight + controller.translationY.toInt())
+            }
+        } else {
+            controllerByViewModel.values.forEach {
+                // When transitioning the view to gone, the view gets smaller, but the translation
+                // Doesn't, let's add the translation
+                width = Math.max(width, it.currentWidth + it.translationX.toInt())
+                height = Math.max(height, it.currentHeight + it.translationY.toInt())
+            }
         }
         if (width != currentCarouselWidth || height != currentCarouselHeight) {
             currentCarouselWidth = width
@@ -1080,7 +1275,10 @@
         }
     }
 
-    private fun updatePlayerToState(viewController: MediaViewController, noAnimation: Boolean) {
+    private fun updateViewControllerToState(
+        viewController: MediaViewController,
+        noAnimation: Boolean
+    ) {
         viewController.setCurrentState(
             startLocation = currentStartLocation,
             endLocation = currentEndLocation,
@@ -1123,18 +1321,31 @@
                         !mediaManager.hasActiveMediaOrRecommendation() &&
                         desiredHostState.showsOnlyActiveMedia
 
-                for (mediaPlayer in MediaPlayerData.players()) {
-                    if (animate) {
-                        mediaPlayer.mediaViewController.animatePendingStateChange(
-                            duration = duration,
-                            delay = startDelay
-                        )
-                    }
-                    if (shouldCloseGuts && mediaPlayer.mediaViewController.isGutsVisible) {
-                        mediaPlayer.closeGuts(!animate)
-                    }
+                if (!mediaFlags.isMediaControlsRefactorEnabled()) {
+                    for (mediaPlayer in MediaPlayerData.players()) {
+                        if (animate) {
+                            mediaPlayer.mediaViewController.animatePendingStateChange(
+                                duration = duration,
+                                delay = startDelay
+                            )
+                        }
+                        if (shouldCloseGuts && mediaPlayer.mediaViewController.isGutsVisible) {
+                            mediaPlayer.closeGuts(!animate)
+                        }
 
-                    mediaPlayer.mediaViewController.onLocationPreChange(desiredLocation)
+                        mediaPlayer.mediaViewController.onLocationPreChange(desiredLocation)
+                    }
+                } else {
+                    controllerByViewModel.values.forEach { controller ->
+                        if (animate) {
+                            controller.animatePendingStateChange(duration, startDelay)
+                        }
+                        if (shouldCloseGuts && controller.isGutsVisible) {
+                            controller.closeGuts(!animate)
+                        }
+
+                        controller.onLocationPreChange(desiredLocation)
+                    }
                 }
                 mediaCarouselScrollHandler.showsSettingsButton = !it.showsOnlyActiveMedia
                 mediaCarouselScrollHandler.falsingProtectionNeeded = it.falsingProtectionNeeded
@@ -1150,7 +1361,11 @@
         }
 
     fun closeGuts(immediate: Boolean = true) {
-        MediaPlayerData.players().forEach { it.closeGuts(immediate) }
+        if (!mediaFlags.isMediaControlsRefactorEnabled()) {
+            MediaPlayerData.players().forEach { it.closeGuts(immediate) }
+        } else {
+            controllerByViewModel.values.forEach { it.closeGuts(immediate) }
+        }
     }
 
     /** Update the size of the carousel, remeasuring it if necessary. */
@@ -1288,6 +1503,10 @@
     }
 
     private fun onSwipeToDismiss() {
+        if (mediaFlags.isMediaControlsRefactorEnabled()) {
+            mediaCarouselViewModel.onSwipeToDismiss()
+            return
+        }
         MediaPlayerData.players().forEachIndexed { index, it ->
             if (it.mIsImpressed) {
                 logSmartspaceCardReported(
@@ -1319,6 +1538,7 @@
             println("dataKeys: ${MediaPlayerData.dataKeys()}")
             println("orderedPlayerSortKeys: ${MediaPlayerData.playerKeys()}")
             println("visiblePlayerSortKeys: ${MediaPlayerData.visiblePlayerKeys()}")
+            println("commonViewModels: $commonViewModels")
             println("smartspaceMediaData: ${MediaPlayerData.smartspaceMediaData}")
             println("shouldPrioritizeSs: ${MediaPlayerData.shouldPrioritizeSs}")
             println("current size: $currentCarouselWidth x $currentCarouselHeight")
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
index 5188132..96a8239 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
@@ -31,6 +31,7 @@
 import com.android.systemui.util.Utils
 import com.android.systemui.util.kotlin.pairwiseBy
 import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import java.util.concurrent.Executor
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
@@ -50,6 +51,7 @@
     @Application private val applicationScope: CoroutineScope,
     @Application private val applicationContext: Context,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
+    @Background private val backgroundExecutor: Executor,
     private val visualStabilityProvider: VisualStabilityProvider,
     private val interactor: MediaCarouselInteractor,
     private val controlInteractorFactory: MediaControlInteractorFactory,
@@ -142,9 +144,9 @@
 
     private fun createMediaControlViewModel(instanceId: InstanceId): MediaControlViewModel {
         return MediaControlViewModel(
-            applicationScope = applicationScope,
             applicationContext = applicationContext,
             backgroundDispatcher = backgroundDispatcher,
+            backgroundExecutor = backgroundExecutor,
             interactor = controlInteractorFactory.create(instanceId),
             logger = logger,
         )
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
index 52e49d6..bc364c3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
@@ -41,21 +41,21 @@
 import com.android.systemui.monet.Style
 import com.android.systemui.res.R
 import com.android.systemui.util.kotlin.sample
+import java.util.concurrent.Executor
 import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOn
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
 
 /** Models UI state and handles user input for a media control. */
 class MediaControlViewModel(
     @Application private val applicationContext: Context,
-    @Application private val applicationScope: CoroutineScope,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
+    @Background private val backgroundExecutor: Executor,
     private val interactor: MediaControlInteractor,
     private val logger: MediaUiEventLogger,
 ) {
@@ -72,9 +72,15 @@
                 .distinctUntilChanged()
         )
 
+    @OptIn(ExperimentalCoroutinesApi::class)
     val player: Flow<MediaPlayerViewModel?> =
-        combine(playTurbulenceNoise, interactor.mediaControl) { playTurbulenceNoise, mediaControl ->
-                mediaControl?.let { toViewModel(it, playTurbulenceNoise) }
+        interactor.onAnyMediaConfigurationChange
+            .flatMapLatest {
+                combine(playTurbulenceNoise, interactor.mediaControl) {
+                    playTurbulenceNoise,
+                    mediaControl ->
+                    mediaControl?.let { toViewModel(it, playTurbulenceNoise) }
+                }
             }
             .distinctUntilChanged()
             .flowOn(backgroundDispatcher)
@@ -161,12 +167,10 @@
                 if (model.isResume && model.resumeProgress != null) {
                     seekBarViewModel.updateStaticProgress(model.resumeProgress)
                 } else {
-                    applicationScope.launch {
-                        withContext(backgroundDispatcher) {
-                            seekBarViewModel.updateController(
-                                model.token?.let { MediaController(applicationContext, it) }
-                            )
-                        }
+                    backgroundExecutor.execute {
+                        seekBarViewModel.updateController(
+                            model.token?.let { MediaController(applicationContext, it) }
+                        )
                     }
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
index 5cd9804..52c4bc5 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
@@ -50,8 +50,10 @@
 import com.android.systemui.res.R
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.withContext
@@ -67,9 +69,12 @@
     private val logger: MediaUiEventLogger,
 ) {
 
+    @OptIn(ExperimentalCoroutinesApi::class)
     val mediaRecsCard: Flow<MediaRecsCardViewModel?> =
-        interactor.recommendations
-            .map { recsCard -> toRecsViewModel(recsCard) }
+        interactor.onAnyMediaConfigurationChange
+            .flatMapLatest {
+                interactor.recommendations.map { recsCard -> toRecsViewModel(recsCard) }
+            }
             .distinctUntilChanged()
             .flowOn(backgroundDispatcher)
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
index 22b3f35..cef1e69 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
@@ -33,19 +33,12 @@
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import com.android.systemui.classifier.Classifier.MEDIA_SEEKBAR
-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.media.controls.util.MediaFlags
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.statusbar.NotificationMediaManager
 import com.android.systemui.util.concurrency.RepeatableExecutor
 import javax.inject.Inject
 import kotlin.math.abs
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
 
 private const val POSITION_UPDATE_INTERVAL_MILLIS = 100L
 private const val MIN_FLING_VELOCITY_SCALE_FACTOR = 10
@@ -88,11 +81,8 @@
 class SeekBarViewModel
 @Inject
 constructor(
-    @Application private val applicationScope: CoroutineScope,
-    @Main private val mainDispatcher: CoroutineDispatcher,
     @Background private val bgExecutor: RepeatableExecutor,
     private val falsingManager: FalsingManager,
-    private val mediaFlags: MediaFlags,
 ) {
     private var _data =
         Progress(
@@ -118,19 +108,9 @@
     private var controller: MediaController? = null
         set(value) {
             if (field?.sessionToken != value?.sessionToken) {
-                if (!mediaFlags.isMediaControlsRefactorEnabled()) {
-                    field?.unregisterCallback(callback)
-                    value?.registerCallback(callback)
-                    field = value
-                } else {
-                    applicationScope.launch {
-                        withContext(mainDispatcher) {
-                            field?.unregisterCallback(callback)
-                            value?.registerCallback(callback)
-                            field = value
-                        }
-                    }
-                }
+                field?.unregisterCallback(callback)
+                value?.registerCallback(callback)
+                field = value
             }
         }
     private var playbackState: PlaybackState? = null
diff --git a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt b/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
index d40112f..3907a72 100644
--- a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
@@ -16,10 +16,16 @@
 
 package com.android.systemui.qrcodescanner.dagger
 
+import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.qs.tiles.QRCodeScannerTile
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
+import com.android.systemui.res.R
 import dagger.Binds
 import dagger.Module
+import dagger.Provides
 import dagger.multibindings.IntoMap
 import dagger.multibindings.StringKey
 
@@ -31,4 +37,22 @@
     @IntoMap
     @StringKey(QRCodeScannerTile.TILE_SPEC)
     fun bindQRCodeScannerTile(qrCodeScannerTile: QRCodeScannerTile): QSTileImpl<*>
+
+    companion object {
+        const val QR_CODE_SCANNER_TILE_SPEC = "qr_code_scanner"
+
+        @Provides
+        @IntoMap
+        @StringKey(QR_CODE_SCANNER_TILE_SPEC)
+        fun provideQRCodeScannerTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+            QSTileConfig(
+                tileSpec = TileSpec.create(QR_CODE_SCANNER_TILE_SPEC),
+                uiConfig =
+                    QSTileUIConfig.Resource(
+                        iconRes = R.drawable.ic_qr_code_scanner,
+                        labelRes = R.string.qr_code_scanner_title,
+                    ),
+                instanceId = uiEventLogger.getNewInstanceId(),
+            )
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
index 4a8e33a..2e52845 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
@@ -60,6 +60,7 @@
 
     companion object {
         /** Create a [TileSpec] from the string [spec]. */
+        @JvmStatic
         fun create(spec: String): TileSpec {
             return if (TextUtils.isEmpty(spec)) {
                 Invalid
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
index d67cf4d..26af9a7 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
@@ -16,10 +16,16 @@
 
 package com.android.systemui.recordissue
 
+import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.qs.tiles.RecordIssueTile
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
+import com.android.systemui.res.R
 import dagger.Binds
 import dagger.Module
+import dagger.Provides
 import dagger.multibindings.IntoMap
 import dagger.multibindings.StringKey
 
@@ -30,4 +36,23 @@
     @IntoMap
     @StringKey(RecordIssueTile.TILE_SPEC)
     fun bindRecordIssueTile(recordIssueTile: RecordIssueTile): QSTileImpl<*>
+
+    companion object {
+
+        const val RECORD_ISSUE_TILE_SPEC = "record_issue"
+
+        @Provides
+        @IntoMap
+        @StringKey(RECORD_ISSUE_TILE_SPEC)
+        fun provideRecordIssueTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+            QSTileConfig(
+                tileSpec = TileSpec.create(RECORD_ISSUE_TILE_SPEC),
+                uiConfig =
+                    QSTileUIConfig.Resource(
+                        iconRes = R.drawable.qs_record_issue_icon_off,
+                        labelRes = R.string.qs_record_issue_label
+                    ),
+                instanceId = uiEventLogger.getNewInstanceId(),
+            )
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
index e3d2f7d..4b6dd8d 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
@@ -199,7 +199,7 @@
 
         for (int i = 0; i < SIM_SLOTS; i++) {
             mInfos[i] = new CellSignalState(
-                    true,
+                    false,
                     R.drawable.ic_shade_no_calling_sms,
                     context.getText(AccessibilityContentDescriptions.NO_CALLING).toString(),
                     "",
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/ui/binder/SmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/smartspace/ui/binder/SmartspaceViewBinder.kt
new file mode 100644
index 0000000..6c3d7df
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/ui/binder/SmartspaceViewBinder.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.smartspace.ui.binder
+
+import android.view.View
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceView
+import com.android.systemui.smartspace.ui.viewmodel.SmartspaceViewModel
+import kotlinx.coroutines.launch
+
+/** Binds the view and view-model for the smartspace. */
+object SmartspaceViewBinder {
+
+    /** Binds the view and view-model for the smartspace. */
+    fun bind(
+        smartspaceView: SmartspaceView,
+        viewModel: SmartspaceViewModel,
+    ) {
+        val view = smartspaceView as View
+        view.repeatWhenAttached {
+            repeatOnLifecycle(Lifecycle.State.CREATED) {
+                launch {
+                    // Observe screen on/off changes
+                    viewModel.isAwake.collect { isAwake -> smartspaceView.setScreenOn(isAwake) }
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/ui/viewmodel/SmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/smartspace/ui/viewmodel/SmartspaceViewModel.kt
new file mode 100644
index 0000000..4177383
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/ui/viewmodel/SmartspaceViewModel.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.smartspace.ui.viewmodel
+
+import com.android.systemui.power.domain.interactor.PowerInteractor
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filter
+
+class SmartspaceViewModel
+@AssistedInject
+constructor(
+    powerInteractor: PowerInteractor,
+    @Assisted val surfaceName: String,
+) {
+
+    /** Screen on/off state */
+    val isAwake: Flow<Boolean> =
+        powerInteractor.isAwake.filter { surfaceName != SURFACE_WEATHER_VIEW }
+
+    @AssistedFactory
+    interface Factory {
+        fun create(surfaceName: String): SmartspaceViewModel
+    }
+
+    companion object {
+        const val SURFACE_DATE_VIEW = "date_view"
+        const val SURFACE_WEATHER_VIEW = "weather_view"
+        const val SURFACE_GENERAL_VIEW = "general_view"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 09985f8..7983db1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -21,6 +21,7 @@
 import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_MANAGEMENT_DISCLOSURE;
 import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_NAMED_MANAGEMENT_DISCLOSURE;
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT;
 import static android.hardware.biometrics.BiometricSourceType.FACE;
 import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
 import static android.view.View.GONE;
@@ -60,7 +61,6 @@
 import android.content.res.Resources;
 import android.graphics.Color;
 import android.hardware.biometrics.BiometricSourceType;
-import android.hardware.face.FaceManager;
 import android.os.BatteryManager;
 import android.os.Handler;
 import android.os.Looper;
@@ -1404,7 +1404,7 @@
                 mKeyguardLogger.logBiometricMessage("KIC suppressingFaceError", msgId, errString);
                 return;
             }
-            if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
+            if (msgId == FACE_ERROR_TIMEOUT) {
                 handleFaceAuthTimeoutError(deferredFaceMessage);
             } else if (mIndicationHelper.isFaceLockoutErrorMsg(msgId)) {
                 handleFaceLockoutError(errString);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
index ac510fe..37989f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
@@ -190,12 +190,12 @@
     private companion object {
         // From which percentage we should start the gradient reveal width
         // E.g. if 0 - starts with 0px width, 0.6f - starts with 60% width
-        private const val GRADIENT_START_BOUNDS_PERCENTAGE: Float = 1f
+        private const val GRADIENT_START_BOUNDS_PERCENTAGE: Float = 0.95f
 
         // When to start changing alpha color of the gradient scrim
         // E.g. if 0.6f - starts fading the gradient away at 60% and becomes completely
         // transparent at 100%
-        private const val REVEAL_GRADIENT_END_COLOR_ALPHA_START_PERCENTAGE: Float = 1f
+        private const val REVEAL_GRADIENT_END_COLOR_ALPHA_START_PERCENTAGE: Float = 0.95f
 
         // When to finish displaying start color fill that reveals the content
         // E.g. if 0.6f - the content won't be visible at 0% and it will gradually
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
index 7a7cb7d..c7952b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
@@ -95,6 +95,9 @@
         const val AIRPLANE_MODE_TILE_SPEC = "airplane"
         const val DATA_SAVER_TILE_SPEC = "saver"
         const val INTERNET_TILE_SPEC = "internet"
+        const val HOTSPOT_TILE_SPEC = "hotspot"
+        const val CAST_TILE_SPEC = "cast"
+        const val BLUETOOTH_TILE_SPEC = "bt"
 
         /** Inject InternetTile or InternetTileNewImpl into tileMap in QSModule */
         @Provides
@@ -204,5 +207,47 @@
                 stateInteractor,
                 mapper,
             )
+
+        @Provides
+        @IntoMap
+        @StringKey(HOTSPOT_TILE_SPEC)
+        fun provideHotspotTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+            QSTileConfig(
+                tileSpec = TileSpec.create(HOTSPOT_TILE_SPEC),
+                uiConfig =
+                    QSTileUIConfig.Resource(
+                        iconRes = R.drawable.ic_hotspot,
+                        labelRes = R.string.quick_settings_hotspot_label,
+                    ),
+                instanceId = uiEventLogger.getNewInstanceId(),
+            )
+
+        @Provides
+        @IntoMap
+        @StringKey(CAST_TILE_SPEC)
+        fun provideCastTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+            QSTileConfig(
+                tileSpec = TileSpec.create(CAST_TILE_SPEC),
+                uiConfig =
+                    QSTileUIConfig.Resource(
+                        iconRes = R.drawable.ic_cast,
+                        labelRes = R.string.quick_settings_cast_title,
+                    ),
+                instanceId = uiEventLogger.getNewInstanceId(),
+            )
+
+        @Provides
+        @IntoMap
+        @StringKey(BLUETOOTH_TILE_SPEC)
+        fun provideBluetoothTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+            QSTileConfig(
+                tileSpec = TileSpec.create(BLUETOOTH_TILE_SPEC),
+                uiConfig =
+                    QSTileUIConfig.Resource(
+                        iconRes = R.drawable.qs_bluetooth_icon_off,
+                        labelRes = R.string.quick_settings_bluetooth_label,
+                    ),
+                instanceId = uiEventLogger.getNewInstanceId(),
+            )
     }
 }
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 c29a64e..446a0d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -40,6 +40,7 @@
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.settingslib.Utils
 import com.android.systemui.Dumpable
+import com.android.systemui.Flags.smartspaceLockscreenViewmodel
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
@@ -60,6 +61,8 @@
 import com.android.systemui.shared.regionsampling.RegionSampler
 import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DATE_SMARTSPACE_DATA_PLUGIN
 import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.WEATHER_SMARTSPACE_DATA_PLUGIN
+import com.android.systemui.smartspace.ui.binder.SmartspaceViewBinder
+import com.android.systemui.smartspace.ui.viewmodel.SmartspaceViewModel
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
@@ -98,6 +101,7 @@
         private val bypassController: KeyguardBypassController,
         private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
         private val wakefulnessLifecycle: WakefulnessLifecycle,
+        private val smartspaceViewModelFactory: SmartspaceViewModel.Factory,
         private val dumpManager: DumpManager,
         private val execution: Execution,
         @Main private val uiExecutor: Executor,
@@ -333,7 +337,12 @@
             throw RuntimeException("Cannot build date view when not decoupled")
         }
 
-        val view = buildView(parent, datePlugin)
+        val view =
+            buildView(
+                surfaceName = SmartspaceViewModel.SURFACE_DATE_VIEW,
+                parent = parent,
+                plugin = datePlugin
+            )
         connectSession()
 
         return view
@@ -352,7 +361,12 @@
             throw RuntimeException("Cannot build weather view when not decoupled")
         }
 
-        val view = buildView(parent, weatherPlugin)
+        val view =
+            buildView(
+                surfaceName = SmartspaceViewModel.SURFACE_WEATHER_VIEW,
+                parent = parent,
+                plugin = weatherPlugin
+            )
         connectSession()
 
         return view
@@ -368,16 +382,23 @@
             throw RuntimeException("Cannot build view when not enabled")
         }
 
-        val view = buildView(parent, plugin, configPlugin)
+        val view =
+            buildView(
+                surfaceName = SmartspaceViewModel.SURFACE_GENERAL_VIEW,
+                parent = parent,
+                plugin = plugin,
+                configPlugin = configPlugin
+            )
         connectSession()
 
         return view
     }
 
     private fun buildView(
-            parent: ViewGroup,
-            plugin: BcSmartspaceDataPlugin?,
-            configPlugin: BcSmartspaceConfigPlugin? = null
+        surfaceName: String,
+        parent: ViewGroup,
+        plugin: BcSmartspaceDataPlugin?,
+        configPlugin: BcSmartspaceConfigPlugin? = null
     ): View? {
         if (plugin == null) {
             return null
@@ -424,6 +445,14 @@
         return (ssView as View).apply {
             setTag(R.id.tag_smartspace_view, Any())
             addOnAttachStateChangeListener(stateChangeListener)
+
+            if (smartspaceLockscreenViewmodel()) {
+                val viewModel = smartspaceViewModelFactory.create(surfaceName)
+                SmartspaceViewBinder.bind(
+                    smartspaceView = ssView,
+                    viewModel = viewModel,
+                )
+            }
         }
     }
 
@@ -466,7 +495,9 @@
         configurationController.addCallback(configChangeListener)
         statusBarStateController.addCallback(statusBarStateListener)
         bypassController.registerOnBypassStateChangedListener(bypassStateChangedListener)
-        wakefulnessLifecycle.addObserver(wakefulnessLifecycleObserver)
+        if (!smartspaceLockscreenViewmodel()) {
+            wakefulnessLifecycle.addObserver(wakefulnessLifecycleObserver)
+        }
 
         datePlugin?.registerSmartspaceEventNotifier { e -> session?.notifySmartspaceEvent(e) }
         weatherPlugin?.registerSmartspaceEventNotifier { e -> session?.notifySmartspaceEvent(e) }
@@ -509,7 +540,9 @@
         configurationController.removeCallback(configChangeListener)
         statusBarStateController.removeCallback(statusBarStateListener)
         bypassController.unregisterOnBypassStateChangedListener(bypassStateChangedListener)
-        wakefulnessLifecycle.removeObserver(wakefulnessLifecycleObserver)
+        if (!smartspaceLockscreenViewmodel()) {
+            wakefulnessLifecycle.removeObserver(wakefulnessLifecycleObserver)
+        }
         session = null
 
         datePlugin?.registerSmartspaceEventNotifier(null)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java
index 0c248f5..0c0cb07 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java
@@ -31,7 +31,6 @@
     boolean animateAlpha;
     boolean animateX;
     public boolean animateY;
-    ArraySet<View> animateYViews = new ArraySet<>();
     boolean animateZ;
     boolean animateHeight;
     boolean animateTopInset;
@@ -87,13 +86,8 @@
         return this;
     }
 
-    public AnimationFilter animateY(View view) {
-        animateYViews.add(view);
-        return this;
-    }
-
     public boolean shouldAnimateY(View view) {
-        return animateY || animateYViews.contains(view);
+        return animateY;
     }
 
     /**
@@ -118,7 +112,6 @@
         animateAlpha |= filter.animateAlpha;
         animateX |= filter.animateX;
         animateY |= filter.animateY;
-        animateYViews.addAll(filter.animateYViews);
         animateZ |= filter.animateZ;
         animateHeight |= filter.animateHeight;
         animateTopInset |= filter.animateTopInset;
@@ -131,7 +124,6 @@
         animateAlpha = false;
         animateX = false;
         animateY = false;
-        animateYViews.clear();
         animateZ = false;
         animateHeight = false;
         animateTopInset = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
index f097d06..ef14557 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
@@ -657,7 +657,7 @@
         }
         ObjectAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_TRANSLATION_Y);
         AnimationFilter filter = properties.getAnimationFilter();
-        if (!filter.shouldAnimateY(child)) {
+        if (!filter.animateY) {
             // just a local update was performed
             if (previousAnimator != null) {
                 // we need to increase all animation keyframes of the previous animator by the
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt
index 4f702d7..d4b2dbf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt
@@ -102,6 +102,15 @@
         )
     }
 
+    fun logOnCarrierRoamingNtnModeChanged(active: Boolean) {
+        buffer.log(
+            TAG,
+            LogLevel.INFO,
+            { bool1 = active },
+            { "onCarrierRoamingNtnModeChanged: $bool1" }
+        )
+    }
+
     fun logOnDisplayInfoChanged(displayInfo: TelephonyDisplayInfo, subId: Int) {
         buffer.log(
             TAG,
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 b3885d2..6803a9d 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
@@ -142,21 +142,33 @@
                 val callback =
                     object :
                         TelephonyCallback(),
-                        TelephonyCallback.ServiceStateListener,
-                        TelephonyCallback.SignalStrengthsListener,
-                        TelephonyCallback.DataConnectionStateListener,
-                        TelephonyCallback.DataActivityListener,
                         TelephonyCallback.CarrierNetworkListener,
+                        TelephonyCallback.CarrierRoamingNtnModeListener,
+                        TelephonyCallback.DataActivityListener,
+                        TelephonyCallback.DataConnectionStateListener,
+                        TelephonyCallback.DataEnabledListener,
                         TelephonyCallback.DisplayInfoListener,
-                        TelephonyCallback.DataEnabledListener {
-                        override fun onServiceStateChanged(serviceState: ServiceState) {
-                            logger.logOnServiceStateChanged(serviceState, subId)
-                            trySend(CallbackEvent.OnServiceStateChanged(serviceState))
+                        TelephonyCallback.ServiceStateListener,
+                        TelephonyCallback.SignalStrengthsListener {
+
+                        override fun onCarrierNetworkChange(active: Boolean) {
+                            logger.logOnCarrierNetworkChange(active, subId)
+                            trySend(CallbackEvent.OnCarrierNetworkChange(active))
                         }
 
-                        override fun onSignalStrengthsChanged(signalStrength: SignalStrength) {
-                            logger.logOnSignalStrengthsChanged(signalStrength, subId)
-                            trySend(CallbackEvent.OnSignalStrengthChanged(signalStrength))
+                        override fun onCarrierRoamingNtnModeChanged(active: Boolean) {
+                            logger.logOnCarrierRoamingNtnModeChanged(active)
+                            trySend(CallbackEvent.OnCarrierRoamingNtnModeChanged(active))
+                        }
+
+                        override fun onDataActivity(direction: Int) {
+                            logger.logOnDataActivity(direction, subId)
+                            trySend(CallbackEvent.OnDataActivity(direction))
+                        }
+
+                        override fun onDataEnabledChanged(enabled: Boolean, reason: Int) {
+                            logger.logOnDataEnabledChanged(enabled, subId)
+                            trySend(CallbackEvent.OnDataEnabledChanged(enabled))
                         }
 
                         override fun onDataConnectionStateChanged(
@@ -167,16 +179,6 @@
                             trySend(CallbackEvent.OnDataConnectionStateChanged(dataState))
                         }
 
-                        override fun onDataActivity(direction: Int) {
-                            logger.logOnDataActivity(direction, subId)
-                            trySend(CallbackEvent.OnDataActivity(direction))
-                        }
-
-                        override fun onCarrierNetworkChange(active: Boolean) {
-                            logger.logOnCarrierNetworkChange(active, subId)
-                            trySend(CallbackEvent.OnCarrierNetworkChange(active))
-                        }
-
                         override fun onDisplayInfoChanged(
                             telephonyDisplayInfo: TelephonyDisplayInfo
                         ) {
@@ -184,9 +186,14 @@
                             trySend(CallbackEvent.OnDisplayInfoChanged(telephonyDisplayInfo))
                         }
 
-                        override fun onDataEnabledChanged(enabled: Boolean, reason: Int) {
-                            logger.logOnDataEnabledChanged(enabled, subId)
-                            trySend(CallbackEvent.OnDataEnabledChanged(enabled))
+                        override fun onServiceStateChanged(serviceState: ServiceState) {
+                            logger.logOnServiceStateChanged(serviceState, subId)
+                            trySend(CallbackEvent.OnServiceStateChanged(serviceState))
+                        }
+
+                        override fun onSignalStrengthsChanged(signalStrength: SignalStrength) {
+                            logger.logOnSignalStrengthsChanged(signalStrength, subId)
+                            trySend(CallbackEvent.OnSignalStrengthChanged(signalStrength))
                         }
                     }
                 telephonyManager.registerTelephonyCallback(bgDispatcher.asExecutor(), callback)
@@ -229,8 +236,8 @@
 
     override val isNonTerrestrial =
         callbackEvents
-            .mapNotNull { it.onServiceStateChanged }
-            .map { it.serviceState.isUsingNonTerrestrialNetwork }
+            .mapNotNull { it.onCarrierRoamingNtnModeChanged }
+            .map { it.active }
             .stateIn(scope, SharingStarted.WhileSubscribed(), false)
 
     override val isGsm =
@@ -502,6 +509,8 @@
 sealed interface CallbackEvent {
     data class OnCarrierNetworkChange(val active: Boolean) : CallbackEvent
 
+    data class OnCarrierRoamingNtnModeChanged(val active: Boolean) : CallbackEvent
+
     data class OnDataActivity(val direction: Int) : CallbackEvent
 
     data class OnDataConnectionStateChanged(val dataState: Int) : CallbackEvent
@@ -522,6 +531,7 @@
 data class TelephonyCallbackState(
     val onDataActivity: CallbackEvent.OnDataActivity? = null,
     val onCarrierNetworkChange: CallbackEvent.OnCarrierNetworkChange? = null,
+    val onCarrierRoamingNtnModeChanged: CallbackEvent.OnCarrierRoamingNtnModeChanged? = null,
     val onDataConnectionStateChanged: CallbackEvent.OnDataConnectionStateChanged? = null,
     val onDataEnabledChanged: CallbackEvent.OnDataEnabledChanged? = null,
     val onDisplayInfoChanged: CallbackEvent.OnDisplayInfoChanged? = null,
@@ -531,6 +541,9 @@
     fun applyEvent(event: CallbackEvent): TelephonyCallbackState {
         return when (event) {
             is CallbackEvent.OnCarrierNetworkChange -> copy(onCarrierNetworkChange = event)
+            is CallbackEvent.OnCarrierRoamingNtnModeChanged -> {
+                copy(onCarrierRoamingNtnModeChanged = event)
+            }
             is CallbackEvent.OnDataActivity -> copy(onDataActivity = event)
             is CallbackEvent.OnDataConnectionStateChanged ->
                 copy(onDataConnectionStateChanged = event)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
index db4e605d..08f973b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
@@ -88,6 +88,7 @@
         const val WORK_MODE_TILE_SPEC = "work"
         const val CAMERA_TOGGLE_TILE_SPEC = "cameratoggle"
         const val MIC_TOGGLE_TILE_SPEC = "mictoggle"
+        const val DND_TILE_SPEC = "dnd"
 
         /** Inject flashlight config */
         @Provides
@@ -136,10 +137,7 @@
                 instanceId = uiEventLogger.getNewInstanceId(),
                 policy =
                     QSTilePolicy.Restricted(
-                        listOf(
-                            DISALLOW_SHARE_LOCATION,
-                            DISALLOW_CONFIG_LOCATION
-                        )
+                        listOf(DISALLOW_SHARE_LOCATION, DISALLOW_CONFIG_LOCATION)
                     )
             )
 
@@ -321,6 +319,21 @@
                 stateInteractor.create(MICROPHONE),
                 mapper.create(SensorPrivacyTileResources.MicrophonePrivacyTileResources),
             )
+
+        /** Inject microphone toggle config */
+        @Provides
+        @IntoMap
+        @StringKey(DND_TILE_SPEC)
+        fun provideDndTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+            QSTileConfig(
+                tileSpec = TileSpec.create(DND_TILE_SPEC),
+                uiConfig =
+                    QSTileUIConfig.Resource(
+                        iconRes = R.drawable.qs_dnd_icon_off,
+                        labelRes = R.string.quick_settings_dnd_label,
+                    ),
+                instanceId = uiEventLogger.getNewInstanceId(),
+            )
     }
 
     /** Inject FlashlightTile into tileMap in QSModule */
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java b/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
index d37dfb4..3c9259c 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
@@ -51,7 +51,7 @@
     private Bitmap mMiniBitmap;
 
     @VisibleForTesting
-    static final int SMALL_SIDE = 128;
+    static final int MINI_BITMAP_MAX_AREA = 112 * 112;
 
     private static final String TAG = WallpaperLocalColorExtractor.class.getSimpleName();
     private static final @NonNull RectF LOCAL_COLOR_BOUNDS =
@@ -326,12 +326,12 @@
 
     private Bitmap createMiniBitmap(@NonNull Bitmap bitmap) {
         Trace.beginSection("WallpaperLocalColorExtractor#createMiniBitmap");
-        // if both sides of the image are larger than SMALL_SIDE, downscale the bitmap.
-        int smallestSide = Math.min(bitmap.getWidth(), bitmap.getHeight());
-        float scale = Math.min(1.0f, (float) SMALL_SIDE / smallestSide);
+        // if the area of the image is greater than MINI_BITMAP_MAX_AREA, downscale the bitmap.
+        int area = bitmap.getWidth() * bitmap.getHeight();
+        double scale = Math.min(1, Math.sqrt((double) MINI_BITMAP_MAX_AREA / area));
         Bitmap result = createMiniBitmap(bitmap,
-                (int) (scale * bitmap.getWidth()),
-                (int) (scale * bitmap.getHeight()));
+                Math.max(1, (int) (scale * bitmap.getWidth())),
+                Math.max(1, (int) (scale * bitmap.getHeight())));
         Trace.endSection();
         return result;
     }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index d354fa2..d6f0ef8 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -19,6 +19,7 @@
 import static android.app.StatusBarManager.SESSION_KEYGUARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT;
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
 import static android.hardware.biometrics.SensorProperties.STRENGTH_CONVENIENCE;
@@ -82,7 +83,6 @@
 import android.hardware.biometrics.BiometricSourceType;
 import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
-import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintSensorProperties;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
@@ -2276,8 +2276,7 @@
     private void faceAuthLockOut() {
         when(mFaceAuthInteractor.isLockedOut()).thenReturn(true);
         mFaceAuthenticationListener.getValue().onAuthenticationStatusChanged(
-                new ErrorFaceAuthenticationStatus(FaceManager.FACE_ERROR_LOCKOUT_PERMANENT, "",
-                        0L));
+                new ErrorFaceAuthenticationStatus(FACE_ERROR_LOCKOUT_PERMANENT, "", 0L));
     }
 
     private void statusBarShadeIsNotLocked() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
index 1e3b556..d01d57e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
@@ -24,26 +24,35 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.hardware.display.DisplayManager;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.testing.AndroidTestingRunner;
-import android.util.Pair;
+import android.testing.TestableLooper;
 import android.view.GestureDetector;
 import android.view.IWindowManager;
 import android.view.InputEvent;
 import android.view.MotionEvent;
+import android.view.WindowManager;
+import android.view.WindowMetrics;
 
-import androidx.lifecycle.DefaultLifecycleObserver;
+import androidx.annotation.NonNull;
 import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleObserver;
 import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LifecycleRegistry;
 import androidx.test.filters.SmallTest;
 
+import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.ambient.touch.dagger.InputSessionComponent;
+import com.android.systemui.kosmos.KosmosJavaAdapter;
 import com.android.systemui.shared.system.InputChannelCompat;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.display.DisplayHelper;
@@ -67,31 +76,58 @@
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class TouchMonitorTest extends SysuiTestCase {
+    private KosmosJavaAdapter mKosmos;
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
+        mKosmos = new KosmosJavaAdapter(this);
+    }
+
+    private static class SimpleLifecycleOwner implements LifecycleOwner {
+        LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
+        @NonNull
+        @Override
+        public Lifecycle getLifecycle() {
+            return mLifecycle;
+        }
+
+        public void setState(Lifecycle.State state) {
+            mLifecycle.setCurrentState(state);
+        }
     }
 
     private static class Environment {
         private final InputSessionComponent.Factory mInputFactory;
         private final InputSession mInputSession;
-        private final Lifecycle mLifecycle;
-        private final LifecycleOwner mLifecycleOwner;
+        private final SimpleLifecycleOwner mLifecycleOwner;
+
+        private final LifecycleRegistry mLifecycleRegistry;
         private final TouchMonitor mMonitor;
-        private final DefaultLifecycleObserver mLifecycleObserver;
         private final InputChannelCompat.InputEventListener mEventListener;
         private final GestureDetector.OnGestureListener mGestureListener;
         private final DisplayHelper mDisplayHelper;
+        private final DisplayManager mDisplayManager;
+        private final WindowManager mWindowManager;
+        private final WindowMetrics mWindowMetrics;
         private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
         private final FakeExecutor mBackgroundExecutor = new FakeExecutor(new FakeSystemClock());
+
         private final Rect mDisplayBounds = Mockito.mock(Rect.class);
         private final IWindowManager mIWindowManager;
 
-        Environment(Set<TouchHandler> handlers) {
-            mLifecycle = Mockito.mock(Lifecycle.class);
-            mLifecycleOwner = Mockito.mock(LifecycleOwner.class);
+        private final KosmosJavaAdapter mKosmos;
+
+
+        Environment(Set<TouchHandler> handlers, KosmosJavaAdapter kosmos) {
+            mLifecycleOwner = new SimpleLifecycleOwner();
+            mLifecycleRegistry = spy(new LifecycleRegistry(mLifecycleOwner));
+
             mIWindowManager = Mockito.mock(IWindowManager.class);
+            mDisplayManager = Mockito.mock(DisplayManager.class);
+            mWindowManager = Mockito.mock(WindowManager.class);
+            mKosmos = kosmos;
 
             mInputFactory = Mockito.mock(InputSessionComponent.Factory.class);
             final InputSessionComponent inputComponent = Mockito.mock(InputSessionComponent.class);
@@ -104,18 +140,16 @@
             mDisplayHelper = Mockito.mock(DisplayHelper.class);
             when(mDisplayHelper.getMaxBounds(anyInt(), anyInt()))
                     .thenReturn(mDisplayBounds);
-            mMonitor = new TouchMonitor(mExecutor, mBackgroundExecutor,
-                    mLifecycle, mInputFactory, mDisplayHelper, handlers, mIWindowManager, 0);
+
+            mWindowMetrics = Mockito.mock(WindowMetrics.class);
+            when(mWindowMetrics.getBounds()).thenReturn(mDisplayBounds);
+            when(mWindowManager.getMaximumWindowMetrics()).thenReturn(mWindowMetrics);
+            mMonitor = new TouchMonitor(mExecutor, mBackgroundExecutor, mLifecycleRegistry,
+                    mInputFactory, mDisplayHelper, mKosmos.getConfigurationInteractor(),
+                    handlers, mIWindowManager,  0);
             mMonitor.init();
 
-            final ArgumentCaptor<LifecycleObserver> lifecycleObserverCaptor =
-                    ArgumentCaptor.forClass(LifecycleObserver.class);
-            verify(mLifecycle).addObserver(lifecycleObserverCaptor.capture());
-            assertThat(lifecycleObserverCaptor.getValue() instanceof DefaultLifecycleObserver)
-                    .isTrue();
-            mLifecycleObserver = (DefaultLifecycleObserver) lifecycleObserverCaptor.getValue();
-
-            updateLifecycle(observer -> observer.first.onResume(observer.second));
+            updateLifecycle(Lifecycle.State.RESUMED);
 
             // Capture creation request.
             final ArgumentCaptor<InputChannelCompat.InputEventListener> inputEventListenerCaptor =
@@ -145,8 +179,8 @@
             listenerConsumer.accept(mGestureListener);
         }
 
-        void updateLifecycle(Consumer<Pair<DefaultLifecycleObserver, LifecycleOwner>> consumer) {
-            consumer.accept(Pair.create(mLifecycleObserver, mLifecycleOwner));
+        void updateLifecycle(Lifecycle.State state) {
+            mLifecycleRegistry.setCurrentState(state);
         }
 
         void verifyInputSessionDispose() {
@@ -156,10 +190,33 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_AMBIENT_TOUCH_MONITOR_LISTEN_TO_DISPLAY_CHANGES)
+    public void testConfigurationListenerUpdatesBounds() {
+        final TouchHandler touchHandler = createTouchHandler();
+        final Environment environment = new Environment(Stream.of(touchHandler)
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
+        ArgumentCaptor<DisplayManager.DisplayListener> listenerCaptor =
+                ArgumentCaptor.forClass(DisplayManager.DisplayListener.class);
+        final Rect testRect = new Rect(0, 0, 2, 2);
+        final Configuration configuration = new Configuration();
+        configuration.windowConfiguration.setMaxBounds(testRect);
+
+        mKosmos.getConfigurationRepository().onConfigurationChange(configuration);
+        final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
+        when(initialEvent.getX()).thenReturn(0.0f);
+        when(initialEvent.getY()).thenReturn(0.0f);
+        environment.publishInputEvent(initialEvent);
+
+        // Verify display bounds passed into TouchHandler#getTouchInitiationRegion
+        verify(touchHandler).getTouchInitiationRegion(eq(testRect), any(), any());
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_AMBIENT_TOUCH_MONITOR_LISTEN_TO_DISPLAY_CHANGES)
     public void testReportedDisplayBounds() {
         final TouchHandler touchHandler = createTouchHandler();
         final Environment environment = new Environment(Stream.of(touchHandler)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
         final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
         when(initialEvent.getX()).thenReturn(0.0f);
@@ -190,7 +247,7 @@
         }).when(touchHandler).getTouchInitiationRegion(any(), any(), any());
 
         final Environment environment = new Environment(Stream.of(touchHandler)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
         // Ensure touch outside specified region is not delivered.
         final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
@@ -219,7 +276,7 @@
         }).when(touchHandler).getTouchInitiationRegion(any(), any(), any());
 
         final Environment environment = new Environment(Stream.of(touchHandler, unzonedTouchHandler)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
         // Ensure touch outside specified region is delivered to unzoned touch handler.
         final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
@@ -261,7 +318,7 @@
         when(touchHandler.isEnabled()).thenReturn(false);
 
         final Environment environment = new Environment(Stream.of(touchHandler)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
         final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
         when(initialEvent.getX()).thenReturn(5.0f);
         when(initialEvent.getY()).thenReturn(5.0f);
@@ -277,7 +334,7 @@
         final TouchHandler touchHandler = createTouchHandler();
 
         final Environment environment = new Environment(Stream.of(touchHandler)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
         final InputEvent initialEvent = Mockito.mock(InputEvent.class);
         environment.publishInputEvent(initialEvent);
@@ -297,7 +354,7 @@
         final TouchHandler touchHandler = createTouchHandler();
 
         final Environment environment = new Environment(Stream.of(touchHandler)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
         final InputEvent initialEvent = Mockito.mock(InputEvent.class);
         environment.publishInputEvent(initialEvent);
@@ -321,7 +378,7 @@
         final TouchHandler touchHandler = createTouchHandler();
 
         final Environment environment = new Environment(Stream.of(touchHandler)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
         final InputEvent initialEvent = Mockito.mock(InputEvent.class);
         environment.publishInputEvent(initialEvent);
@@ -340,7 +397,7 @@
         final TouchHandler touchHandler = createTouchHandler();
 
         final Environment environment = new Environment(Stream.of(touchHandler)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
         final InputEvent initialEvent = Mockito.mock(InputEvent.class);
         environment.publishInputEvent(initialEvent);
@@ -365,7 +422,7 @@
         when(touchHandler2.isEnabled()).thenReturn(true);
 
         final Environment environment = new Environment(Stream.of(touchHandler, touchHandler2)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
         final InputEvent initialEvent = Mockito.mock(InputEvent.class);
         environment.publishInputEvent(initialEvent);
@@ -389,7 +446,7 @@
         final TouchHandler touchHandler = createTouchHandler();
 
         final Environment environment = new Environment(Stream.of(touchHandler)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
         final InputEvent initialEvent = Mockito.mock(InputEvent.class);
         environment.publishInputEvent(initialEvent);
@@ -435,7 +492,7 @@
                 Mockito.mock(TouchHandler.TouchSession.Callback.class);
 
         final Environment environment = new Environment(Stream.of(touchHandler)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
         final InputEvent initialEvent = Mockito.mock(InputEvent.class);
         environment.publishInputEvent(initialEvent);
@@ -453,11 +510,9 @@
         final TouchHandler touchHandler = createTouchHandler();
 
         final Environment environment = new Environment(Stream.of(touchHandler)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
-        environment.updateLifecycle(observerOwnerPair -> {
-            observerOwnerPair.first.onPause(observerOwnerPair.second);
-        });
+        environment.updateLifecycle(Lifecycle.State.STARTED);
 
         environment.verifyInputSessionDispose();
     }
@@ -467,7 +522,7 @@
         final TouchHandler touchHandler = createTouchHandler();
 
         final Environment environment = new Environment(Stream.of(touchHandler)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
         final InputEvent initialEvent = Mockito.mock(InputEvent.class);
         environment.publishInputEvent(initialEvent);
@@ -486,9 +541,7 @@
 
         verify(touchHandler).onSessionStart(touchSessionArgumentCaptor.capture());
 
-        environment.updateLifecycle(observerOwnerPair -> {
-            observerOwnerPair.first.onPause(observerOwnerPair.second);
-        });
+        environment.updateLifecycle(Lifecycle.State.STARTED);
 
         verify(environment.mInputSession, never()).dispose();
 
@@ -505,7 +558,7 @@
         final TouchHandler touchHandler = createTouchHandler();
 
         final Environment environment = new Environment(Stream.of(touchHandler)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
         final InputEvent initialEvent = Mockito.mock(InputEvent.class);
         environment.publishInputEvent(initialEvent);
@@ -524,9 +577,7 @@
 
         verify(touchHandler).onSessionStart(touchSessionArgumentCaptor.capture());
 
-        environment.updateLifecycle(observerOwnerPair -> {
-            observerOwnerPair.first.onDestroy(observerOwnerPair.second);
-        });
+        environment.updateLifecycle(Lifecycle.State.DESTROYED);
 
         // Check to make sure the input session is now disposed.
         environment.verifyInputSessionDispose();
@@ -538,7 +589,7 @@
         final TouchHandler touchHandler1 = createTouchHandler();
         final TouchHandler touchHandler2 = createTouchHandler();
         final Environment environment = new Environment(Stream.of(touchHandler1, touchHandler2)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
         final InputEvent initialEvent = Mockito.mock(InputEvent.class);
         environment.publishInputEvent(initialEvent);
@@ -574,7 +625,7 @@
                 Mockito.mock(TouchHandler.TouchSession.Callback.class);
 
         final Environment environment = new Environment(Stream.of(touchHandler)
-                .collect(Collectors.toCollection(HashSet::new)));
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
 
         final InputEvent initialEvent = Mockito.mock(InputEvent.class);
         environment.publishInputEvent(initialEvent);
@@ -584,9 +635,7 @@
 
         environment.executeAll();
 
-        environment.updateLifecycle(observerOwnerPair -> {
-            observerOwnerPair.first.onDestroy(observerOwnerPair.second);
-        });
+        environment.updateLifecycle(Lifecycle.State.DESTROYED);
 
         environment.executeAll();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorTest.kt
index 9e007e9..63b4ff7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorTest.kt
@@ -91,7 +91,7 @@
     @Test
     fun maxBoundsChange_emitsMaxBoundsChange() =
         testScope.runTest {
-            val values by collectValues(underTest.naturalMaxBounds)
+            val values by collectValues(underTest.maxBounds)
 
             updateDisplay(width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT)
             runCurrent()
@@ -109,7 +109,7 @@
     @Test
     fun maxBoundsSameOnConfigChange_doesNotEmitMaxBoundsChange() =
         testScope.runTest {
-            val values by collectValues(underTest.naturalMaxBounds)
+            val values by collectValues(underTest.maxBounds)
 
             updateDisplay(width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT)
             runCurrent()
@@ -122,6 +122,48 @@
     @Test
     fun firstMaxBoundsChange_emitsMaxBoundsChange() =
         testScope.runTest {
+            val values by collectValues(underTest.maxBounds)
+
+            updateDisplay(width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT)
+            runCurrent()
+
+            assertThat(values).containsExactly(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT))
+        }
+
+    @Test
+    fun maxBoundsChange_emitsNaturalMaxBoundsChange() =
+        testScope.runTest {
+            val values by collectValues(underTest.naturalMaxBounds)
+
+            updateDisplay(width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT)
+            runCurrent()
+            updateDisplay(width = DISPLAY_WIDTH * 2, height = DISPLAY_HEIGHT * 3)
+            runCurrent()
+
+            assertThat(values)
+                .containsExactly(
+                    Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT),
+                    Rect(0, 0, DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 3),
+                )
+                .inOrder()
+        }
+
+    @Test
+    fun maxBoundsSameOnConfigChange_doesNotEmitNaturalMaxBoundsChange() =
+        testScope.runTest {
+            val values by collectValues(underTest.naturalMaxBounds)
+
+            updateDisplay(width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT)
+            runCurrent()
+            updateDisplay(width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT)
+            runCurrent()
+
+            assertThat(values).containsExactly(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT))
+        }
+
+    @Test
+    fun firstMaxBoundsChange_emitsNaturalMaxBoundsChange() =
+        testScope.runTest {
             val values by collectValues(underTest.naturalMaxBounds)
 
             updateDisplay(width = DISPLAY_WIDTH, height = DISPLAY_HEIGHT)
@@ -131,7 +173,7 @@
         }
 
     @Test
-    fun displayRotatedButMaxBoundsTheSame_doesNotEmitNewMaxBoundsChange() =
+    fun displayRotatedButMaxBoundsTheSame_doesNotEmitNewNaturalMaxBoundsChange() =
         testScope.runTest {
             val values by collectValues(underTest.naturalMaxBounds)
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt
index 5581f0c..431fef6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt
@@ -17,7 +17,9 @@
 package com.android.systemui.deviceentry.domain.interactor
 
 import android.content.res.mainResources
-import android.hardware.face.FaceManager
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGHT
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT
 import android.hardware.fingerprint.FingerprintManager
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -266,7 +268,7 @@
             faceAuthRepository.setAuthenticationStatus(
                 HelpFaceAuthenticationStatus(
                     msg = "Move left",
-                    msgId = FaceManager.FACE_ACQUIRED_TOO_RIGHT,
+                    msgId = FACE_ACQUIRED_TOO_RIGHT,
                 )
             )
 
@@ -293,7 +295,7 @@
             faceAuthRepository.setAuthenticationStatus(
                 HelpFaceAuthenticationStatus(
                     msg = "Move left",
-                    msgId = FaceManager.FACE_ACQUIRED_TOO_RIGHT,
+                    msgId = FACE_ACQUIRED_TOO_RIGHT,
                 )
             )
 
@@ -318,7 +320,7 @@
             faceAuthRepository.setAuthenticationStatus(
                 HelpFaceAuthenticationStatus(
                     msg = "Move left",
-                    msgId = FaceManager.FACE_ACQUIRED_TOO_RIGHT,
+                    msgId = FACE_ACQUIRED_TOO_RIGHT,
                 )
             )
 
@@ -333,10 +335,7 @@
 
             // WHEN authentication status error is FACE_ERROR_HW_UNAVAILABLE
             faceAuthRepository.setAuthenticationStatus(
-                ErrorFaceAuthenticationStatus(
-                    msgId = FaceManager.FACE_ERROR_HW_UNAVAILABLE,
-                    msg = "test"
-                )
+                ErrorFaceAuthenticationStatus(msgId = FACE_ERROR_HW_UNAVAILABLE, msg = "test")
             )
 
             // THEN faceErrorMessage isn't updated - it's still null since it was suppressed
@@ -350,10 +349,7 @@
 
             // WHEN authentication status error is FACE_ERROR_HW_UNAVAILABLE
             faceAuthRepository.setAuthenticationStatus(
-                ErrorFaceAuthenticationStatus(
-                    msgId = FaceManager.FACE_ERROR_HW_UNAVAILABLE,
-                    msg = "test"
-                )
+                ErrorFaceAuthenticationStatus(msgId = FACE_ERROR_HW_UNAVAILABLE, msg = "test")
             )
 
             // GIVEN face is allowed
@@ -370,7 +366,7 @@
 
             // WHEN authentication status error is FACE_ERROR_TIMEOUT
             faceAuthRepository.setAuthenticationStatus(
-                ErrorFaceAuthenticationStatus(msgId = FaceManager.FACE_ERROR_TIMEOUT, msg = "test")
+                ErrorFaceAuthenticationStatus(msgId = FACE_ERROR_TIMEOUT, msg = "test")
             )
 
             // GIVEN face is allowed
@@ -389,7 +385,7 @@
 
             // WHEN authentication status error is FACE_ERROR_TIMEOUT
             faceAuthRepository.setAuthenticationStatus(
-                ErrorFaceAuthenticationStatus(msgId = FaceManager.FACE_ERROR_TIMEOUT, msg = "test")
+                ErrorFaceAuthenticationStatus(msgId = FACE_ERROR_TIMEOUT, msg = "test")
             )
 
             // GIVEN face is allowed
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
index b3cfcf2..857af66 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
@@ -27,6 +27,7 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.media.controls.MediaTestUtils
 import com.android.systemui.media.controls.data.repository.MediaFilterRepository
+import com.android.systemui.media.controls.data.repository.mediaFilterRepository
 import com.android.systemui.media.controls.shared.model.EXTRA_KEY_TRIGGER_RESUME
 import com.android.systemui.media.controls.shared.model.MediaCommonModel
 import com.android.systemui.media.controls.shared.model.MediaData
@@ -38,6 +39,7 @@
 import com.android.systemui.media.controls.util.MediaUiEventLogger
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
@@ -77,6 +79,7 @@
 @RunWith(AndroidTestingRunner::class)
 @TestableLooper.RunWithLooper
 class MediaDataFilterImplTest : SysuiTestCase() {
+    val kosmos = testKosmos()
 
     @Mock private lateinit var listener: MediaDataProcessor.Listener
     @Mock private lateinit var userTracker: UserTracker
@@ -91,12 +94,12 @@
     @Mock private lateinit var cardAction: SmartspaceAction
 
     private lateinit var mediaDataFilter: MediaDataFilterImpl
-    private lateinit var repository: MediaFilterRepository
     private lateinit var testScope: TestScope
     private lateinit var dataMain: MediaData
     private lateinit var dataGuest: MediaData
     private lateinit var dataPrivateProfile: MediaData
     private val clock = FakeSystemClock()
+    private val repository: MediaFilterRepository = kosmos.mediaFilterRepository
 
     @Before
     fun setup() {
@@ -104,7 +107,6 @@
         MediaPlayerData.clear()
         whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(false)
         testScope = TestScope()
-        repository = MediaFilterRepository(FakeSystemClock())
         mediaDataFilter =
             MediaDataFilterImpl(
                 context,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
index ffb50c1..1de7ee3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
@@ -54,6 +54,7 @@
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.media.controls.data.repository.MediaDataRepository
 import com.android.systemui.media.controls.data.repository.MediaFilterRepository
+import com.android.systemui.media.controls.data.repository.mediaFilterRepository
 import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
 import com.android.systemui.media.controls.domain.resume.MediaResumeListener
 import com.android.systemui.media.controls.domain.resume.ResumeMediaBrowser
@@ -68,6 +69,7 @@
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.SbnBuilder
+import com.android.systemui.testKosmos
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.capture
@@ -125,6 +127,7 @@
 @RunWithLooper(setAsMainLooper = true)
 @RunWith(AndroidTestingRunner::class)
 class MediaDataProcessorTest : SysuiTestCase() {
+    val kosmos = testKosmos()
 
     @JvmField @Rule val mockito = MockitoJUnit.rule()
     @Mock lateinit var mediaControllerFactory: MediaControllerFactory
@@ -168,7 +171,6 @@
     @Mock private lateinit var ugm: IUriGrantsManager
     @Mock private lateinit var imageSource: ImageDecoder.Source
     private lateinit var mediaDataRepository: MediaDataRepository
-    private lateinit var mediaFilterRepository: MediaFilterRepository
     private lateinit var testScope: TestScope
     private lateinit var testDispatcher: TestDispatcher
     private lateinit var testableLooper: TestableLooper
@@ -183,6 +185,7 @@
             Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION,
             1
         )
+    private val mediaFilterRepository: MediaFilterRepository = kosmos.mediaFilterRepository
 
     private lateinit var staticMockSession: MockitoSession
 
@@ -210,7 +213,6 @@
         )
         testDispatcher = UnconfinedTestDispatcher()
         testScope = TestScope(testDispatcher)
-        mediaFilterRepository = MediaFilterRepository(clock)
         mediaDataRepository = MediaDataRepository(mediaFlags, dumpManager)
         mediaDataProcessor =
             MediaDataProcessor(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
index c3daf84..0a5aace 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
@@ -36,6 +36,7 @@
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.media.controls.MediaTestUtils
 import com.android.systemui.media.controls.domain.pipeline.EMPTY_SMARTSPACE_MEDIA_DATA
@@ -44,6 +45,7 @@
 import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QS
 import com.android.systemui.media.controls.ui.view.MediaHostState
 import com.android.systemui.media.controls.ui.view.MediaScrollView
+import com.android.systemui.media.controls.ui.viewmodel.mediaCarouselViewModel
 import com.android.systemui.media.controls.util.MediaFlags
 import com.android.systemui.media.controls.util.MediaUiEventLogger
 import com.android.systemui.plugins.ActivityStarter
@@ -100,6 +102,7 @@
     val kosmos = testKosmos()
 
     @Mock lateinit var mediaControlPanelFactory: Provider<MediaControlPanel>
+    @Mock lateinit var mediaViewControllerFactory: Provider<MediaViewController>
     @Mock lateinit var panel: MediaControlPanel
     @Mock lateinit var visualStabilityProvider: VisualStabilityProvider
     @Mock lateinit var mediaHostStatesManager: MediaHostStatesManager
@@ -148,6 +151,7 @@
                 mediaHostStatesManager,
                 activityStarter,
                 clock,
+                kosmos.testDispatcher,
                 executor,
                 bgExecutor,
                 testDispatcher,
@@ -162,6 +166,8 @@
                 kosmos.keyguardTransitionInteractor,
                 globalSettings,
                 secureSettings,
+                kosmos.mediaCarouselViewModel,
+                mediaViewControllerFactory,
             )
         verify(configurationController).addCallback(capture(configListener))
         verify(mediaDataManager).addListener(capture(listener))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt
index cb4ab64..e1c2d3f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt
@@ -29,12 +29,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.Classifier
-import com.android.systemui.kosmos.applicationCoroutineScope
-import com.android.systemui.kosmos.testDispatcher
-import com.android.systemui.media.controls.util.MediaFlags
-import com.android.systemui.media.controls.util.mediaFlags
 import com.android.systemui.plugins.FalsingManager
-import com.android.systemui.testKosmos
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.concurrency.FakeRepeatableExecutor
 import com.android.systemui.util.time.FakeSystemClock
@@ -61,7 +56,6 @@
 @RunWith(AndroidTestingRunner::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class SeekBarViewModelTest : SysuiTestCase() {
-    val kosmos = testKosmos()
 
     private lateinit var viewModel: SeekBarViewModel
     private lateinit var fakeExecutor: FakeExecutor
@@ -81,7 +75,6 @@
     @Mock private lateinit var mockTransport: MediaController.TransportControls
     @Mock private lateinit var falsingManager: FalsingManager
     @Mock private lateinit var mockBar: SeekBar
-    @Mock private lateinit var mediaFlags: MediaFlags
     private val token1 = MediaSession.Token(1, null)
     private val token2 = MediaSession.Token(2, null)
 
@@ -90,18 +83,10 @@
     @Before
     fun setUp() {
         fakeExecutor = FakeExecutor(FakeSystemClock())
-        viewModel =
-            SeekBarViewModel(
-                kosmos.applicationCoroutineScope,
-                kosmos.testDispatcher,
-                FakeRepeatableExecutor(fakeExecutor),
-                falsingManager,
-                mediaFlags,
-            )
+        viewModel = SeekBarViewModel(FakeRepeatableExecutor(fakeExecutor), falsingManager)
         viewModel.logSeek = {}
         whenever(mockController.sessionToken).thenReturn(token1)
         whenever(mockBar.context).thenReturn(context)
-        whenever(mediaFlags.isMediaControlsRefactorEnabled()).thenReturn(false)
 
         // LiveData to run synchronously
         ArchTaskExecutor.getInstance().setDelegate(taskExecutor)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
index 7b5c1d3..19b137c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
@@ -18,7 +18,7 @@
 
 import android.graphics.Rect
 import android.os.PowerManager
-import android.testing.AndroidTestingRunner
+import android.platform.test.flag.junit.FlagsParameterization
 import android.testing.TestableLooper
 import android.testing.ViewUtils
 import android.view.MotionEvent
@@ -41,6 +41,7 @@
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
 import com.android.systemui.communal.util.CommunalColors
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.andSceneContainer
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
@@ -49,8 +50,10 @@
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.sceneDataSourceDelegator
-import com.android.systemui.shade.data.repository.fakeShadeRepository
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.statusbar.phone.SystemUIDialogFactory
 import com.android.systemui.testKosmos
@@ -69,12 +72,14 @@
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
 @ExperimentalCoroutinesApi
-@RunWith(AndroidTestingRunner::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
-class GlanceableHubContainerControllerTest : SysuiTestCase() {
+class GlanceableHubContainerControllerTest(flags: FlagsParameterization?) : SysuiTestCase() {
     private val kosmos: Kosmos =
         testKosmos().apply {
             // UnconfinedTestDispatcher makes testing simpler due to CommunalInteractor flows using
@@ -96,6 +101,10 @@
     private lateinit var communalRepository: FakeCommunalRepository
     private lateinit var underTest: GlanceableHubContainerController
 
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags!!)
+    }
+
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
@@ -251,7 +260,7 @@
                 goToScene(CommunalScenes.Communal)
 
                 // Shade shows up.
-                fakeShadeRepository.setQsExpansion(1.0f)
+                shadeTestUtil.setQsExpansion(1.0f)
                 testableLooper.processAllMessages()
 
                 // Touch events are not intercepted.
@@ -405,7 +414,7 @@
                 goToScene(CommunalScenes.Communal)
 
                 // Shade shows up.
-                fakeShadeRepository.setQsExpansion(1.0f)
+                shadeTestUtil.setQsExpansion(1.0f)
                 testableLooper.processAllMessages()
 
                 assertThat(underTest.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
@@ -458,6 +467,13 @@
     }
 
     private fun goToScene(scene: SceneKey) {
+        if (SceneContainerFlag.isEnabled) {
+            if (scene == CommunalScenes.Communal) {
+                kosmos.sceneInteractor.changeScene(Scenes.Communal, "test")
+            } else {
+                kosmos.sceneInteractor.changeScene(Scenes.Lockscreen, "test")
+            }
+        }
         communalRepository.changeScene(scene)
         testableLooper.processAllMessages()
     }
@@ -486,5 +502,11 @@
             MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, CONTAINER_WIDTH.toFloat(), 0f, 0)
         private val MOVE_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
         private val UP_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0)
+
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return FlagsParameterization.allCombinationsOf().andSceneContainer()
+        }
     }
 }
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 d95cc2e..112829a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@
 package com.android.systemui.shade
 
 import android.content.Context
-import android.testing.AndroidTestingRunner
+import android.platform.test.flag.junit.FlagsParameterization
 import android.testing.TestableLooper.RunWithLooper
 import android.view.KeyEvent
 import android.view.MotionEvent
@@ -35,9 +35,11 @@
 import com.android.systemui.classifier.FalsingCollectorFake
 import com.android.systemui.dock.DockManager
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.DisableSceneContainer
 import com.android.systemui.flags.FakeFeatureFlagsClassic
 import com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED
 import com.android.systemui.flags.Flags.SPLIT_SHADE_SUBPIXEL_OPTIMIZATION
+import com.android.systemui.flags.andSceneContainer
 import com.android.systemui.keyevent.domain.interactor.SysUIKeyEventHandler
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -45,6 +47,7 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.res.R
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
 import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
 import com.android.systemui.statusbar.DragDownHelper
@@ -69,11 +72,13 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
+import java.util.Optional
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
+import org.junit.Assert.assertEquals
 import org.junit.Before
 import org.junit.Ignore
 import org.junit.Test
@@ -86,15 +91,15 @@
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
-import kotlin.test.assertEquals
-import java.util.Optional
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 import org.mockito.Mockito.`when` as whenever
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 @RunWithLooper(setAsMainLooper = true)
-class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
+class NotificationShadeWindowViewControllerTest(flags: FlagsParameterization?) : SysuiTestCase() {
 
     @Mock private lateinit var view: NotificationShadeWindowView
     @Mock private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController
@@ -128,7 +133,7 @@
     @Mock lateinit var keyguardSecurityContainerController: KeyguardSecurityContainerController
     @Mock
     private lateinit var unfoldTransitionProgressProvider:
-        Optional<UnfoldTransitionProgressProvider>
+            Optional<UnfoldTransitionProgressProvider>
     @Mock lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
     @Mock lateinit var dragDownHelper: DragDownHelper
     @Mock lateinit var mSelectedUserInteractor: SelectedUserInteractor
@@ -150,23 +155,29 @@
 
     private lateinit var featureFlagsClassic: FakeFeatureFlagsClassic
 
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags!!)
+    }
+
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
         whenever(view.bottom).thenReturn(VIEW_BOTTOM)
         whenever(view.findViewById<ViewGroup>(R.id.keyguard_bouncer_container))
-            .thenReturn(mock(ViewGroup::class.java))
+                .thenReturn(mock(ViewGroup::class.java))
         whenever(keyguardBouncerComponentFactory.create(any(ViewGroup::class.java)))
-            .thenReturn(keyguardBouncerComponent)
+                .thenReturn(keyguardBouncerComponent)
         whenever(keyguardBouncerComponent.securityContainerController)
-            .thenReturn(keyguardSecurityContainerController)
+                .thenReturn(keyguardSecurityContainerController)
         whenever(keyguardTransitionInteractor.transition(LOCKSCREEN, DREAMING))
-            .thenReturn(emptyFlow<TransitionStep>())
+                .thenReturn(emptyFlow<TransitionStep>())
 
         featureFlagsClassic = FakeFeatureFlagsClassic()
         featureFlagsClassic.set(SPLIT_SHADE_SUBPIXEL_OPTIMIZATION, true)
         featureFlagsClassic.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false)
-        mSetFlagsRule.disableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
+        if (!SceneContainerFlag.isEnabled) {
+            mSetFlagsRule.disableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
+        }
         mSetFlagsRule.enableFlags(Flags.FLAG_REVAMPED_BOUNCER_MESSAGES)
 
         testScope = TestScope()
@@ -269,7 +280,7 @@
             whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
             whenever(panelExpansionInteractor.isFullyCollapsed).thenReturn(true)
             whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
-                .thenReturn(true)
+                    .thenReturn(true)
             whenever(phoneStatusBarViewController.sendTouchToView(DOWN_EVENT)).thenReturn(true)
 
             val returnVal = interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)
@@ -284,7 +295,7 @@
             underTest.setStatusBarViewController(phoneStatusBarViewController)
             whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
             whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
-                .thenReturn(true)
+                    .thenReturn(true)
             // Item we're testing
             whenever(panelExpansionInteractor.isFullyCollapsed).thenReturn(false)
 
@@ -302,7 +313,7 @@
             whenever(panelExpansionInteractor.isFullyCollapsed).thenReturn(true)
             // Item we're testing
             whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
-                .thenReturn(false)
+                    .thenReturn(false)
 
             val returnVal = interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)
 
@@ -316,7 +327,7 @@
             underTest.setStatusBarViewController(phoneStatusBarViewController)
             whenever(panelExpansionInteractor.isFullyCollapsed).thenReturn(true)
             whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
-                .thenReturn(true)
+                    .thenReturn(true)
             // Item we're testing
             whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(false)
 
@@ -333,7 +344,7 @@
             whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
             whenever(panelExpansionInteractor.isFullyCollapsed).thenReturn(true)
             whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
-                .thenReturn(true)
+                    .thenReturn(true)
 
             // Down event first
             interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)
@@ -354,7 +365,7 @@
             // GIVEN touch dispatcher in a state that returns true
             underTest.setStatusBarViewController(phoneStatusBarViewController)
             whenever(keyguardUnlockAnimationController.isPlayingCannedUnlockAnimation())
-                .thenReturn(true)
+                    .thenReturn(true)
             assertThat(interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)).isTrue()
 
             // WHEN launch animation is running for 2 seconds
@@ -375,6 +386,7 @@
         }
 
     @Test
+    @DisableSceneContainer
     fun handleDispatchTouchEvent_nsslMigrationOff_userActivity_not_called() {
         mSetFlagsRule.disableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
         underTest.setStatusBarViewController(phoneStatusBarViewController)
@@ -386,7 +398,7 @@
 
     @Test
     fun handleDispatchTouchEvent_nsslMigrationOn_userActivity() {
-        mSetFlagsRule.enableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
+        enableMigrateClocksFlag()
         underTest.setStatusBarViewController(phoneStatusBarViewController)
 
         interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)
@@ -408,7 +420,7 @@
     fun shouldInterceptTouchEvent_statusBarKeyguardViewManagerShouldIntercept() {
         // down event should be intercepted by keyguardViewManager
         whenever(statusBarKeyguardViewManager.shouldInterceptTouchEvent(DOWN_EVENT))
-            .thenReturn(true)
+                .thenReturn(true)
 
         // Then touch should not be intercepted
         val shouldIntercept = interactionEventHandler.shouldInterceptTouchEvent(DOWN_EVENT)
@@ -421,14 +433,14 @@
         whenever(sysuiStatusBarStateController.isDozing).thenReturn(true)
         // AND alternate bouncer doesn't want the touch
         whenever(statusBarKeyguardViewManager.shouldInterceptTouchEvent(DOWN_EVENT))
-            .thenReturn(false)
+                .thenReturn(false)
         // AND quick settings controller doesn't want it
         whenever(quickSettingsController.shouldQuickSettingsIntercept(any(), any(), any()))
-            .thenReturn(false)
+                .thenReturn(false)
         // AND the lock icon wants the touch
         whenever(lockIconViewController.willHandleTouchWhileDozing(DOWN_EVENT)).thenReturn(true)
 
-        mSetFlagsRule.enableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
+        enableMigrateClocksFlag()
 
         // THEN touch should NOT be intercepted by NotificationShade
         assertThat(interactionEventHandler.shouldInterceptTouchEvent(DOWN_EVENT)).isFalse()
@@ -440,14 +452,14 @@
         whenever(sysuiStatusBarStateController.isDozing).thenReturn(true)
         // AND alternate bouncer doesn't want the touch
         whenever(statusBarKeyguardViewManager.shouldInterceptTouchEvent(DOWN_EVENT))
-            .thenReturn(false)
+                .thenReturn(false)
         // AND the lock icon does NOT want the touch
         whenever(lockIconViewController.willHandleTouchWhileDozing(DOWN_EVENT)).thenReturn(false)
         // AND quick settings controller doesn't want it
         whenever(quickSettingsController.shouldQuickSettingsIntercept(any(), any(), any()))
-            .thenReturn(false)
+                .thenReturn(false)
 
-        mSetFlagsRule.enableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
+        enableMigrateClocksFlag()
 
         // THEN touch should be intercepted by NotificationShade
         assertThat(interactionEventHandler.shouldInterceptTouchEvent(DOWN_EVENT)).isTrue()
@@ -459,14 +471,14 @@
         whenever(sysuiStatusBarStateController.isDozing).thenReturn(true)
         // AND alternate bouncer doesn't want the touch
         whenever(statusBarKeyguardViewManager.shouldInterceptTouchEvent(DOWN_EVENT))
-            .thenReturn(false)
+                .thenReturn(false)
         // AND the lock icon does NOT want the touch
         whenever(lockIconViewController.willHandleTouchWhileDozing(DOWN_EVENT)).thenReturn(false)
         // AND quick settings controller DOES want it
         whenever(quickSettingsController.shouldQuickSettingsIntercept(any(), any(), any()))
-            .thenReturn(true)
+                .thenReturn(true)
 
-        mSetFlagsRule.enableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
+        enableMigrateClocksFlag()
 
         // THEN touch should be intercepted by NotificationShade
         assertThat(interactionEventHandler.shouldInterceptTouchEvent(DOWN_EVENT)).isTrue()
@@ -480,20 +492,20 @@
         whenever(dozeServiceHost.isPulsing()).thenReturn(true)
         // AND status bar doesn't want it
         whenever(statusBarKeyguardViewManager.shouldInterceptTouchEvent(DOWN_EVENT))
-            .thenReturn(false)
+                .thenReturn(false)
         // AND shade is not fully expanded (mock is false by default)
         // AND the lock icon does NOT want the touch
         whenever(lockIconViewController.willHandleTouchWhileDozing(DOWN_EVENT)).thenReturn(false)
         // AND quick settings controller DOES want it
         whenever(quickSettingsController.shouldQuickSettingsIntercept(any(), any(), any()))
-            .thenReturn(true)
+                .thenReturn(true)
         // AND bouncer is not showing
         whenever(centralSurfaces.isBouncerShowing()).thenReturn(false)
         // AND panel view controller wants it
         whenever(shadeViewController.handleExternalInterceptTouch(DOWN_EVENT))
-            .thenReturn(true)
+                .thenReturn(true)
 
-        mSetFlagsRule.enableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
+        enableMigrateClocksFlag()
 
         // THEN touch should be intercepted by NotificationShade
         assertThat(interactionEventHandler.shouldInterceptTouchEvent(DOWN_EVENT)).isTrue()
@@ -550,11 +562,11 @@
     @Ignore("b/321332798")
     fun setsUpCommunalHubLayout_whenFlagEnabled() {
         whenever(mGlanceableHubContainerController.communalAvailable())
-            .thenReturn(MutableStateFlow(true))
+                .thenReturn(MutableStateFlow(true))
 
         val mockCommunalView = mock(View::class.java)
         whenever(mGlanceableHubContainerController.initView(any<Context>()))
-            .thenReturn(mockCommunalView)
+                .thenReturn(mockCommunalView)
 
         val mockCommunalPlaceholder = mock(View::class.java)
         val fakeViewIndex = 20
@@ -572,7 +584,7 @@
     @Test
     fun doesNotSetupCommunalHubLayout_whenFlagDisabled() {
         whenever(mGlanceableHubContainerController.communalAvailable())
-            .thenReturn(MutableStateFlow(false))
+                .thenReturn(MutableStateFlow(false))
 
         val mockCommunalPlaceholder = mock(View::class.java)
         val fakeViewIndex = 20
@@ -616,15 +628,27 @@
 
     @Test
     fun cancelCurrentTouch_callsDragDownHelper() {
-        mSetFlagsRule.enableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
+        enableMigrateClocksFlag()
         underTest.cancelCurrentTouch()
 
         verify(dragDownHelper).stopDragging()
     }
 
+    private fun enableMigrateClocksFlag() {
+        if (!Flags.migrateClocksToBlueprint()) {
+            mSetFlagsRule.enableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
+        }
+    }
+
     companion object {
         private val DOWN_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
         private val MOVE_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
         private const val VIEW_BOTTOM = 100
+
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return FlagsParameterization.allCombinationsOf().andSceneContainer()
+        }
     }
 }
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 5abad61..63ce233 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
@@ -30,6 +30,7 @@
 import android.os.Bundle
 import android.os.Handler
 import android.os.UserHandle
+import android.platform.test.annotations.DisableFlags
 import android.provider.Settings
 import android.view.View
 import android.widget.FrameLayout
@@ -49,11 +50,14 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener
 import com.android.systemui.settings.UserTracker
+import com.android.systemui.smartspace.ui.viewmodel.SmartspaceViewModel
+import com.android.systemui.smartspace.viewmodel.smartspaceViewModelFactory
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener
+import com.android.systemui.testKosmos
 import com.android.systemui.util.concurrency.FakeExecution
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
@@ -182,6 +186,7 @@
     private lateinit var weatherSmartspaceView: SmartspaceView
     private lateinit var smartspaceView: SmartspaceView
     private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
+    private lateinit var smartspaceViewModelFactory: SmartspaceViewModel.Factory
 
     private val clock = FakeSystemClock()
     private val executor = FakeExecutor(clock)
@@ -234,6 +239,7 @@
             clock,
             dumpManager
         )
+        smartspaceViewModelFactory = testKosmos().smartspaceViewModelFactory
 
         controller = LockscreenSmartspaceController(
                 context,
@@ -251,6 +257,7 @@
                 keyguardBypassController,
                 keyguardUpdateMonitor,
                 wakefulnessLifecycle,
+                smartspaceViewModelFactory,
                 dumpManager,
                 execution,
                 executor,
@@ -785,6 +792,7 @@
     }
 
     @Test
+    @DisableFlags(com.android.systemui.Flags.FLAG_SMARTSPACE_LOCKSCREEN_VIEWMODEL)
     fun testWakefulnessLifecycleDispatch_wake_setsSmartspaceScreenOnTrue() {
         // Connect session
         connectSession()
@@ -801,6 +809,7 @@
     }
 
     @Test
+    @DisableFlags(com.android.systemui.Flags.FLAG_SMARTSPACE_LOCKSCREEN_VIEWMODEL)
     fun testWakefulnessLifecycleDispatch_sleep_setsSmartspaceScreenOnFalse() {
         // Connect session
         connectSession()
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 9d14116..3695d8c 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
@@ -35,6 +35,7 @@
 import android.telephony.SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX
 import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET
 import android.telephony.TelephonyCallback
+import android.telephony.TelephonyCallback.CarrierRoamingNtnModeListener
 import android.telephony.TelephonyCallback.DataActivityListener
 import android.telephony.TelephonyCallback.DisplayInfoListener
 import android.telephony.TelephonyCallback.ServiceStateListener
@@ -983,26 +984,19 @@
 
     @Test
     @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
-    fun isNonTerrestrial_updatesFromServiceState() =
+    fun isNonTerrestrial_updatesFromCallback0() =
         testScope.runTest {
             val latest by collectLastValue(underTest.isNonTerrestrial)
 
-            // Lambda makes it a little clearer what we are testing IMO
-            val serviceStateCreator = { ntn: Boolean ->
-                mock<ServiceState>().also {
-                    whenever(it.isUsingNonTerrestrialNetwork).thenReturn(ntn)
-                }
-            }
-
             // Starts out false
             assertThat(latest).isFalse()
 
-            getTelephonyCallbackForType<ServiceStateListener>()
-                .onServiceStateChanged(serviceStateCreator(true))
+            val callback = getTelephonyCallbackForType<CarrierRoamingNtnModeListener>()
+
+            callback.onCarrierRoamingNtnModeChanged(true)
             assertThat(latest).isTrue()
 
-            getTelephonyCallbackForType<ServiceStateListener>()
-                .onServiceStateChanged(serviceStateCreator(false))
+            callback.onCarrierRoamingNtnModeChanged(false)
             assertThat(latest).isFalse()
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectTest.kt
deleted file mode 100644
index b1df159..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/revealeffect/RippleRevealEffectTest.kt
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.surfaceeffects.revealeffect
-
-import android.graphics.RenderEffect
-import android.testing.AndroidTestingRunner
-import android.testing.TestableLooper
-import androidx.test.filters.SmallTest
-import com.android.systemui.animation.AnimatorTestRule
-import com.android.systemui.model.SysUiStateTest
-import com.android.systemui.surfaceeffects.RenderEffectDrawCallback
-import com.google.common.truth.Truth.assertThat
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-@TestableLooper.RunWithLooper(setAsMainLooper = true)
-class RippleRevealEffectTest : SysUiStateTest() {
-
-    @get:Rule val animatorTestRule = AnimatorTestRule(this)
-
-    @Test
-    fun play_triggersDrawCallback() {
-        var effectFromCallback: RenderEffect? = null
-        val revealEffectConfig = RippleRevealEffectConfig(duration = 1000f)
-        val drawCallback =
-            object : RenderEffectDrawCallback {
-                override fun onDraw(renderEffect: RenderEffect) {
-                    effectFromCallback = renderEffect
-                }
-            }
-        val revealEffect = RippleRevealEffect(revealEffectConfig, drawCallback)
-        assertThat(effectFromCallback).isNull()
-
-        revealEffect.play()
-
-        animatorTestRule.advanceTimeBy(500L)
-
-        assertThat(effectFromCallback).isNotNull()
-    }
-
-    @Test
-    fun play_triggersStateChangedCallback() {
-        val revealEffectConfig = RippleRevealEffectConfig(duration = 1000f)
-        val drawCallback =
-            object : RenderEffectDrawCallback {
-                override fun onDraw(renderEffect: RenderEffect) {}
-            }
-        var animationStartedCalled = false
-        var animationEndedCalled = false
-        val stateChangedCallback =
-            object : RippleRevealEffect.AnimationStateChangedCallback {
-                override fun onAnimationStart() {
-                    animationStartedCalled = true
-                }
-
-                override fun onAnimationEnd() {
-                    animationEndedCalled = true
-                }
-            }
-        val revealEffect =
-            RippleRevealEffect(revealEffectConfig, drawCallback, stateChangedCallback)
-
-        assertThat(animationStartedCalled).isFalse()
-        assertThat(animationEndedCalled).isFalse()
-
-        revealEffect.play()
-
-        assertThat(animationStartedCalled).isTrue()
-
-        animatorTestRule.advanceTimeBy(revealEffectConfig.duration.toLong())
-
-        assertThat(animationEndedCalled).isTrue()
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java
index 0eba21a..33d09c1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java
@@ -59,8 +59,8 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class WallpaperLocalColorExtractorTest extends SysuiTestCase {
-    private static final int LOW_BMP_WIDTH = 128;
-    private static final int LOW_BMP_HEIGHT = 128;
+    private static final int LOW_BMP_WIDTH = 112;
+    private static final int LOW_BMP_HEIGHT = 112;
     private static final int HIGH_BMP_WIDTH = 3000;
     private static final int HIGH_BMP_HEIGHT = 4000;
     private static final int VERY_LOW_BMP_WIDTH = 1;
@@ -189,7 +189,7 @@
 
     /**
      * Test that for bitmaps of random dimensions, the mini bitmap is always created
-     * with either a width <= SMALL_SIDE or a height <= SMALL_SIDE
+     * with an area <= MINI_BITMAP_MAX_AREA
      */
     @Test
     public void testMiniBitmapCreation() {
@@ -203,14 +203,14 @@
             spyColorExtractor.onBitmapChanged(bitmap);
 
             assertThat(mMiniBitmapUpdatedCount).isEqualTo(1);
-            assertThat(Math.min(mMiniBitmapWidth, mMiniBitmapHeight))
-                    .isAtMost(WallpaperLocalColorExtractor.SMALL_SIDE);
+            assertThat(mMiniBitmapWidth * mMiniBitmapHeight)
+                    .isAtMost(WallpaperLocalColorExtractor.MINI_BITMAP_MAX_AREA);
         }
     }
 
     /**
-     * Test that for bitmaps with both width and height <= SMALL_SIDE,
-     * the mini bitmap is always created with both width and height <= SMALL_SIDE
+     * Test that for bitmaps with both width and height <= LOW_BMP_WIDTH,
+     * the mini bitmap is always created with an area <= MINI_BITMAP_MAX_AREA
      */
     @Test
     public void testSmallMiniBitmapCreation() {
@@ -224,8 +224,8 @@
             spyColorExtractor.onBitmapChanged(bitmap);
 
             assertThat(mMiniBitmapUpdatedCount).isEqualTo(1);
-            assertThat(Math.max(mMiniBitmapWidth, mMiniBitmapHeight))
-                    .isAtMost(WallpaperLocalColorExtractor.SMALL_SIDE);
+            assertThat(mMiniBitmapWidth * mMiniBitmapHeight)
+                    .isAtMost(WallpaperLocalColorExtractor.MINI_BITMAP_MAX_AREA);
         }
     }
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt
index 91057b6..bbe37c1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt
@@ -16,14 +16,12 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
-import com.android.internal.widget.lockPatternUtils
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
-import com.android.systemui.user.domain.interactor.selectedUserInteractor
 
 val Kosmos.fromAodTransitionInteractor by
     Kosmos.Fixture {
@@ -36,7 +34,5 @@
             keyguardInteractor = keyguardInteractor,
             powerInteractor = powerInteractor,
             keyguardOcclusionInteractor = keyguardOcclusionInteractor,
-            selectedUserInteractor = selectedUserInteractor,
-            lockPatternUtils = lockPatternUtils,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt
index 7dab5c2..690bde7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt
@@ -16,7 +16,16 @@
 
 package com.android.systemui.media.controls.data.repository
 
+import android.content.applicationContext
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.policy.configurationController
 import com.android.systemui.util.time.systemClock
 
-val Kosmos.mediaFilterRepository by Kosmos.Fixture { MediaFilterRepository(systemClock) }
+val Kosmos.mediaFilterRepository by
+    Kosmos.Fixture {
+        MediaFilterRepository(
+            applicationContext = applicationContext,
+            systemClock = systemClock,
+            configurationController = configurationController
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt
index 6eae28f..069995a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.media.controls.ui.viewmodel
 
 import android.content.applicationContext
+import com.android.systemui.concurrency.fakeExecutor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.kosmos.testDispatcher
@@ -32,6 +33,7 @@
             applicationScope = applicationCoroutineScope,
             applicationContext = applicationContext,
             backgroundDispatcher = testDispatcher,
+            backgroundExecutor = fakeExecutor,
             visualStabilityProvider = visualStabilityProvider,
             interactor = mediaCarouselInteractor,
             controlInteractorFactory = mediaControlInteractorFactory,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelKosmos.kt
index b3fb15f..2f3d3c3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelKosmos.kt
@@ -17,8 +17,8 @@
 package com.android.systemui.media.controls.ui.viewmodel
 
 import android.content.applicationContext
+import com.android.systemui.concurrency.fakeExecutor
 import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.media.controls.domain.pipeline.interactor.mediaControlInteractor
 import com.android.systemui.media.controls.util.mediaUiEventLogger
@@ -26,9 +26,9 @@
 val Kosmos.mediaControlViewModel by
     Kosmos.Fixture {
         MediaControlViewModel(
-            applicationScope = applicationCoroutineScope,
             applicationContext = applicationContext,
             backgroundDispatcher = testDispatcher,
+            backgroundExecutor = fakeExecutor,
             interactor = mediaControlInteractor,
             logger = mediaUiEventLogger,
         )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt
index a47b2e8..d17dd6c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeTestUtil.kt
@@ -31,6 +31,16 @@
 /** Sets up shade state for tests for either value of the scene container flag. */
 class ShadeTestUtil constructor(val delegate: ShadeTestUtilDelegate) {
 
+    /** Sets shade expansion to a value between 0-1. */
+    fun setShadeExpansion(shadeExpansion: Float) {
+        setShadeAndQsExpansion(shadeExpansion, 0f)
+    }
+
+    /** Sets QS expansion to a value between 0-1. */
+    fun setQsExpansion(qsExpansion: Float) {
+        setShadeAndQsExpansion(0f, qsExpansion)
+    }
+
     /** Sets both shade and QS expansion. One value must be zero or values must add up to 1f. */
     fun setShadeAndQsExpansion(shadeExpansion: Float, qsExpansion: Float) {
         Assert.assertTrue(
@@ -40,15 +50,24 @@
         delegate.assertFlagValid()
         delegate.setShadeAndQsExpansionInternal(shadeExpansion, qsExpansion)
     }
+
+    /** Sets the shade expansion on the lockscreen to the given amount from 0-1. */
+    fun setLockscreenShadeExpansion(lockscreenShadeExpansion: Float) {
+        delegate.assertFlagValid()
+        delegate.setLockscreenShadeExpansion(lockscreenShadeExpansion)
+    }
 }
 
 /** Sets up shade state for tests for a specific value of the scene container flag. */
 interface ShadeTestUtilDelegate {
+    /** Asserts that the scene container flag matches this implementation. */
+    fun assertFlagValid()
+
     /** Sets both shade and QS expansion. One value must be zero or values must add up to 1f. */
     fun setShadeAndQsExpansionInternal(shadeExpansion: Float, qsExpansion: Float)
 
-    /** Asserts that the scene container flag matches this implementation. */
-    fun assertFlagValid()
+    /** Sets the shade expansion on the lockscreen to the given amount from 0-1. */
+    fun setLockscreenShadeExpansion(lockscreenShadeExpansion: Float)
 }
 
 /** Sets up shade state for tests when the scene container flag is disabled. */
@@ -60,12 +79,16 @@
         testScope.runCurrent()
     }
 
+    override fun setLockscreenShadeExpansion(lockscreenShadeExpansion: Float) {
+        shadeRepository.setLockscreenShadeExpansion(lockscreenShadeExpansion)
+    }
+
     override fun assertFlagValid() {
         Assert.assertFalse(SceneContainerFlag.isEnabled)
     }
 }
 
-/** Sets up shade state for tests when the scene container flag is disabled. */
+/** Sets up shade state for tests when the scene container flag is enabled. */
 class ShadeTestUtilSceneImpl(val testScope: TestScope, val sceneInteractor: SceneInteractor) :
     ShadeTestUtilDelegate {
     override fun setShadeAndQsExpansionInternal(shadeExpansion: Float, qsExpansion: Float) {
@@ -78,6 +101,24 @@
         }
     }
 
+    override fun setLockscreenShadeExpansion(lockscreenShadeExpansion: Float) {
+        if (lockscreenShadeExpansion == 0f) {
+            setIdleScene(Scenes.Lockscreen)
+        } else if (lockscreenShadeExpansion == 1f) {
+            setIdleScene(Scenes.Shade)
+        } else {
+            setTransitionProgress(Scenes.Lockscreen, Scenes.Shade, lockscreenShadeExpansion)
+        }
+    }
+
+    private fun setIdleScene(scene: SceneKey) {
+        sceneInteractor.changeScene(scene, "test")
+        val transitionState =
+            MutableStateFlow<ObservableTransitionState>(ObservableTransitionState.Idle(scene))
+        sceneInteractor.setTransitionState(transitionState)
+        testScope.runCurrent()
+    }
+
     private fun setTransitionProgress(from: SceneKey, to: SceneKey, progress: Float) {
         sceneInteractor.changeScene(from, "test")
         val transitionState =
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/smartspace/viewmodel/SmartspaceViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/smartspace/viewmodel/SmartspaceViewModelKosmos.kt
new file mode 100644
index 0000000..ebaf323
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/smartspace/viewmodel/SmartspaceViewModelKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.smartspace.viewmodel
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.smartspace.ui.viewmodel.SmartspaceViewModel
+
+val Kosmos.smartspaceViewModelFactory by
+    Kosmos.Fixture {
+        object : SmartspaceViewModel.Factory {
+            override fun create(surfaceName: String): SmartspaceViewModel {
+                return SmartspaceViewModel(
+                    powerInteractor = powerInteractor,
+                    surfaceName = surfaceName
+                )
+            }
+        }
+    }
diff --git a/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java b/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java
index 697ef87..91ba9b3 100644
--- a/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java
+++ b/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java
@@ -56,6 +56,7 @@
     @GuardedBy("mTransports")
     private final SparseArray<Transport> mTransports = new SparseArray<>();
     @NonNull
+    @GuardedBy("mTransportsListeners")
     private final RemoteCallbackList<IOnTransportsChangedListener> mTransportsListeners =
             new RemoteCallbackList<>();
     /** Message type -> IOnMessageReceivedListener */
@@ -84,34 +85,28 @@
      */
     public void addListener(IOnTransportsChangedListener listener) {
         Slog.i(TAG, "Registering OnTransportsChangedListener");
-        mTransportsListeners.register(listener);
-        List<AssociationInfo> associations = new ArrayList<>();
-        synchronized (mTransports) {
-            for (int i = 0; i < mTransports.size(); i++) {
-                AssociationInfo association = mAssociationStore.getAssociationById(
-                        mTransports.keyAt(i));
-                if (association != null) {
-                    associations.add(association);
+        synchronized (mTransportsListeners) {
+            mTransportsListeners.register(listener);
+            mTransportsListeners.broadcast(listener1 -> {
+                // callback to the current listener with all the associations of the transports
+                // immediately
+                if (listener1 == listener) {
+                    try {
+                        listener.onTransportsChanged(getAssociationsWithTransport());
+                    } catch (RemoteException ignored) {
+                    }
                 }
-            }
+            });
         }
-        mTransportsListeners.broadcast(listener1 -> {
-            // callback to the current listener with all the associations of the transports
-            // immediately
-            if (listener1 == listener) {
-                try {
-                    listener.onTransportsChanged(associations);
-                } catch (RemoteException ignored) {
-                }
-            }
-        });
     }
 
     /**
      * Remove the listener for receiving callbacks when any of the transports is changed
      */
     public void removeListener(IOnTransportsChangedListener listener) {
-        mTransportsListeners.unregister(listener);
+        synchronized (mTransportsListeners) {
+            mTransportsListeners.unregister(listener);
+        }
     }
 
     /**
@@ -179,7 +174,7 @@
         Slog.i(TAG, "Transport detached.");
     }
 
-    private void notifyOnTransportsChanged() {
+    private List<AssociationInfo> getAssociationsWithTransport() {
         List<AssociationInfo> associations = new ArrayList<>();
         synchronized (mTransports) {
             for (int i = 0; i < mTransports.size(); i++) {
@@ -190,12 +185,18 @@
                 }
             }
         }
-        mTransportsListeners.broadcast(listener -> {
-            try {
-                listener.onTransportsChanged(associations);
-            } catch (RemoteException ignored) {
-            }
-        });
+        return associations;
+    }
+
+    private void notifyOnTransportsChanged() {
+        synchronized (mTransportsListeners) {
+            mTransportsListeners.broadcast(listener -> {
+                try {
+                    listener.onTransportsChanged(getAssociationsWithTransport());
+                } catch (RemoteException ignored) {
+                }
+            });
+        }
     }
 
     private void initializeTransport(int associationId,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 49f2c8b..c47e42d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3541,13 +3541,23 @@
                 mAppProfiler.setAllowLowerMemLevelLocked(false);
                 doLowMem = false;
             }
+            if (doOomAdj) {
+                if (Flags.migrateFullOomadjUpdates()) {
+                    app.forEachConnectionHost((host) -> enqueueOomAdjTargetLocked(host));
+                }
+            }
+
             EventLogTags.writeAmProcDied(app.userId, pid, app.processName, setAdj, setProcState);
             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
             handleAppDiedLocked(app, pid, false, true, fromBinderDied);
 
             if (doOomAdj) {
-                updateOomAdjLocked(OOM_ADJ_REASON_PROCESS_END);
+                if (Flags.migrateFullOomadjUpdates()) {
+                    updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_PROCESS_END);
+                } else {
+                    updateOomAdjLocked(OOM_ADJ_REASON_PROCESS_END);
+                }
             }
             if (doLowMem) {
                 mAppProfiler.doLowMemReportIfNeededLocked(app);
@@ -17723,11 +17733,6 @@
     }
 
     @GuardedBy({"this", "mProcLock"})
-    final void setAppIdTempAllowlistStateLSP(int uid, boolean onAllowlist) {
-        mOomAdjuster.setAppIdTempAllowlistStateLSP(uid, onAllowlist);
-    }
-
-    @GuardedBy({"this", "mProcLock"})
     final void setUidTempAllowlistStateLSP(int uid, boolean onAllowlist) {
         mOomAdjuster.setUidTempAllowlistStateLSP(uid, onAllowlist);
     }
@@ -18689,7 +18694,7 @@
                     } else {
                         mFgsStartTempAllowList.removeUid(changingUid);
                     }
-                    setAppIdTempAllowlistStateLSP(changingUid, adding);
+                    setUidTempAllowlistStateLSP(changingUid, adding);
                 }
             }
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index bf4f34f..c579ab5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -281,6 +281,8 @@
                     return runClearWatchHeap(pw);
                 case "clear-start-info":
                     return runClearStartInfo(pw);
+                case "start-info-detailed-monitoring":
+                    return runStartInfoDetailedMonitoring(pw);
                 case "clear-exit-info":
                     return runClearExitInfo(pw);
                 case "bug-report":
@@ -1395,12 +1397,12 @@
                 "runClearStartInfo()");
         String opt;
         int userId = UserHandle.USER_CURRENT;
-        String packageName = null;
         while ((opt = getNextOption()) != null) {
             if (opt.equals("--user")) {
                 userId = UserHandle.parseUserArg(getNextArgRequired());
             } else {
-                packageName = opt;
+                getErrPrintWriter().println("Error: Unknown option: " + opt);
+                return -1;
             }
         }
         if (userId == UserHandle.USER_CURRENT) {
@@ -1411,21 +1413,19 @@
             userId = user.id;
         }
         mInternal.mProcessList.getAppStartInfoTracker()
-                .clearHistoryProcessStartInfo(packageName, userId);
+                .clearHistoryProcessStartInfo(getNextArg(), userId);
         return 0;
     }
 
-    int runClearExitInfo(PrintWriter pw) throws RemoteException {
-        mInternal.enforceCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
-                "runClearExitInfo()");
+    int runStartInfoDetailedMonitoring(PrintWriter pw) throws RemoteException {
         String opt;
         int userId = UserHandle.USER_CURRENT;
-        String packageName = null;
         while ((opt = getNextOption()) != null) {
             if (opt.equals("--user")) {
                 userId = UserHandle.parseUserArg(getNextArgRequired());
             } else {
-                packageName = opt;
+                getErrPrintWriter().println("Error: Unknown option: " + opt);
+                return -1;
             }
         }
         if (userId == UserHandle.USER_CURRENT) {
@@ -1435,7 +1435,33 @@
             }
             userId = user.id;
         }
-        mInternal.mProcessList.mAppExitInfoTracker.clearHistoryProcessExitInfo(packageName, userId);
+        mInternal.mProcessList.getAppStartInfoTracker()
+                .configureDetailedMonitoring(pw, getNextArg(), userId);
+        return 0;
+    }
+
+    int runClearExitInfo(PrintWriter pw) throws RemoteException {
+        mInternal.enforceCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
+                "runClearExitInfo()");
+        String opt;
+        int userId = UserHandle.USER_CURRENT;
+        while ((opt = getNextOption()) != null) {
+            if (opt.equals("--user")) {
+                userId = UserHandle.parseUserArg(getNextArgRequired());
+            } else {
+                getErrPrintWriter().println("Error: Unknown option: " + opt);
+                return -1;
+            }
+        }
+        if (userId == UserHandle.USER_CURRENT) {
+            UserInfo user = mInterface.getCurrentUser();
+            if (user == null) {
+                return -1;
+            }
+            userId = user.id;
+        }
+        mInternal.mProcessList.mAppExitInfoTracker.clearHistoryProcessExitInfo(getNextArg(),
+                userId);
         return 0;
     }
 
@@ -4356,10 +4382,15 @@
             pw.println("      above <HEAP-LIMIT> then a heap dump is collected for the user to report.");
             pw.println("  clear-watch-heap");
             pw.println("      Clear the previously set-watch-heap.");
-            pw.println("  clear-start-info [--user <USER_ID> | all | current] [package]");
-            pw.println("      Clear the process start-info for given package");
-            pw.println("  clear-exit-info [--user <USER_ID> | all | current] [package]");
-            pw.println("      Clear the process exit-info for given package");
+            pw.println("  clear-start-info [--user <USER_ID> | all | current] <PACKAGE>");
+            pw.println("      Clear process start-info for the given package.");
+            pw.println("      Clear start-info for all packages if no package is provided.");
+            pw.println("  start-info-detailed-monitoring [--user <USER_ID> | all | current] <PACKAGE>");
+            pw.println("      Enable application start info detailed monitoring for the given package.");
+            pw.println("      Disable if no package is supplied.");
+            pw.println("  clear-exit-info [--user <USER_ID> | all | current] <PACKAGE>");
+            pw.println("      Clear process exit-info for the given package.");
+            pw.println("      Clear exit-info for all packages if no package is provided.");
             pw.println("  bug-report [--progress | --telephony]");
             pw.println("      Request bug report generation; will launch a notification");
             pw.println("        when done to select where it should be delivered. Options are:");
diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java
index 2be1fe2..376f654 100644
--- a/services/core/java/com/android/server/am/AppStartInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java
@@ -65,6 +65,7 @@
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -82,8 +83,12 @@
     private static final int FOREACH_ACTION_REMOVE_ITEM = 1;
     private static final int FOREACH_ACTION_STOP_ITERATION = 2;
 
+    private static final String MONITORING_MODE_EMPTY_TEXT = "No records";
+
     @VisibleForTesting static final int APP_START_INFO_HISTORY_LIST_SIZE = 16;
 
+    private static final int APP_START_INFO_MONITORING_MODE_LIST_SIZE = 100;
+
     @VisibleForTesting static final String APP_START_STORE_DIR = "procstartstore";
 
     @VisibleForTesting static final String APP_START_INFO_FILE = "procstartinfo";
@@ -426,6 +431,40 @@
                 ApplicationStartInfo.START_TIMESTAMP_APPLICATION_ONCREATE);
     }
 
+    /**
+     * Helper functions for monitoring shell command.
+     * > adb shell am start-info-detailed-monitoring [package-name]
+     */
+    void configureDetailedMonitoring(PrintWriter pw, String packageName, int userId) {
+        synchronized (mLock) {
+            if (!mEnabled) {
+                return;
+            }
+
+            forEachPackageLocked((name, records) -> {
+                for (int i = 0; i < records.size(); i++) {
+                    records.valueAt(i).disableAppMonitoringMode();
+                }
+                return AppStartInfoTracker.FOREACH_ACTION_NONE;
+            });
+
+            if (TextUtils.isEmpty(packageName)) {
+                pw.println("ActivityManager AppStartInfo detailed monitoring disabled");
+            } else {
+                SparseArray<AppStartInfoContainer> array = mData.getMap().get(packageName);
+                if (array != null) {
+                    for (int i = 0; i < array.size(); i++) {
+                        array.valueAt(i).enableAppMonitoringModeForUser(userId);
+                    }
+                    pw.println("ActivityManager AppStartInfo detailed monitoring enabled for "
+                            + packageName);
+                } else {
+                    pw.println("Package " + packageName + " not found");
+                }
+            }
+        }
+    }
+
     /** Report a bind application timestamp to add to {@link ApplicationStartInfo}. */
     public void reportBindApplicationTimeNanos(ProcessRecord app, long timeNs) {
         addTimestampToStart(app, timeNs,
@@ -1011,15 +1050,46 @@
 
     /** A container class of (@link android.app.ApplicationStartInfo) */
     final class AppStartInfoContainer {
-        private List<ApplicationStartInfo> mInfos; // Always kept sorted by first timestamp.
+        private ArrayList<ApplicationStartInfo> mInfos; // Always kept sorted by first timestamp.
         private int mMaxCapacity;
         private int mUid;
+        private boolean mMonitoringModeEnabled = false;
 
         AppStartInfoContainer(final int maxCapacity) {
             mInfos = new ArrayList<ApplicationStartInfo>();
             mMaxCapacity = maxCapacity;
         }
 
+        int getMaxCapacity() {
+            return mMonitoringModeEnabled ? APP_START_INFO_MONITORING_MODE_LIST_SIZE : mMaxCapacity;
+        }
+
+        @GuardedBy("mLock")
+        void enableAppMonitoringModeForUser(int userId) {
+            if (UserHandle.getUserId(mUid) == userId) {
+                mMonitoringModeEnabled = true;
+            }
+        }
+
+        @GuardedBy("mLock")
+        void disableAppMonitoringMode() {
+            mMonitoringModeEnabled = false;
+
+            // Capacity is reduced by turning off monitoring mode. Check if array size is within
+            // new lower limits and trim extraneous records if it is not.
+            if (mInfos.size() <= getMaxCapacity()) {
+                return;
+            }
+
+            // Sort records so we can remove the least recent ones.
+            Collections.sort(mInfos, (a, b) ->
+                    Long.compare(getStartTimestamp(b), getStartTimestamp(a)));
+
+            // Remove records and trim list object back to size.
+            mInfos.subList(0, mInfos.size() - getMaxCapacity()).clear();
+            mInfos.trimToSize();
+        }
+
         @GuardedBy("mLock")
         void getStartInfoLocked(
                 final int filterPid, final int maxNum, ArrayList<ApplicationStartInfo> results) {
@@ -1029,7 +1099,7 @@
         @GuardedBy("mLock")
         void addStartInfoLocked(ApplicationStartInfo info) {
             int size = mInfos.size();
-            if (size >= mMaxCapacity) {
+            if (size >= getMaxCapacity()) {
                 // Remove oldest record if size is over max capacity.
                 int oldestIndex = -1;
                 long oldestTimeStamp = Long.MAX_VALUE;
@@ -1061,12 +1131,59 @@
 
         @GuardedBy("mLock")
         void dumpLocked(PrintWriter pw, String prefix, SimpleDateFormat sdf) {
+            if (mMonitoringModeEnabled) {
+                // For monitoring mode, calculate the average start time for each start state to
+                // add to output.
+                List<Long> coldStartTimes = new ArrayList<>();
+                List<Long> warmStartTimes = new ArrayList<>();
+                List<Long> hotStartTimes = new ArrayList<>();
+
+                for (int i = 0; i < mInfos.size(); i++) {
+                    ApplicationStartInfo startInfo = mInfos.get(i);
+                    Map<Integer, Long> timestamps = startInfo.getStartupTimestamps();
+
+                    // Confirm required timestamps exist.
+                    if (timestamps.containsKey(ApplicationStartInfo.START_TIMESTAMP_LAUNCH)
+                            && timestamps.containsKey(
+                            ApplicationStartInfo.START_TIMESTAMP_FIRST_FRAME)) {
+                        // Add timestamp to correct collection.
+                        long time = timestamps.get(ApplicationStartInfo.START_TIMESTAMP_FIRST_FRAME)
+                                - timestamps.get(ApplicationStartInfo.START_TIMESTAMP_LAUNCH);
+                        switch (startInfo.getStartType()) {
+                            case ApplicationStartInfo.START_TYPE_COLD:
+                                coldStartTimes.add(time);
+                                break;
+                            case ApplicationStartInfo.START_TYPE_WARM:
+                                warmStartTimes.add(time);
+                                break;
+                            case ApplicationStartInfo.START_TYPE_HOT:
+                                hotStartTimes.add(time);
+                                break;
+                        }
+                    }
+                }
+
+                pw.println(prefix + "  Average Start Time in ns for Cold Starts: "
+                        + (coldStartTimes.isEmpty()  ? MONITORING_MODE_EMPTY_TEXT
+                                : calculateAverage(coldStartTimes)));
+                pw.println(prefix + "  Average Start Time in ns for Warm Starts: "
+                        + (warmStartTimes.isEmpty() ? MONITORING_MODE_EMPTY_TEXT
+                                : calculateAverage(warmStartTimes)));
+                pw.println(prefix + "  Average Start Time in ns for Hot Starts: "
+                        + (hotStartTimes.isEmpty() ? MONITORING_MODE_EMPTY_TEXT
+                                : calculateAverage(hotStartTimes)));
+            }
+
             int size = mInfos.size();
             for (int i = 0; i < size; i++) {
                 mInfos.get(i).dump(pw, prefix + "  ", "#" + i, sdf);
             }
         }
 
+        private long calculateAverage(List<Long> vals) {
+            return (long) vals.stream().mapToDouble(a -> a).average().orElse(0.0);
+        }
+
         @GuardedBy("mLock")
         void writeToProto(ProtoOutputStream proto, long fieldId) throws IOException {
             long token = proto.start(fieldId);
@@ -1076,6 +1193,7 @@
                 mInfos.get(i)
                         .writeToProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO);
             }
+            proto.write(AppsStartInfoProto.Package.User.MONITORING_ENABLED, mMonitoringModeEnabled);
             proto.end(token);
         }
 
@@ -1094,6 +1212,10 @@
                         info.readFromProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO);
                         mInfos.add(info);
                         break;
+                    case (int) AppsStartInfoProto.Package.User.MONITORING_ENABLED:
+                        mMonitoringModeEnabled = proto.readBoolean(
+                            AppsStartInfoProto.Package.User.MONITORING_ENABLED);
+                        break;
                 }
             }
             proto.end(token);
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 9b72db8..a289dd1 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -3696,27 +3696,18 @@
     }
 
     @GuardedBy({"mService", "mProcLock"})
-    void setAppIdTempAllowlistStateLSP(int uid, boolean onAllowlist) {
-        boolean changed = false;
-        for (int i = mActiveUids.size() - 1; i >= 0; i--) {
-            final UidRecord uidRec = mActiveUids.valueAt(i);
-            if (uidRec.getUid() == uid && uidRec.isCurAllowListed() != onAllowlist) {
-                uidRec.setCurAllowListed(onAllowlist);
-                changed = true;
-            }
-        }
-        if (changed) {
-            updateOomAdjLSP(OOM_ADJ_REASON_ALLOWLIST);
-        }
-    }
-
-    @GuardedBy({"mService", "mProcLock"})
     void setUidTempAllowlistStateLSP(int uid, boolean onAllowlist) {
-        boolean changed = false;
         final UidRecord uidRec = mActiveUids.get(uid);
         if (uidRec != null && uidRec.isCurAllowListed() != onAllowlist) {
             uidRec.setCurAllowListed(onAllowlist);
-            updateOomAdjLSP(OOM_ADJ_REASON_ALLOWLIST);
+            if (Flags.migrateFullOomadjUpdates()) {
+                for (int i = uidRec.getNumOfProcs() - 1; i >= 0; i--) {
+                    enqueueOomAdjTargetLocked(uidRec.getProcessRecordByIndex(i));
+                }
+                updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_ALLOWLIST);
+            } else {
+                updateOomAdjLSP(OOM_ADJ_REASON_ALLOWLIST);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 0816527..a74c489 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -71,6 +71,7 @@
 import java.io.PrintWriter;
 import java.util.Arrays;
 import java.util.List;
+import java.util.function.Consumer;
 
 /**
  * Full information about a particular process that
@@ -1692,4 +1693,22 @@
                 && !mOptRecord.shouldNotFreeze()
                 && mState.getCurAdj() >= ProcessList.FREEZER_CUTOFF_ADJ;
     }
+
+    public void forEachConnectionHost(Consumer<ProcessRecord> consumer) {
+        for (int i = mServices.numberOfConnections() - 1; i >= 0; i--) {
+            final ConnectionRecord cr = mServices.getConnectionAt(i);
+            final ProcessRecord service = cr.binding.service.app;
+            consumer.accept(service);
+        }
+        for (int i = mServices.numberOfSdkSandboxConnections() - 1; i >= 0; i--) {
+            final ConnectionRecord cr = mServices.getSdkSandboxConnectionAt(i);
+            final ProcessRecord service = cr.binding.service.app;
+            consumer.accept(service);
+        }
+        for (int i = mProviders.numberOfProviderConnections() - 1; i >= 0; i--) {
+            ContentProviderConnection cpc = mProviders.getProviderConnectionAt(i);
+            ProcessRecord provider = cpc.provider.proc;
+            consumer.accept(provider);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index 19be5f9..fb63ec6 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -106,3 +106,13 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "migrate_full_oomadj_updates"
+    namespace: "backstage_power"
+    description: "Migrate full updates to partial updates where possible"
+    bug: "324915545"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricLogger.java b/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
index cd5d0c8..ff1e5d5 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
@@ -16,13 +16,14 @@
 
 package com.android.server.biometrics.log;
 
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_START;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.hardware.SensorManager;
 import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricsProtoEnums;
-import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
 import android.util.Slog;
 
@@ -137,7 +138,7 @@
         final boolean isFingerprint = mStatsModality == BiometricsProtoEnums.MODALITY_FINGERPRINT;
         if (isFace || isFingerprint) {
             if ((isFingerprint && acquiredInfo == FingerprintManager.FINGERPRINT_ACQUIRED_START)
-                    || (isFace && acquiredInfo == FaceManager.FACE_ACQUIRED_START)) {
+                    || (isFace && acquiredInfo == FACE_ACQUIRED_START)) {
                 mFirstAcquireTimeMs = System.currentTimeMillis();
             }
         } else if (acquiredInfo == BiometricConstants.BIOMETRIC_ACQUIRED_GOOD) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
index 8d32235..ef7abdd 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
@@ -17,6 +17,9 @@
 package com.android.server.biometrics.sensors.face.aidl;
 
 import static android.adaptiveauth.Flags.reportBiometricAuthAttempts;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_NOT_DETECTED;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_SENSOR_DIRTY;
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_UNKNOWN;
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_VENDOR;
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_VENDOR_BASE;
 import static android.hardware.face.FaceManager.getAuthHelpMessage;
@@ -43,7 +46,6 @@
 import android.hardware.biometrics.face.IFace;
 import android.hardware.face.FaceAuthenticateOptions;
 import android.hardware.face.FaceAuthenticationFrame;
-import android.hardware.face.FaceManager;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Slog;
@@ -90,8 +92,8 @@
     private final SensorPrivacyManager mSensorPrivacyManager;
     @NonNull
     private final AuthenticationStateListeners mAuthenticationStateListeners;
-    @FaceManager.FaceAcquired
-    private int mLastAcquire = FaceManager.FACE_ACQUIRED_UNKNOWN;
+    @BiometricFaceConstants.FaceAcquired
+    private int mLastAcquire = FACE_ACQUIRED_UNKNOWN;
 
     public FaceAuthenticationClient(@NonNull Context context,
             @NonNull Supplier<AidlSession> lazyDaemon,
@@ -232,9 +234,9 @@
     public boolean wasUserDetected() {
         // Do not provide haptic feedback if the user was not detected, and an error (usually
         // ERROR_TIMEOUT) is received.
-        return mLastAcquire != FaceManager.FACE_ACQUIRED_NOT_DETECTED
-                && mLastAcquire != FaceManager.FACE_ACQUIRED_SENSOR_DIRTY
-                && mLastAcquire != FaceManager.FACE_ACQUIRED_UNKNOWN;
+        return mLastAcquire != FACE_ACQUIRED_NOT_DETECTED
+                && mLastAcquire != FACE_ACQUIRED_SENSOR_DIRTY
+                && mLastAcquire != FACE_ACQUIRED_UNKNOWN;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
index 6b99493..559462a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
@@ -16,6 +16,8 @@
 
 package com.android.server.biometrics.sensors.face.aidl;
 
+import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -28,7 +30,6 @@
 import android.hardware.biometrics.face.IFace;
 import android.hardware.biometrics.face.ISession;
 import android.hardware.biometrics.face.SensorProps;
-import android.hardware.face.FaceManager;
 import android.hardware.face.FaceSensorPropertiesInternal;
 import android.os.Binder;
 import android.os.Handler;
@@ -296,7 +297,7 @@
         if (client != null && client.isInterruptable()) {
             Slog.e(TAG, "Sending face hardware unavailable error for client: " + client);
             final ErrorConsumer errorConsumer = (ErrorConsumer) client;
-            errorConsumer.onError(FaceManager.FACE_ERROR_HW_UNAVAILABLE,
+            errorConsumer.onError(FACE_ERROR_HW_UNAVAILABLE,
                     0 /* vendorCode */);
 
             FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java
index a818eab..816242d 100644
--- a/services/core/java/com/android/server/dreams/DreamController.java
+++ b/services/core/java/com/android/server/dreams/DreamController.java
@@ -205,7 +205,7 @@
             Intent intent = new Intent(DreamService.SERVICE_INTERFACE);
             intent.setComponent(name);
             intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-            intent.putExtra(DreamService.EXTRA_DREAM_OVERLAY_COMPONENT, overlayComponentName);
+            DreamService.setDreamOverlayComponent(intent, overlayComponentName);
             try {
                 if (!mContext.bindServiceAsUser(intent, mCurrentDream,
                         Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 8686e9a..39f3121 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -2617,19 +2617,6 @@
         mBatteryController.notifyStylusGestureStarted(deviceId, eventTime);
     }
 
-    // Native callback.
-    @SuppressWarnings("unused")
-    private int getPackageUid(String pkg) {
-        if (TextUtils.isEmpty(pkg)) {
-            return Process.INVALID_UID;
-        }
-        try {
-            return mContext.getPackageManager().getPackageUid(pkg, 0 /*flags*/);
-        } catch (PackageManager.NameNotFoundException e) {
-            return Process.INVALID_UID;
-        }
-    }
-
     /**
      * Flatten a map into a string list, with value positioned directly next to the
      * key.
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index e196dee..5731161 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -922,7 +922,7 @@
     }
 
     /**
-     * Handles a message deliveyr status from a Context Hub.
+     * Handles a message delivery status from a Context Hub.
      *
      * @param messageDeliveryStatus     The message delivery status to deliver.
      */
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 36790ab..2e25ad8 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -573,12 +573,16 @@
                     (scanFlags & SCAN_DONT_KILL_APP) != 0 /* retainImplicitGrantOnReplace */);
             mPm.addAllPackageProperties(pkg);
 
-            if (oldPkgSetting == null || oldPkgSetting.getPkg() == null) {
-                mPm.mDomainVerificationManager.addPackage(pkgSetting,
-                        request.getPreVerifiedDomains());
-            } else {
-                mPm.mDomainVerificationManager.migrateState(oldPkgSetting, pkgSetting,
-                        request.getPreVerifiedDomains());
+            // Only verify app links for non-archival installations, otherwise there won't be any
+            // declared app links.
+            if (!request.isArchived()) {
+                if (oldPkgSetting == null || oldPkgSetting.getPkg() == null) {
+                    mPm.mDomainVerificationManager.addPackage(pkgSetting,
+                            request.getPreVerifiedDomains());
+                } else {
+                    mPm.mDomainVerificationManager.migrateState(oldPkgSetting, pkgSetting,
+                            request.getPreVerifiedDomains());
+                }
             }
 
             int collectionSize = ArrayUtils.size(pkg.getInstrumentations());
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index fde49d2..5fa8856 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -129,6 +129,7 @@
     private final WindowManagerPolicy mPolicy;
     private final FaceDownDetector mFaceDownDetector;
     private final ScreenUndimDetector mScreenUndimDetector;
+    private final WakefulnessSessionObserver mWakefulnessSessionObserver;
     private final ActivityManagerInternal mActivityManagerInternal;
     private final InputManagerInternal mInputManagerInternal;
     private final InputMethodManagerInternal mInputMethodManagerInternal;
@@ -197,6 +198,7 @@
         mPolicy = policy;
         mFaceDownDetector = faceDownDetector;
         mScreenUndimDetector = screenUndimDetector;
+        mWakefulnessSessionObserver = new WakefulnessSessionObserver(mContext, null);
         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
         mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
         mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
@@ -286,6 +288,8 @@
         }
 
         mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags);
+
+        mWakefulnessSessionObserver.onWakeLockAcquired(flags);
     }
 
     public void onLongPartialWakeLockStart(String tag, int ownerUid, WorkSource workSource,
@@ -386,6 +390,16 @@
     public void onWakeLockReleased(int flags, String tag, String packageName,
             int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
             IWakeLockCallback callback) {
+        onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag,
+                callback, ScreenTimeoutOverridePolicy.RELEASE_REASON_UNKNOWN);
+    }
+
+    /**
+     * Called when a wake lock is released.
+     */
+    public void onWakeLockReleased(int flags, String tag, String packageName,
+            int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
+            IWakeLockCallback callback, int releaseReason) {
         if (DEBUG) {
             Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag
                     + "\", packageName=" + packageName
@@ -409,6 +423,8 @@
             }
         }
         mWakeLockLog.onWakeLockReleased(tag, ownerUid);
+
+        mWakefulnessSessionObserver.onWakeLockReleased(flags, releaseReason);
     }
 
     /** Shows the keyguard without requesting the device to immediately lock. */
@@ -670,6 +686,8 @@
             interactivity.changeStartTime = eventTime;
             interactivity.isChanging = true;
             handleEarlyInteractiveChange(groupId);
+            mWakefulnessSessionObserver.onWakefulnessChangeStarted(groupId, wakefulness,
+                    changeReason, eventTime);
         }
     }
 
@@ -680,6 +698,7 @@
      */
     public void onGroupRemoved(int groupId) {
         mInteractivityByGroupId.remove(groupId);
+        mWakefulnessSessionObserver.removePowerGroup(groupId);
     }
 
     /**
@@ -693,6 +712,8 @@
 
         try {
             mBatteryStats.noteUserActivity(uid, event);
+            mWakefulnessSessionObserver.notifyUserActivity(
+                    SystemClock.uptimeMillis(), displayGroupId, event);
         } catch (RemoteException ex) {
             // Ignore
         }
@@ -798,6 +819,8 @@
         if (mWakeLockLog != null) {
             mWakeLockLog.dump(pw);
         }
+
+        mWakefulnessSessionObserver.dump(pw);
     }
 
     private void updatePendingBroadcastLocked() {
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index eb1f720..bbb59ce 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -231,7 +231,7 @@
 
     // Default timeout in milliseconds.  This is only used until the settings
     // provider populates the actual default value (R.integer.def_screen_off_timeout).
-    private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
+    static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
     private static final int DEFAULT_SLEEP_TIMEOUT = -1;
 
     // Screen brightness boost timeout.
@@ -1417,8 +1417,9 @@
             updateSettingsLocked();
             if (mFeatureFlags.isEarlyScreenTimeoutDetectorEnabled()) {
                 mScreenTimeoutOverridePolicy = new ScreenTimeoutOverridePolicy(mContext,
-                        mMinimumScreenOffTimeoutConfig, () -> {
+                        mMinimumScreenOffTimeoutConfig, (releaseReason) -> {
                     Message msg = mHandler.obtainMessage(MSG_RELEASE_ALL_OVERRIDE_WAKE_LOCKS);
+                    msg.arg1 = releaseReason;
                     mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
                 });
             }
@@ -1827,6 +1828,12 @@
 
     @GuardedBy("mLock")
     private void removeWakeLockNoUpdateLocked(WakeLock wakeLock, int index) {
+        removeWakeLockNoUpdateLocked(wakeLock, index,
+                ScreenTimeoutOverridePolicy.RELEASE_REASON_UNKNOWN);
+    }
+
+    @GuardedBy("mLock")
+    private void removeWakeLockNoUpdateLocked(WakeLock wakeLock, int index, int releaseReason) {
         mWakeLocks.remove(index);
         UidState state = wakeLock.mUidState;
         state.mNumWakeLocks--;
@@ -1835,7 +1842,7 @@
             mUidState.remove(state.mUid);
         }
 
-        notifyWakeLockReleasedLocked(wakeLock);
+        notifyWakeLockReleasedLocked(wakeLock, releaseReason);
         applyWakeLockFlagsOnReleaseLocked(wakeLock);
         mDirty |= DIRTY_WAKE_LOCKS;
     }
@@ -2001,12 +2008,17 @@
 
     @GuardedBy("mLock")
     private void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
+        notifyWakeLockReleasedLocked(wakeLock, ScreenTimeoutOverridePolicy.RELEASE_REASON_UNKNOWN);
+    }
+
+    @GuardedBy("mLock")
+    private void notifyWakeLockReleasedLocked(WakeLock wakeLock, int releaseReason) {
         if (mSystemReady && wakeLock.mNotifiedAcquired) {
             wakeLock.mNotifiedAcquired = false;
             wakeLock.mAcquireTime = 0;
             mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag,
                     wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid,
-                    wakeLock.mWorkSource, wakeLock.mHistoryTag, wakeLock.mCallback);
+                    wakeLock.mWorkSource, wakeLock.mHistoryTag, wakeLock.mCallback, releaseReason);
             notifyWakeLockLongFinishedLocked(wakeLock);
         }
     }
@@ -5345,7 +5357,7 @@
                     handleAttentiveTimeout();
                     break;
                 case MSG_RELEASE_ALL_OVERRIDE_WAKE_LOCKS:
-                    releaseAllOverrideWakeLocks();
+                    releaseAllOverrideWakeLocks(msg.arg1);
                     break;
             }
 
@@ -7269,7 +7281,7 @@
         return false;
     }
 
-    private void releaseAllOverrideWakeLocks() {
+    private void releaseAllOverrideWakeLocks(int releaseReason) {
         synchronized (mLock) {
             final int size = mWakeLocks.size();
             boolean change = false;
@@ -7277,7 +7289,7 @@
                 final WakeLock wakeLock = mWakeLocks.get(i);
                 if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
                         == PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK) {
-                    removeWakeLockNoUpdateLocked(wakeLock, i);
+                    removeWakeLockNoUpdateLocked(wakeLock, i, releaseReason);
                     change = true;
                 }
             }
diff --git a/services/core/java/com/android/server/power/ScreenTimeoutOverridePolicy.java b/services/core/java/com/android/server/power/ScreenTimeoutOverridePolicy.java
index adde518..dcb3c39 100644
--- a/services/core/java/com/android/server/power/ScreenTimeoutOverridePolicy.java
+++ b/services/core/java/com/android/server/power/ScreenTimeoutOverridePolicy.java
@@ -23,6 +23,7 @@
 import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_DIM;
 import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_TIMEOUT_OVERRIDE;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.os.PowerManager;
 import android.util.IndentingPrintWriter;
@@ -31,6 +32,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
   * Policy that handle the screen timeout override wake lock behavior.
@@ -50,25 +53,62 @@
     public static final int RELEASE_REASON_NON_INTERACTIVE = 1;
 
     /**
-     * Release reason code: Release because user activity occurred.
-     */
-    public static final int RELEASE_REASON_USER_ACTIVITY = 2;
-    /**
      * Release reason code: Release because a screen lock is acquired.
      */
-    public static final int RELEASE_REASON_SCREEN_LOCK = 3;
+    public static final int RELEASE_REASON_SCREEN_LOCK = 2;
+
+    /**
+     * Release reason code: Release because user activity attention occurs.
+     */
+    public static final int RELEASE_REASON_USER_ACTIVITY_ATTENTION = 3;
+
+    /**
+     * Release reason code: Release because user activity other occurs.
+     */
+    public static final int RELEASE_REASON_USER_ACTIVITY_OTHER = 4;
+
+    /**
+     * Release reason code: Release because user activity button occurs.
+     */
+    public static final int RELEASE_REASON_USER_ACTIVITY_BUTTON = 5;
+
+    /**
+     * Release reason code: Release because user activity touch occurs.
+     */
+    public static final int RELEASE_REASON_USER_ACTIVITY_TOUCH = 6;
+
+    /**
+     * Release reason code: Release because user activity accessibility occurs.
+     */
+    public static final int RELEASE_REASON_USER_ACTIVITY_ACCESSIBILITY = 7;
+
+    /**
+     * @hide
+     */
+    @IntDef(prefix = { "RELEASE_REASON_" }, value = {
+            RELEASE_REASON_UNKNOWN,
+            RELEASE_REASON_NON_INTERACTIVE,
+            RELEASE_REASON_SCREEN_LOCK,
+            RELEASE_REASON_USER_ACTIVITY_ATTENTION,
+            RELEASE_REASON_USER_ACTIVITY_OTHER,
+            RELEASE_REASON_USER_ACTIVITY_BUTTON,
+            RELEASE_REASON_USER_ACTIVITY_TOUCH,
+            RELEASE_REASON_USER_ACTIVITY_ACCESSIBILITY
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ReleaseReason{}
 
     // The screen timeout override config in milliseconds.
     private long mScreenTimeoutOverrideConfig;
 
     // The last reason that wake locks had been released by service.
-    private int mLastAutoReleaseReason = RELEASE_REASON_UNKNOWN;
+    private @ReleaseReason int mLastAutoReleaseReason = RELEASE_REASON_UNKNOWN;
 
     interface PolicyCallback {
         /**
          * Notify {@link PowerManagerService} to release all override wake locks.
          */
-        void releaseAllScreenTimeoutOverrideWakelocks();
+        void releaseAllScreenTimeoutOverrideWakelocks(@ReleaseReason int reason);
     }
     private PolicyCallback mPolicyCallback;
 
@@ -110,11 +150,20 @@
 
         switch (event) {
             case PowerManager.USER_ACTIVITY_EVENT_ATTENTION:
+                releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_ATTENTION);
+                return;
             case PowerManager.USER_ACTIVITY_EVENT_OTHER:
+                releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_OTHER);
+                return;
             case PowerManager.USER_ACTIVITY_EVENT_BUTTON:
+                releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_BUTTON);
+                return;
             case PowerManager.USER_ACTIVITY_EVENT_TOUCH:
+                releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_TOUCH);
+                return;
             case PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY:
-                releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY);
+                releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY_ACCESSIBILITY);
+                return;
         }
     }
 
@@ -154,8 +203,8 @@
                 + " (reason=" + mLastAutoReleaseReason + ")");
     }
 
-    private void releaseAllWakeLocks(int reason) {
-        mPolicyCallback.releaseAllScreenTimeoutOverrideWakelocks();
+    private void releaseAllWakeLocks(@ReleaseReason int reason) {
+        mPolicyCallback.releaseAllScreenTimeoutOverrideWakelocks(reason);
         mLastAutoReleaseReason = reason;
         logReleaseReason();
     }
diff --git a/services/core/java/com/android/server/power/WakefulnessSessionObserver.java b/services/core/java/com/android/server/power/WakefulnessSessionObserver.java
new file mode 100644
index 0000000..d57cd5d
--- /dev/null
+++ b/services/core/java/com/android/server/power/WakefulnessSessionObserver.java
@@ -0,0 +1,595 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+import static android.os.PowerManager.USER_ACTIVITY_EVENT_OTHER;
+import static android.os.PowerManagerInternal.isInteractive;
+
+import static com.android.server.power.PowerManagerService.DEFAULT_SCREEN_OFF_TIMEOUT;
+import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_NON_INTERACTIVE;
+import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_SCREEN_LOCK;
+import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_UNKNOWN;
+import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_ACCESSIBILITY;
+import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_ATTENTION;
+import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_BUTTON;
+import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_OTHER;
+import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_TOUCH;
+
+import android.annotation.IntDef;
+import android.app.ActivityManager;
+import android.app.SynchronousUserSwitchObserver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.PowerManagerInternal;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.IndentingPrintWriter;
+import android.util.SparseArray;
+import android.view.Display;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Observe the wakefulness session of the device, tracking the reason and the
+ * last user activity when the interactive state is off.
+ */
+public class WakefulnessSessionObserver {
+    private static final String TAG = "WakefulnessSessionObserver";
+
+    private static final int OFF_REASON_UNKNOWN = FrameworkStatsLog
+            .SCREEN_INTERACTIVE_SESSION_REPORTED__INTERACTIVE_STATE_OFF_REASON__UNKNOWN;
+    private static final int OFF_REASON_TIMEOUT = FrameworkStatsLog
+            .SCREEN_INTERACTIVE_SESSION_REPORTED__INTERACTIVE_STATE_OFF_REASON__TIMEOUT;
+    @VisibleForTesting
+    protected static final int OFF_REASON_POWER_BUTTON = FrameworkStatsLog
+            .SCREEN_INTERACTIVE_SESSION_REPORTED__INTERACTIVE_STATE_OFF_REASON__POWER_BUTTON;
+
+    /**
+     * Interactive off reason
+     * {@link android.os.statsd.power.ScreenInteractiveSessionReported.InteractiveStateOffReason}.
+     */
+    @IntDef(prefix = {"OFF_REASON_"}, value = {
+            OFF_REASON_UNKNOWN,
+            OFF_REASON_TIMEOUT,
+            OFF_REASON_POWER_BUTTON
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    private @interface OffReason {}
+
+    private static final int OVERRIDE_OUTCOME_UNKNOWN = FrameworkStatsLog
+            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__UNKNOWN;
+    @VisibleForTesting
+    protected static final int OVERRIDE_OUTCOME_TIMEOUT_SUCCESS = FrameworkStatsLog
+            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__TIMEOUT_SUCCESS;
+    @VisibleForTesting
+    protected static final int OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT = FrameworkStatsLog
+            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__TIMEOUT_USER_INITIATED_REVERT;
+    private static final int OVERRIDE_OUTCOME_CANCEL_CLIENT_API_CALL = FrameworkStatsLog
+            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_CLIENT_API_CALL;
+    @VisibleForTesting
+    protected static final int OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION = FrameworkStatsLog
+            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_USER_INTERACTION;
+    @VisibleForTesting
+    protected static final int OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON = FrameworkStatsLog
+            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_POWER_BUTTON;
+    private static final int OVERRIDE_OUTCOME_CANCEL_CLIENT_DISCONNECT = FrameworkStatsLog
+            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_CLIENT_DISCONNECTED;
+    private static final int OVERRIDE_OUTCOME_CANCEL_OTHER = FrameworkStatsLog
+            .SCREEN_TIMEOUT_OVERRIDE_REPORTED__OVERRIDE_OUTCOME__CANCEL_OTHER;
+
+    /**
+     * Override Outcome
+     * {@link android.os.statsd.power.ScreenTimeoutOverrideReported.OverrideOutcome}.
+     */
+    @IntDef(prefix = {"OVERRIDE_OUTCOME_"}, value = {
+            OVERRIDE_OUTCOME_UNKNOWN,
+            OVERRIDE_OUTCOME_TIMEOUT_SUCCESS,
+            OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT,
+            OVERRIDE_OUTCOME_CANCEL_CLIENT_API_CALL,
+            OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION,
+            OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON,
+            OVERRIDE_OUTCOME_CANCEL_CLIENT_DISCONNECT,
+            OVERRIDE_OUTCOME_CANCEL_OTHER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    private @interface OverrideOutcome {}
+
+    private static final int DEFAULT_USER_ACTIVITY = USER_ACTIVITY_EVENT_OTHER;
+    private static final long TIMEOUT_USER_INITIATED_REVERT_THRESHOLD_MILLIS = 5000L;
+    private static final long SEND_OVERRIDE_TIMEOUT_LOG_THRESHOLD_MILLIS = 1000L;
+
+    private Context mContext;
+    private int mScreenOffTimeoutMs;
+    private int mOverrideTimeoutMs = 0;
+    @VisibleForTesting
+    protected final SparseArray<WakefulnessSessionPowerGroup> mPowerGroups = new SparseArray<>();
+    @VisibleForTesting
+    protected WakefulnessSessionFrameworkStatsLogger mWakefulnessSessionFrameworkStatsLogger;
+    private final Clock mClock;
+    private final Object mLock = new Object();
+
+    public WakefulnessSessionObserver(Context context, Injector injector) {
+        if (injector == null) {
+            injector = new Injector();
+        }
+
+        mContext = context;
+        mWakefulnessSessionFrameworkStatsLogger = injector
+                .getWakefulnessSessionFrameworkStatsLogger();
+        mClock = injector.getClock();
+        updateSettingScreenOffTimeout(context);
+
+        try {
+            final UserSwitchObserver observer = new UserSwitchObserver();
+            ActivityManager.getService().registerUserSwitchObserver(observer, TAG);
+        } catch (RemoteException e) {
+            // Shouldn't happen since in-process.
+        }
+
+        mOverrideTimeoutMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_screenTimeoutOverride);
+
+        mContext.getContentResolver()
+                .registerContentObserver(
+                        Settings.System.getUriFor(Settings.System.SCREEN_OFF_TIMEOUT),
+                        false,
+                        new ContentObserver(new Handler(mContext.getMainLooper())) {
+                            @Override
+                            public void onChange(boolean selfChange) {
+                                updateSettingScreenOffTimeout(mContext);
+                            }
+                        },
+                        UserHandle.USER_ALL);
+
+        mPowerGroups.append(
+                Display.DEFAULT_DISPLAY_GROUP,
+                new WakefulnessSessionPowerGroup(Display.DEFAULT_DISPLAY_GROUP));
+    }
+
+    /**
+     * Track the user activity event.
+     *
+     * @param eventTime Activity time, in uptime millis.
+     * @param powerGroupId Power Group Id for this user activity
+     * @param event Activity type as defined in {@link PowerManager}. {@link
+     *     android.hardware.display.DisplayManagerInternal.DisplayPowerRequest}
+     */
+    public void notifyUserActivity(
+            long eventTime, int powerGroupId, @PowerManager.UserActivityEvent int event) {
+        if (!mPowerGroups.contains(powerGroupId)) {
+            mPowerGroups.append(powerGroupId, new WakefulnessSessionPowerGroup(powerGroupId));
+        }
+        mPowerGroups.get(powerGroupId).notifyUserActivity(eventTime, event);
+    }
+
+    /**
+     * Track the system wakefulness
+     *
+     * @param powerGroupId Power Group Id for this wakefulness changes
+     * @param wakefulness Wakefulness as defined in {@link PowerManagerInternal}
+     * @param changeReason Reason of the go to sleep in
+     * {@link PowerManager.GoToSleepReason} or {@link PowerManager.WakeReason}
+     * @param eventTime timestamp of the wakefulness changes
+     */
+    public void onWakefulnessChangeStarted(int powerGroupId, int wakefulness, int changeReason,
+            long eventTime) {
+        if (!mPowerGroups.contains(powerGroupId)) {
+            mPowerGroups.append(powerGroupId, new WakefulnessSessionPowerGroup(powerGroupId));
+        }
+        mPowerGroups.get(powerGroupId).onWakefulnessChangeStarted(wakefulness, changeReason,
+                eventTime);
+    }
+
+    /**
+     * Track the acquired wakelocks
+     *
+     * @param flags wakelocks to be acquired {@link PowerManager}
+     */
+    public void onWakeLockAcquired(int flags) {
+        int maskedFlag = flags & PowerManager.WAKE_LOCK_LEVEL_MASK;
+        if (maskedFlag == PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK) {
+            for (int idx = 0; idx < mPowerGroups.size(); idx++) {
+                mPowerGroups.valueAt(idx).acquireTimeoutOverrideWakeLock();
+            }
+        }
+    }
+
+    /**
+     * Track the released wakelocks
+     *
+     * @param flags wakelocks to be released {@link PowerManager}
+     * @param releaseReason the reason to release wakelock
+     * {@link ScreenTimeoutOverridePolicy.ReleaseReason}
+     */
+    public void onWakeLockReleased(int flags, int releaseReason) {
+        int maskedFlag = flags & PowerManager.WAKE_LOCK_LEVEL_MASK;
+        if (maskedFlag == PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK) {
+            for (int idx = 0; idx < mPowerGroups.size(); idx++) {
+                mPowerGroups.valueAt(idx).releaseTimeoutOverrideWakeLock(releaseReason);
+            }
+        }
+    }
+
+    /**
+     * Remove the inactive power group
+     *
+     * @param powerGroupId Power Group Id that should be removed
+     */
+    public void removePowerGroup(int powerGroupId) {
+        if (mPowerGroups.contains((powerGroupId))) {
+            mPowerGroups.delete(powerGroupId);
+        }
+    }
+
+    void dump(PrintWriter writer) {
+        writer.println();
+        writer.println("Wakefulness Session Observer:");
+        writer.println("default timeout: " + mScreenOffTimeoutMs);
+        writer.println("override timeout: " + mOverrideTimeoutMs);
+        IndentingPrintWriter indentingPrintWriter = new IndentingPrintWriter(writer);
+        indentingPrintWriter.increaseIndent();
+        for (int idx = 0; idx < mPowerGroups.size(); idx++) {
+            mPowerGroups.valueAt(idx).dump(indentingPrintWriter);
+        }
+        writer.println();
+    }
+
+    private void updateSettingScreenOffTimeout(Context context) {
+        synchronized (mLock) {
+            mScreenOffTimeoutMs = Settings.System.getIntForUser(
+                    context.getContentResolver(),
+                    Settings.System.SCREEN_OFF_TIMEOUT,
+                    DEFAULT_SCREEN_OFF_TIMEOUT,
+                    UserHandle.USER_CURRENT);
+        }
+    }
+
+    private int getScreenOffTimeout() {
+        synchronized (mLock) {
+            return mScreenOffTimeoutMs;
+        }
+    }
+
+    /** Screen Session by each power group */
+    @VisibleForTesting
+    protected class WakefulnessSessionPowerGroup {
+        private static final long TIMEOUT_OFF_RESET_TIMESTAMP = -1;
+
+        private int mPowerGroupId;
+        private int mCurrentWakefulness;
+        private boolean mIsInteractive = false;
+        // state on start timestamp: will be used in state off to calculate the duration of state on
+        private long mInteractiveStateOnStartTimestamp;
+        @VisibleForTesting
+        protected long mCurrentUserActivityTimestamp;
+        @VisibleForTesting
+        protected @PowerManager.UserActivityEvent int mCurrentUserActivityEvent;
+        @VisibleForTesting
+        protected long mPrevUserActivityTimestamp;
+        @VisibleForTesting
+        protected @PowerManager.UserActivityEvent int mPrevUserActivityEvent;
+        // to track the Override Timeout is set (that is, on SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK)
+        private int mTimeoutOverrideWakeLockCounter = 0;
+        // The timestamp when Override Timeout is set to false
+        private @ScreenTimeoutOverridePolicy.ReleaseReason int mTimeoutOverrideReleaseReason;
+        // The timestamp when state off by timeout occurs
+        // will set TIMEOUT_OFF_RESET_TIMESTAMP if state on or state off by power button
+        private long mTimeoutOffTimestamp;
+        // The timestamp for the latest logTimeoutOverrideEvent calling
+        private long mSendOverrideTimeoutLogTimestamp;
+
+        public WakefulnessSessionPowerGroup(int powerGroupId) {
+            mCurrentUserActivityEvent = DEFAULT_USER_ACTIVITY;
+            mCurrentUserActivityTimestamp = -1;
+            mPrevUserActivityEvent = DEFAULT_USER_ACTIVITY;
+            mPrevUserActivityTimestamp = -1;
+            mPowerGroupId = powerGroupId;
+        }
+
+        public void notifyUserActivity(long eventTime, @PowerManager.UserActivityEvent int event) {
+            // only track when user activity changes
+            if (event == mCurrentUserActivityEvent) {
+                return;
+            }
+            mPrevUserActivityEvent = mCurrentUserActivityEvent;
+            mCurrentUserActivityEvent = event;
+            mPrevUserActivityTimestamp = mCurrentUserActivityTimestamp;
+            mCurrentUserActivityTimestamp = eventTime;
+        }
+
+        public void onWakefulnessChangeStarted(int wakefulness, int changeReason, long eventTime) {
+            mCurrentWakefulness = wakefulness;
+            if (mIsInteractive == isInteractive(wakefulness)) {
+                return;
+            }
+
+            mIsInteractive = isInteractive(wakefulness);
+            if (mIsInteractive) {
+                mInteractiveStateOnStartTimestamp = eventTime;
+
+                // Log the outcome of screen timeout override (USER INITIATED REVERT),
+                // when user initiates to revert the screen off state in a short period.
+                if (mTimeoutOffTimestamp != TIMEOUT_OFF_RESET_TIMESTAMP) {
+                    long offToOnDurationMs = eventTime - mTimeoutOffTimestamp;
+                    if (offToOnDurationMs < TIMEOUT_USER_INITIATED_REVERT_THRESHOLD_MILLIS) {
+                        mWakefulnessSessionFrameworkStatsLogger.logTimeoutOverrideEvent(
+                                mPowerGroupId,
+                                OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT,
+                                mOverrideTimeoutMs,
+                                getScreenOffTimeout());
+                        mSendOverrideTimeoutLogTimestamp = eventTime;
+                    }
+                    mTimeoutOffTimestamp = TIMEOUT_OFF_RESET_TIMESTAMP;
+                }
+            } else {
+                int lastUserActivity = mCurrentUserActivityEvent;
+                long lastUserActivityDurationMs = eventTime - mCurrentUserActivityTimestamp;
+                @OffReason int interactiveStateOffReason = OFF_REASON_UNKNOWN;
+                int reducedInteractiveStateOnDurationMs = 0;
+
+                if (changeReason == PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON) {
+                    interactiveStateOffReason = OFF_REASON_POWER_BUTTON;
+
+                    // Power Off will be triggered by USER_ACTIVITY_EVENT_BUTTON
+                    // The metric wants to record the previous activity before EVENT_BUTTON
+                    lastUserActivity = mPrevUserActivityEvent;
+                    lastUserActivityDurationMs = eventTime - mPrevUserActivityTimestamp;
+
+                    if (isInOverrideTimeout()
+                            || mTimeoutOverrideReleaseReason == RELEASE_REASON_USER_ACTIVITY_BUTTON
+                    ) {
+                        mWakefulnessSessionFrameworkStatsLogger.logTimeoutOverrideEvent(
+                                mPowerGroupId,
+                                OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON,
+                                mOverrideTimeoutMs,
+                                getScreenOffTimeout());
+                        mSendOverrideTimeoutLogTimestamp = eventTime;
+                        mTimeoutOverrideReleaseReason = RELEASE_REASON_UNKNOWN; // reset the reason
+                    }
+                } else if (changeReason == PowerManager.GO_TO_SLEEP_REASON_TIMEOUT) {
+                    // Interactive Off reason is timeout
+                    interactiveStateOffReason = OFF_REASON_TIMEOUT;
+
+                    lastUserActivity = mCurrentUserActivityEvent;
+                    lastUserActivityDurationMs = eventTime - mCurrentUserActivityTimestamp;
+
+                    // Log the outcome of screen timeout override when the early screen
+                    // timeout has been done successfully.
+                    if (isInOverrideTimeout()) {
+                        reducedInteractiveStateOnDurationMs =
+                                getScreenOffTimeout() - mOverrideTimeoutMs;
+
+                        mWakefulnessSessionFrameworkStatsLogger.logTimeoutOverrideEvent(
+                                mPowerGroupId,
+                                OVERRIDE_OUTCOME_TIMEOUT_SUCCESS,
+                                mOverrideTimeoutMs,
+                                getScreenOffTimeout());
+                        mSendOverrideTimeoutLogTimestamp = eventTime;
+
+                        // Record a timestamp to track if the user initiates to revert from off
+                        // state instantly
+                        mTimeoutOffTimestamp = eventTime;
+                    }
+                }
+
+                long interactiveStateOnDurationMs =
+                        eventTime - mInteractiveStateOnStartTimestamp;
+                mWakefulnessSessionFrameworkStatsLogger.logSessionEvent(
+                        mPowerGroupId,
+                        interactiveStateOffReason,
+                        interactiveStateOnDurationMs,
+                        lastUserActivity,
+                        lastUserActivityDurationMs,
+                        reducedInteractiveStateOnDurationMs);
+            }
+        }
+
+        public void acquireTimeoutOverrideWakeLock() {
+            synchronized (mLock) {
+                mTimeoutOverrideWakeLockCounter++;
+            }
+        }
+
+        public void releaseTimeoutOverrideWakeLock(
+                @ScreenTimeoutOverridePolicy.ReleaseReason  int releaseReason) {
+            synchronized (mLock) {
+                mTimeoutOverrideWakeLockCounter--;
+            }
+
+            if (!isInOverrideTimeout()) {
+                mTimeoutOverrideReleaseReason = releaseReason;
+                long now = mClock.uptimeMillis();
+
+                // Log the outcome of screen timeout override (USER INTERACTIVE or DISCONNECT),
+                // when early screen timeout be canceled.
+                // Note: Set the threshold to avoid sending this log repeatly after other outcomes.
+                long sendOverrideTimeoutLogDuration = now - mSendOverrideTimeoutLogTimestamp;
+                boolean sendOverrideTimeoutLogSoon = sendOverrideTimeoutLogDuration
+                        < SEND_OVERRIDE_TIMEOUT_LOG_THRESHOLD_MILLIS;
+                if (!sendOverrideTimeoutLogSoon) {
+                    @OverrideOutcome int outcome = OVERRIDE_OUTCOME_UNKNOWN;
+                    switch (releaseReason) {
+                        case RELEASE_REASON_USER_ACTIVITY_ATTENTION:
+                        case RELEASE_REASON_USER_ACTIVITY_OTHER:
+                        case RELEASE_REASON_USER_ACTIVITY_BUTTON:
+                        case RELEASE_REASON_USER_ACTIVITY_TOUCH:
+                        case RELEASE_REASON_USER_ACTIVITY_ACCESSIBILITY:
+                            outcome = OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION;
+                            break;
+                        case RELEASE_REASON_SCREEN_LOCK:
+                        case RELEASE_REASON_NON_INTERACTIVE:
+                            outcome = OVERRIDE_OUTCOME_CANCEL_CLIENT_DISCONNECT;
+                            break;
+                        default:
+                            outcome = OVERRIDE_OUTCOME_UNKNOWN;
+                    }
+                    mWakefulnessSessionFrameworkStatsLogger.logTimeoutOverrideEvent(
+                            mPowerGroupId,
+                            outcome,
+                            mOverrideTimeoutMs,
+                            getScreenOffTimeout());
+                }
+            }
+        }
+
+        @VisibleForTesting
+        protected boolean isInOverrideTimeout() {
+            synchronized (mLock) {
+                return (mTimeoutOverrideWakeLockCounter > 0);
+            }
+        }
+
+        void dump(IndentingPrintWriter writer) {
+            final long now = mClock.uptimeMillis();
+
+            writer.println("Wakefulness Session Power Group powerGroupId: " + mPowerGroupId);
+            writer.increaseIndent();
+            writer.println("current wakefulness: " + mCurrentWakefulness);
+            writer.println("current user activity event: " + mCurrentUserActivityEvent);
+            final long currentUserActivityDurationMs = now - mCurrentUserActivityTimestamp;
+            writer.println("current user activity duration: " + currentUserActivityDurationMs);
+            writer.println("previous user activity event: " + mPrevUserActivityEvent);
+            final long prevUserActivityDurationMs = now - mPrevUserActivityTimestamp;
+            writer.println("previous user activity duration: " + prevUserActivityDurationMs);
+            writer.println("is in override timeout: " + isInOverrideTimeout());
+            writer.decreaseIndent();
+        }
+    }
+
+    /** Log screen session atoms */
+    protected static class WakefulnessSessionFrameworkStatsLogger {
+        public void logSessionEvent(
+                int powerGroupId,
+                @OffReason int interactiveStateOffReason,
+                long interactiveStateOnDurationMs,
+                @PowerManager.UserActivityEvent int userActivityEvent,
+                long lastUserActivityEventDurationMs,
+                int reducedInteractiveStateOnDurationMs) {
+            int logUserActivityEvent = convertToLogUserActivityEvent(userActivityEvent);
+            FrameworkStatsLog.write(
+                    FrameworkStatsLog.SCREEN_INTERACTIVE_SESSION_REPORTED,
+                    powerGroupId,
+                    interactiveStateOffReason,
+                    interactiveStateOnDurationMs,
+                    logUserActivityEvent,
+                    lastUserActivityEventDurationMs,
+                    (long) reducedInteractiveStateOnDurationMs);
+        }
+
+        public void logTimeoutOverrideEvent(
+                int powerGroupId,
+                @OverrideOutcome int overrideOutcome,
+                int overrideTimeoutMs,
+                int defaultTimeoutMs) {
+            FrameworkStatsLog.write(
+                    FrameworkStatsLog.SCREEN_TIMEOUT_OVERRIDE_REPORTED,
+                    powerGroupId,
+                    overrideOutcome,
+                    (long) overrideTimeoutMs,
+                    (long) defaultTimeoutMs);
+        }
+
+        private static final int USER_ACTIVITY_OTHER = FrameworkStatsLog
+                .SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__OTHER;
+
+        private static final int USER_ACTIVITY_BUTTON = FrameworkStatsLog
+                .SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__BUTTON;
+
+        private static final int USER_ACTIVITY_TOUCH = FrameworkStatsLog
+                .SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__TOUCH;
+
+        private static final int USER_ACTIVITY_ACCESSIBILITY = FrameworkStatsLog
+                .SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__ACCESSIBILITY;
+        private static final int USER_ACTIVITY_ATTENTION = FrameworkStatsLog
+                .SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__ATTENTION;
+        private static final int USER_ACTIVITY_FACE_DOWN = FrameworkStatsLog
+                .SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__FACE_DOWN;
+
+        private static final int USER_ACTIVITY_DEVICE_STATE = FrameworkStatsLog
+                .SCREEN_INTERACTIVE_SESSION_REPORTED__LAST_USER_ACTIVITY_EVENT__DEVICE_STATE;
+
+        /**
+         * User Activity Event
+         * {@link android.os.statsd.power.ScreenInteractiveSessionReported.UserActivityEvent}.
+         */
+        @IntDef(prefix = {"USER_ACTIVITY_"}, value = {
+                USER_ACTIVITY_OTHER,
+                USER_ACTIVITY_BUTTON,
+                USER_ACTIVITY_TOUCH,
+                USER_ACTIVITY_ACCESSIBILITY,
+                USER_ACTIVITY_ATTENTION,
+                USER_ACTIVITY_FACE_DOWN,
+                USER_ACTIVITY_DEVICE_STATE,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        private @interface UserActivityEvent {}
+
+        private @UserActivityEvent int convertToLogUserActivityEvent(
+                @PowerManager.UserActivityEvent int userActivity) {
+            switch (userActivity) {
+                case PowerManager.USER_ACTIVITY_EVENT_OTHER:
+                    return USER_ACTIVITY_OTHER;
+                case PowerManager.USER_ACTIVITY_EVENT_BUTTON:
+                    return USER_ACTIVITY_BUTTON;
+                case PowerManager.USER_ACTIVITY_EVENT_TOUCH:
+                    return USER_ACTIVITY_TOUCH;
+                case PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY:
+                    return USER_ACTIVITY_ACCESSIBILITY;
+                case PowerManager.USER_ACTIVITY_EVENT_ATTENTION:
+                    return USER_ACTIVITY_ATTENTION;
+                case PowerManager.USER_ACTIVITY_EVENT_FACE_DOWN:
+                    return USER_ACTIVITY_FACE_DOWN;
+                case PowerManager.USER_ACTIVITY_EVENT_DEVICE_STATE:
+                    return USER_ACTIVITY_DEVICE_STATE;
+            }
+            return USER_ACTIVITY_OTHER;
+        }
+    }
+
+    /** To observe and do actions if users switch */
+    private final class UserSwitchObserver extends SynchronousUserSwitchObserver {
+        @Override
+        public void onUserSwitching(int newUserId) throws RemoteException {
+            updateSettingScreenOffTimeout(mContext);
+        }
+    }
+
+    @VisibleForTesting
+    interface Clock {
+        long uptimeMillis();
+    }
+
+    @VisibleForTesting
+    static class Injector {
+        WakefulnessSessionFrameworkStatsLogger getWakefulnessSessionFrameworkStatsLogger() {
+            return new WakefulnessSessionFrameworkStatsLogger();
+        }
+
+        Clock getClock() {
+            return SystemClock::uptimeMillis;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index 6e17fd3..4ddd546 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -91,7 +91,7 @@
     @GuardedBy("mLock")
     private final ArrayMap<Integer, ArrayMap<IBinder, ArraySet<AppHintSession>>> mActiveSessions;
 
-    /** Lock to protect mActiveSessions. */
+    /** Lock to protect mActiveSessions and the UidObserver. */
     private final Object mLock = new Object();
 
     @GuardedBy("mNonIsolatedTidsLock")
@@ -318,11 +318,10 @@
 
     @VisibleForTesting
     final class MyUidObserver extends UidObserver {
-        private final Object mCacheLock = new Object();
-        @GuardedBy("mCacheLock")
+        @GuardedBy("mLock")
         private final SparseIntArray mProcStatesCache = new SparseIntArray();
         public boolean isUidForeground(int uid) {
-            synchronized (mCacheLock) {
+            synchronized (mLock) {
                 return mProcStatesCache.get(uid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)
                         <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
             }
@@ -331,10 +330,8 @@
         @Override
         public void onUidGone(int uid, boolean disabled) {
             FgThread.getHandler().post(() -> {
-                synchronized (mCacheLock) {
-                    mProcStatesCache.delete(uid);
-                }
                 synchronized (mLock) {
+                    mProcStatesCache.delete(uid);
                     ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap = mActiveSessions.get(uid);
                     if (tokenMap == null) {
                         return;
@@ -357,7 +354,7 @@
         @Override
         public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
             FgThread.getHandler().post(() -> {
-                synchronized (mCacheLock) {
+                synchronized (mLock) {
                     if (powerhintThreadCleanup()) {
                         final boolean before = isUidForeground(uid);
                         mProcStatesCache.put(uid, procState);
@@ -370,9 +367,7 @@
                     } else {
                         mProcStatesCache.put(uid, procState);
                     }
-                }
-                boolean shouldAllowUpdate = isUidForeground(uid);
-                synchronized (mLock) {
+                    boolean shouldAllowUpdate = isUidForeground(uid);
                     ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap = mActiveSessions.get(uid);
                     if (tokenMap == null) {
                         return;
@@ -691,10 +686,10 @@
                     }
                 }
 
-                AppHintSession hs = new AppHintSession(callingUid, callingTgid, tids, token,
-                        halSessionPtr, durationNanos);
                 logPerformanceHintSessionAtom(callingUid, halSessionPtr, durationNanos, tids);
                 synchronized (mLock) {
+                    AppHintSession hs = new AppHintSession(callingUid, callingTgid, tids, token,
+                            halSessionPtr, durationNanos);
                     ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap =
                             mActiveSessions.get(callingUid);
                     if (tokenMap == null) {
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index fe4522a..c5683f3 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -99,6 +99,7 @@
 import android.window.SizeConfigurationBuckets;
 import android.window.TransitionInfo;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.AssistUtils;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.protolog.common.ProtoLog;
@@ -108,6 +109,9 @@
 import com.android.server.pm.pkg.AndroidPackage;
 import com.android.server.uri.GrantUri;
 import com.android.server.uri.NeededUriGrants;
+import com.android.server.utils.quota.Categorizer;
+import com.android.server.utils.quota.Category;
+import com.android.server.utils.quota.CountQuotaTracker;
 import com.android.server.vr.VrManagerInternal;
 
 /**
@@ -123,6 +127,13 @@
     private final ActivityTaskSupervisor mTaskSupervisor;
     private final Context mContext;
 
+    // Prevent malicious app abusing the Activity#setPictureInPictureParams API
+    @VisibleForTesting CountQuotaTracker mSetPipAspectRatioQuotaTracker;
+    // Limit to 60 times / minute
+    private static final int SET_PIP_ASPECT_RATIO_LIMIT = 60;
+    // The timeWindowMs here can not be smaller than QuotaTracker#MIN_WINDOW_SIZE_MS
+    private static final long SET_PIP_ASPECT_RATIO_TIME_WINDOW_MS = 60_000;
+
     /** Wrapper around VoiceInteractionServiceManager. */
     private AssistUtils mAssistUtils;
 
@@ -1035,6 +1046,25 @@
                     + ": Current activity does not support picture-in-picture.");
         }
 
+        // Rate limit how frequent an app can request aspect ratio change via
+        // Activity#setPictureInPictureParams
+        final int userId = UserHandle.getCallingUserId();
+        if (mSetPipAspectRatioQuotaTracker == null) {
+            mSetPipAspectRatioQuotaTracker = new CountQuotaTracker(mContext,
+                    Categorizer.SINGLE_CATEGORIZER);
+            mSetPipAspectRatioQuotaTracker.setCountLimit(Category.SINGLE_CATEGORY,
+                    SET_PIP_ASPECT_RATIO_LIMIT, SET_PIP_ASPECT_RATIO_TIME_WINDOW_MS);
+        }
+        if (r.pictureInPictureArgs.hasSetAspectRatio()
+                && params.hasSetAspectRatio()
+                && !r.pictureInPictureArgs.getAspectRatio().equals(
+                params.getAspectRatio())
+                && !mSetPipAspectRatioQuotaTracker.noteEvent(
+                userId, r.packageName, "setPipAspectRatio")) {
+            throw new IllegalStateException(caller
+                    + ": Too many PiP aspect ratio change requests from " + r.packageName);
+        }
+
         final float minAspectRatio = mContext.getResources().getFloat(
                 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
         final float maxAspectRatio = mContext.getResources().getFloat(
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index d0c6e15..4c53e0f 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -269,6 +269,8 @@
                                     customAppTransition.mBackgroundColor);
                         }
                     }
+                    infoBuilder.setLetterboxColor(currentActivity.mLetterboxUiController
+                            .getLetterboxBackgroundColor().toArgb());
                     removedWindowContainer = currentActivity;
                     prevTask = prevActivities.get(0).getTask();
                     backType = BackNavigationInfo.TYPE_CROSS_ACTIVITY;
diff --git a/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java b/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
index 61f5679..f04b4af 100644
--- a/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
@@ -114,6 +114,18 @@
             return RESULT_DONE;
         }
 
+        // TODO(b/336998072) - Find a better solution to this that makes use of the logic from
+        //  TaskLaunchParamsModifier. Put logic in common utils, return RESULT_CONTINUE, inherit
+        //  from parent class, etc.
+        if (outParams.mPreferredTaskDisplayArea == null && task.getRootTask() != null) {
+            appendLog("display-from-task=" + task.getRootTask().getDisplayId());
+            outParams.mPreferredTaskDisplayArea = task.getRootTask().getDisplayArea();
+        }
+
+        if (phase == PHASE_DISPLAY_AREA) {
+            return RESULT_DONE;
+        }
+
         if (!currentParams.mBounds.isEmpty()) {
             appendLog("currentParams has bounds set, not overriding");
             return RESULT_SKIP;
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index da1581e..683efde 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -1316,7 +1316,7 @@
         return shouldShowLetterboxUi;
     }
 
-    private Color getLetterboxBackgroundColor() {
+    Color getLetterboxBackgroundColor() {
         final WindowState w = mActivityRecord.findMainWindow();
         if (w == null || w.isLetterboxedForDisplayCutout()) {
             return Color.valueOf(Color.BLACK);
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index dd538de..312c4be 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -60,6 +60,7 @@
 import android.view.WindowInsets.Type;
 import android.window.PictureInPictureSurfaceTransaction;
 import android.window.TaskSnapshot;
+import android.window.WindowAnimationState;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.IResultReceiver;
@@ -371,6 +372,12 @@
                 Binder.restoreCallingIdentity(token);
             }
         }
+
+        @Override
+        public void handOffAnimation(
+                RemoteAnimationTarget[] targets, WindowAnimationState[] states) {
+            // unused legacy implementation
+        }
     };
 
     /**
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 622a809..6003c1b 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2477,6 +2477,7 @@
             final DisplayContent display = getChildAt(displayNdx);
             final boolean curResult = result;
             boolean[] resumedOnDisplay = new boolean[1];
+            final ActivityRecord topOfDisplay = display.topRunningActivity();
             display.forAllRootTasks(rootTask -> {
                 final ActivityRecord topRunningActivity = rootTask.topRunningActivity();
                 if (!rootTask.isFocusableAndVisible() || topRunningActivity == null) {
@@ -2490,8 +2491,7 @@
                     resumedOnDisplay[0] |= curResult;
                     return;
                 }
-                if (topRunningActivity.isState(RESUMED)
-                        && topRunningActivity == rootTask.getDisplayArea().topRunningActivity()) {
+                if (topRunningActivity.isState(RESUMED) && topRunningActivity == topOfDisplay) {
                     // Kick off any lingering app transitions form the MoveTaskToFront operation,
                     // but only consider the top activity on that display.
                     rootTask.executeAppTransition(targetOptions);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index f23a440..9a7f87d 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -199,6 +199,7 @@
 import com.android.server.am.ActivityManagerService;
 import com.android.server.am.AppTimeTracker;
 import com.android.server.uri.NeededUriGrants;
+import com.android.window.flags.Flags;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -3363,7 +3364,8 @@
         // If true, we want to get the Dimmer from the level above since we don't want to animate
         // the dim with the Task.
         if (!isRootTask() || (Dimmer.DIMMER_REFACTOR && isTranslucentAndVisible())
-                || isTranslucent(null)) {
+                || (Flags.getDimmerOnClosing() ? isTranslucentForTransition()
+                                                : isTranslucent(null))) {
             return super.getDimmer();
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index de7c0eb..616ab88 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -349,6 +349,7 @@
 import com.android.server.DisplayThread;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
+import com.android.server.SystemConfig;
 import com.android.server.UiThread;
 import com.android.server.Watchdog;
 import com.android.server.input.InputManagerService;
@@ -454,13 +455,12 @@
     /**
      * Use WMShell for app transition.
      */
-    public static final String ENABLE_SHELL_TRANSITIONS = "persist.wm.debug.shell_transit";
+    private static final String ENABLE_SHELL_TRANSITIONS = "persist.wm.debug.shell_transit";
 
     /**
      * @see #ENABLE_SHELL_TRANSITIONS
      */
-    public static final boolean sEnableShellTransitions =
-            SystemProperties.getBoolean(ENABLE_SHELL_TRANSITIONS, true);
+    public static final boolean sEnableShellTransitions = getShellTransitEnabled();
 
     /**
      * Allows a fullscreen windowing mode activity to launch in its desired orientation directly
@@ -10230,4 +10230,13 @@
             }
         }
     }
+
+    private static boolean getShellTransitEnabled() {
+        android.content.pm.FeatureInfo autoFeature = SystemConfig.getInstance()
+                .getAvailableFeatures().get(PackageManager.FEATURE_AUTOMOTIVE);
+        if (autoFeature != null && autoFeature.version >= 0) {
+            return SystemProperties.getBoolean(ENABLE_SHELL_TRANSITIONS, true);
+        }
+        return true;
+    }
 }
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 553f721..80bf5b9 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -143,7 +143,6 @@
     jmethodID getTouchCalibrationForInputDevice;
     jmethodID notifyDropWindow;
     jmethodID getParentSurfaceForPointers;
-    jmethodID getPackageUid;
 } gServiceClassInfo;
 
 static struct {
@@ -364,7 +363,6 @@
     void notifyDropWindow(const sp<IBinder>& token, float x, float y) override;
     void notifyDeviceInteraction(int32_t deviceId, nsecs_t timestamp,
                                  const std::set<gui::Uid>& uids) override;
-    gui::Uid getPackageUid(std::string package) override;
 
     /* --- PointerControllerPolicyInterface implementation --- */
 
@@ -1126,21 +1124,6 @@
     mInputManager->getMetricsCollector().notifyDeviceInteraction(deviceId, timestamp, uids);
 }
 
-gui::Uid NativeInputManager::getPackageUid(std::string package) {
-    ATRACE_CALL();
-    JNIEnv* env = jniEnv();
-    ScopedLocalFrame localFrame(env);
-
-    ScopedLocalRef<jstring> javaPackage(env, env->NewStringUTF(package.c_str()));
-    const jint uid =
-            env->CallIntMethod(mServiceObj, gServiceClassInfo.getPackageUid, javaPackage.get());
-    if (checkAndClearExceptionFromCallback(env, "getPackageUid")) {
-        LOG(FATAL) << __func__ << ": Failed to get UID for package: " << package;
-    }
-
-    return gui::Uid{static_cast<uint32_t>(uid)};
-}
-
 void NativeInputManager::notifySensorEvent(int32_t deviceId, InputDeviceSensorType sensorType,
                                            InputDeviceSensorAccuracy accuracy, nsecs_t timestamp,
                                            const std::vector<float>& values) {
@@ -3139,8 +3122,6 @@
     GET_METHOD_ID(gServiceClassInfo.getParentSurfaceForPointers, clazz,
                   "getParentSurfaceForPointers", "(I)J");
 
-    GET_METHOD_ID(gServiceClassInfo.getPackageUid, clazz, "getPackageUid", "(Ljava/lang/String;)I");
-
     // InputDevice
 
     FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
diff --git a/services/tests/dreamservicetests/Android.bp b/services/tests/dreamservicetests/Android.bp
index 86b3a6c..6369d45 100644
--- a/services/tests/dreamservicetests/Android.bp
+++ b/services/tests/dreamservicetests/Android.bp
@@ -18,7 +18,9 @@
         "mockito-target-minus-junit4",
         "services.core",
         "mockingservicestests-utils-mockito",
+        "platform-test-annotations",
         "servicestests-utils",
+        "testables",
     ],
 
     defaults: [
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
index 293ab7b..23314cd 100644
--- a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
@@ -19,17 +19,26 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.verify;
 
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
+import android.os.Looper;
+import android.platform.test.annotations.EnableFlags;
 import android.service.dreams.DreamService;
+import android.service.dreams.Flags;
+import android.service.dreams.IDreamOverlayCallback;
+import android.testing.TestableLooper;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -38,6 +47,18 @@
 public class DreamServiceTest {
     private static final String TEST_PACKAGE_NAME = "com.android.frameworks.dreamservicetests";
 
+    private TestableLooper mTestableLooper;
+
+    @Before
+    public void setup() throws Exception {
+        mTestableLooper = new TestableLooper(Looper.getMainLooper());
+    }
+
+    @After
+    public void tearDown() {
+        mTestableLooper.destroy();
+    }
+
     @Test
     public void testMetadataParsing() throws PackageManager.NameNotFoundException {
         final String testDreamClassName = "com.android.server.dreams.TestDreamService";
@@ -70,4 +91,76 @@
                 PackageManager.ComponentInfoFlags.of(PackageManager.GET_META_DATA));
         return DreamService.getDreamMetadata(context, si);
     }
+
+    /**
+     * Verifies progressing a {@link DreamService} to creation
+     */
+    @Test
+    public void testCreate() throws Exception {
+        final TestDreamEnvironment environment = new TestDreamEnvironment.Builder(mTestableLooper)
+                .setShouldShowComplications(true)
+                .build();
+        assertTrue(environment.advance(TestDreamEnvironment.DREAM_STATE_CREATE));
+    }
+
+    /**
+     * Verifies progressing a {@link DreamService}  to binding
+     */
+    @Test
+    public void testBind() throws Exception {
+        final TestDreamEnvironment environment = new TestDreamEnvironment.Builder(mTestableLooper)
+                .setShouldShowComplications(true)
+                .build();
+        assertTrue(environment.advance(TestDreamEnvironment.DREAM_STATE_BIND));
+    }
+
+    /**
+     * Verifies progressing a {@link DreamService} through
+     * {@link android.service.dreams.DreamActivity} creation.
+     */
+    @Test
+    public void testDreamActivityCreate() throws Exception {
+        final TestDreamEnvironment environment = new TestDreamEnvironment.Builder(mTestableLooper)
+                .setShouldShowComplications(true)
+                .build();
+        assertTrue(environment.advance(TestDreamEnvironment.DREAM_STATE_DREAM_ACTIVITY_CREATED));
+    }
+
+    /**
+     * Verifies progressing a {@link DreamService} through starting.
+     */
+    @Test
+    public void testStart() throws Exception {
+        final TestDreamEnvironment environment = new TestDreamEnvironment.Builder(mTestableLooper)
+                .setShouldShowComplications(true)
+                .build();
+        assertTrue(environment.advance(TestDreamEnvironment.DREAM_STATE_STARTED));
+    }
+
+    /**
+     * Verifies progressing a {@link DreamService} through waking.
+     */
+    @Test
+    public void testWake() throws Exception {
+        final TestDreamEnvironment environment = new TestDreamEnvironment.Builder(mTestableLooper)
+                .setShouldShowComplications(true)
+                .build();
+        assertTrue(environment.advance(TestDreamEnvironment.DREAM_STATE_WOKEN));
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_DREAM_WAKE_REDIRECT)
+    public void testRedirect() throws Exception {
+        TestDreamEnvironment environment = new TestDreamEnvironment.Builder(mTestableLooper)
+                .setDreamOverlayPresent(true)
+                .setShouldShowComplications(true)
+                .build();
+
+        environment.advance(TestDreamEnvironment.DREAM_STATE_STARTED);
+        final IDreamOverlayCallback overlayCallback = environment.getDreamOverlayCallback();
+        overlayCallback.onRedirectWake(true);
+        environment.resetClientInvocations();
+        environment.advance(TestDreamEnvironment.DREAM_STATE_WOKEN);
+        verify(environment.getDreamOverlayClient()).onWakeRequested();
+    }
 }
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java
new file mode 100644
index 0000000..ef85ba5
--- /dev/null
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.dreams;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.description;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.annotation.IntDef;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IRemoteCallback;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.service.dreams.DreamActivity;
+import android.service.dreams.DreamOverlayConnectionHandler;
+import android.service.dreams.DreamService;
+import android.service.dreams.IDreamManager;
+import android.service.dreams.IDreamOverlayCallback;
+import android.service.dreams.IDreamOverlayClient;
+import android.service.dreams.IDreamService;
+import android.testing.TestableLooper;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowInsetsController;
+import android.view.WindowManager;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.function.Consumer;
+
+
+/**
+ * {@link TestDreamEnvironment} sets up entire testing environment around a dream service, allowing
+ * bring-up and interaction around the dream.
+ *
+ * @hide
+ */
+@VisibleForTesting
+public class TestDreamEnvironment {
+    private static final String FAKE_DREAM_PACKAGE_NAME = "com.foo.bar";
+    private static final ComponentName FAKE_DREAM_OVERLAY_COMPONENT =
+            ComponentName.createRelative(FAKE_DREAM_PACKAGE_NAME, ".OverlayComponent");
+    private static final String FAKE_DREAM_SETTINGS_ACTIVITY = ".SettingsActivity";
+    private static final ComponentName FAKE_DREAM_ACTIVITY_COMPONENT =
+            ComponentName.createRelative(FAKE_DREAM_PACKAGE_NAME, ".DreamActivity");
+    private static final ComponentName FAKE_DREAM_COMPONENT =
+            ComponentName.createRelative(FAKE_DREAM_PACKAGE_NAME, ".DreamService");
+
+    /** Initial state when creating a test environment */
+    public static final int DREAM_STATE_INIT = 0;
+
+    /** State where the dream has been created */
+    public static final int DREAM_STATE_CREATE = 1;
+
+    /** State where the dream has been bound to */
+    public static final int DREAM_STATE_BIND = 2;
+
+    /** State where the dream activity has been created and signaled back to the dream */
+    public static final int DREAM_STATE_DREAM_ACTIVITY_CREATED = 3;
+
+
+    /** State where the dream has started after being attached */
+    public static final int DREAM_STATE_STARTED = 4;
+
+    /** State where the dream has been woken */
+    public static final int DREAM_STATE_WOKEN = 5;
+
+
+    @IntDef(prefix = { "DREAM_STATE_" }, value = {
+            DREAM_STATE_INIT,
+            DREAM_STATE_CREATE,
+            DREAM_STATE_BIND,
+            DREAM_STATE_DREAM_ACTIVITY_CREATED,
+            DREAM_STATE_STARTED,
+            DREAM_STATE_WOKEN,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DreamState{}
+
+    /**
+     * A convenience builder for assembling a {@link TestDreamEnvironment}.
+     */
+    public static class Builder {
+        private final TestableLooper mLooper;
+        private boolean mShouldShowComplications;
+        private boolean mOverlayPresent;
+        private boolean mWindowless;
+
+        public Builder(TestableLooper looper) {
+            mLooper = looper;
+        }
+
+        /**
+         * Sets whether the dream should show complications.
+         * @param show {@code true} for showing complications, {@code false} otherwise.
+         * @return The updated {@link Builder}.
+         */
+        public Builder setShouldShowComplications(boolean show) {
+            mShouldShowComplications = show;
+            return this;
+        }
+
+        /**
+         * Sets whether a dream overlay is present
+         * @param present {@code true} if the overlay is present, {@code false} otherwise.
+         */
+        public Builder setDreamOverlayPresent(boolean present) {
+            mOverlayPresent = present;
+            return this;
+        }
+
+        /**
+         * Sets whether the dream should be windowless
+         */
+        public Builder setWindowless(boolean windowless) {
+            mWindowless = windowless;
+            return this;
+        }
+
+        /**
+         * Builds the a {@link TestDreamEnvironment} based on the builder.
+         */
+        public TestDreamEnvironment build() throws Exception {
+            return new TestDreamEnvironment(mLooper, mShouldShowComplications,
+                    mOverlayPresent, mWindowless);
+        }
+    }
+
+    private static class TestInjector implements DreamService.Injector {
+        @Mock
+        private Resources mResources;
+
+        @Mock
+        private PackageManager mPackageManager;
+
+        @Mock
+        private TypedArray mAttributes;
+
+        @Mock
+        private ServiceInfo mServiceInfo;
+
+        private final Handler mHandler;
+        private final IDreamManager mDreamManager;
+        private final DreamOverlayConnectionHandler mDreamOverlayConnectionHandler;
+
+        TestInjector(Looper looper,
+                IDreamManager dreamManager,
+                DreamOverlayConnectionHandler dreamOverlayConnectionHandler,
+                boolean shouldShowComplications) {
+            MockitoAnnotations.initMocks(this);
+            mHandler = new Handler(looper);
+            mDreamManager = dreamManager;
+            mDreamOverlayConnectionHandler = dreamOverlayConnectionHandler;
+            mServiceInfo.packageName = FAKE_DREAM_PACKAGE_NAME;
+            when(mAttributes.getBoolean(eq(R.styleable.Dream_showClockAndComplications),
+                    anyBoolean()))
+                    .thenReturn(shouldShowComplications);
+            when(mAttributes.getDrawable(eq(com.android.internal.R.styleable.Dream_previewImage)))
+                    .thenReturn(mock(Drawable.class));
+            when(mAttributes.getString(eq(com.android.internal.R.styleable.Dream_settingsActivity)))
+                    .thenReturn(FAKE_DREAM_SETTINGS_ACTIVITY);
+            when(mPackageManager.extractPackageItemInfoAttributes(any(), any(), any(), any()))
+                    .thenReturn(mAttributes);
+        }
+        @Override
+        public void init(Context context) {
+        }
+
+        @Override
+        public DreamOverlayConnectionHandler createOverlayConnection(
+                ComponentName overlayComponent) {
+            return mDreamOverlayConnectionHandler;
+        }
+
+        @Override
+        public ComponentName getDreamActivityComponent() {
+            return FAKE_DREAM_ACTIVITY_COMPONENT;
+        }
+
+        @Override
+        public ComponentName getDreamComponent() {
+            return FAKE_DREAM_COMPONENT;
+        }
+
+        @Override
+        public String getDreamPackageName() {
+            return FAKE_DREAM_PACKAGE_NAME;
+        }
+
+        @Override
+        public IDreamManager getDreamManager() {
+            return mDreamManager;
+        }
+
+        @Override
+        public ServiceInfo getServiceInfo() {
+            return mServiceInfo;
+        }
+
+        @Override
+        public Handler getHandler() {
+            return mHandler;
+        }
+
+        @Override
+        public PackageManager getPackageManager() {
+            return mPackageManager;
+        }
+
+        @Override
+        public Resources getResources() {
+            return mResources;
+        }
+    }
+
+    @Mock
+    private IDreamManager mDreamManager;
+
+    @Mock
+    private DreamOverlayConnectionHandler mDreamOverlayConnectionHandler;
+
+    @Mock
+    private DreamActivity mDreamActivity;
+
+    @Mock
+    private Window mActivityWindow;
+
+    @Mock
+    private View mDecorView;
+
+    @Mock
+    private IDreamOverlayClient mDreamOverlayClient;
+
+    private final TestableLooper mTestableLooper;
+    private final DreamService mService;
+    private final boolean mWindowless;
+
+    private IDreamService mDreamServiceWrapper;
+
+    private @DreamState int mCurrentDreamState = DREAM_STATE_INIT;
+
+    private IDreamOverlayCallback mDreamOverlayCallback;
+
+    private boolean mOverlayPresent;
+
+    public TestDreamEnvironment(
+            TestableLooper looper,
+            boolean shouldShowComplications,
+            boolean overlayPresent,
+            boolean windowless
+    ) {
+        MockitoAnnotations.initMocks(this);
+
+        mOverlayPresent = overlayPresent;
+        mWindowless = windowless;
+
+        mTestableLooper = looper;
+        final DreamService.Injector injector = new TestInjector(mTestableLooper.getLooper(),
+                mDreamManager, mDreamOverlayConnectionHandler, shouldShowComplications);
+
+        when(mDreamActivity.getWindow()).thenReturn(mActivityWindow);
+        when(mActivityWindow.getAttributes()).thenReturn(mock(WindowManager.LayoutParams.class));
+        when(mActivityWindow.getDecorView()).thenReturn(mDecorView);
+        when(mDreamOverlayConnectionHandler.bind()).thenReturn(true);
+
+        doAnswer((InvocationOnMock invocation) -> {
+            Consumer<IDreamOverlayClient> client =
+                    (Consumer<IDreamOverlayClient>) invocation.getArguments()[0];
+            client.accept(mDreamOverlayClient);
+            return null;
+        }).when(mDreamOverlayConnectionHandler).addConsumer(any());
+        when(mDecorView.getWindowInsetsController()).thenReturn(
+                mock(WindowInsetsController.class));
+
+        mService = new DreamService(injector);
+    }
+
+    /**
+     * Advances a dream to a given state, progressing through all previous states.
+     */
+    public boolean advance(@DreamState int state) throws Exception {
+        if (state <= mCurrentDreamState) {
+            return false;
+        }
+
+        do {
+            switch(++mCurrentDreamState) {
+                case DREAM_STATE_CREATE -> createDream();
+                case DREAM_STATE_BIND -> bindToDream();
+                case DREAM_STATE_DREAM_ACTIVITY_CREATED -> createDreamActivity();
+                case DREAM_STATE_STARTED -> startDream();
+                case DREAM_STATE_WOKEN -> wakeDream();
+            }
+        } while (mCurrentDreamState < state);
+
+        return true;
+    }
+
+    private void createDream() {
+        mService.onCreate();
+        mService.setWindowless(mWindowless);
+    }
+
+    private void bindToDream() {
+        final Intent intent = new Intent();
+
+        if (mOverlayPresent) {
+            DreamService.setDreamOverlayComponent(intent, FAKE_DREAM_OVERLAY_COMPONENT);
+        }
+
+        mDreamServiceWrapper = IDreamService.Stub.asInterface(mService.onBind(intent));
+
+        if (mOverlayPresent) {
+            // Ensure that the overlay has been bound by the dream.
+            verify(mDreamOverlayConnectionHandler,
+                    description("dream did not bind to the dream overlay")).bind();
+        }
+    }
+
+    private void createDreamActivity() throws RemoteException {
+        final IRemoteCallback callback = mock(IRemoteCallback.class);
+        mDreamServiceWrapper.attach(mock(IBinder.class), false, false, callback);
+        mTestableLooper.processAllMessages();
+
+        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mDreamManager,
+                description("dream manager was not informed to start the dream activity"))
+                .startDreamActivity(intentCaptor.capture());
+        final Intent intent = intentCaptor.getValue();
+
+        final DreamService.DreamActivityCallbacks dreamActivityCallbacks =
+                DreamActivity.getCallback(intent);
+
+        dreamActivityCallbacks.onActivityCreated(mDreamActivity);
+    }
+
+    private void startDream() throws RemoteException {
+        final ArgumentCaptor<View.OnAttachStateChangeListener> attachChangeListenerCaptor =
+                ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
+        verify(mDecorView,
+                description("dream did not add a listener to when the decor view is attached"))
+                .addOnAttachStateChangeListener(attachChangeListenerCaptor.capture());
+
+        resetClientInvocations();
+        attachChangeListenerCaptor.getValue().onViewAttachedToWindow(mDecorView);
+
+        if (mOverlayPresent) {
+            final ArgumentCaptor<IDreamOverlayCallback> overlayCallbackCaptor =
+                    ArgumentCaptor.forClass(IDreamOverlayCallback.class);
+            verify(mDreamOverlayClient, description("dream client not informed of dream start"))
+                    .startDream(any(), overlayCallbackCaptor.capture(), any(), anyBoolean());
+
+            mDreamOverlayCallback = overlayCallbackCaptor.getValue();
+        }
+    }
+
+    private void wakeDream() throws RemoteException {
+        mService.wakeUp();
+    }
+
+    /**
+     * Retrieves the dream overlay callback.
+     */
+    public IDreamOverlayCallback getDreamOverlayCallback() throws Exception {
+        advance(DREAM_STATE_STARTED);
+        return mDreamOverlayCallback;
+    }
+
+    /**
+     * Resets interactions with the dream overlay client.
+     */
+    public void resetClientInvocations() {
+        Mockito.clearInvocations(mDreamOverlayClient);
+    }
+
+    /**
+     * Retrieves the dream overlay client.
+     */
+    public IDreamOverlayClient getDreamOverlayClient() {
+        return mDreamOverlayClient;
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 9590783..cc69c1d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -245,9 +245,11 @@
         LocalServices.removeServiceForTest(PackageManagerInternal.class);
     }
 
+    @SuppressWarnings("GuardedBy")
     @After
     public void tearDown() {
         sService.mOomAdjuster.resetInternal();
+        sService.mOomAdjuster.mActiveUids.clear();
     }
 
     private static <T> void setFieldValue(Class clazz, Object obj, String fieldName, T val) {
@@ -2816,6 +2818,69 @@
                 SCHED_GROUP_DEFAULT);
     }
 
+    @SuppressWarnings("GuardedBy")
+    @Test
+    public void testSetUidTempAllowlistState() {
+        final ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+                MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+        final ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+                MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
+        setProcessesToLru(app, app2);
+
+        // App1 binds to app2 and gets temp allowlisted.
+        bindService(app2, app, null, null, 0, mock(IBinder.class));
+        sService.mOomAdjuster.setUidTempAllowlistStateLSP(MOCKAPP_UID, true);
+
+        assertEquals(true, app.getUidRecord().isSetAllowListed());
+        assertEquals(true, app.mOptRecord.shouldNotFreeze());
+        assertEquals(true, app2.mOptRecord.shouldNotFreeze());
+
+        sService.mOomAdjuster.setUidTempAllowlistStateLSP(MOCKAPP_UID, false);
+        assertEquals(false, app.getUidRecord().isSetAllowListed());
+        assertEquals(false, app.mOptRecord.shouldNotFreeze());
+        assertEquals(false, app2.mOptRecord.shouldNotFreeze());
+    }
+
+    @SuppressWarnings("GuardedBy")
+    @Test
+    public void testSetUidTempAllowlistState_multipleAllowlistClients() {
+        final ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+                MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+        final ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+                MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
+        final ProcessRecord app3 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
+                MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
+        setProcessesToLru(app, app2, app3);
+
+        // App1 and app2 both bind to app3 and get temp allowlisted.
+        bindService(app3, app, null, null, 0, mock(IBinder.class));
+        bindService(app3, app2, null, null, 0, mock(IBinder.class));
+        sService.mOomAdjuster.setUidTempAllowlistStateLSP(MOCKAPP_UID, true);
+        sService.mOomAdjuster.setUidTempAllowlistStateLSP(MOCKAPP2_UID, true);
+
+        assertEquals(true, app.getUidRecord().isSetAllowListed());
+        assertEquals(true, app2.getUidRecord().isSetAllowListed());
+        assertEquals(true, app.mOptRecord.shouldNotFreeze());
+        assertEquals(true, app2.mOptRecord.shouldNotFreeze());
+        assertEquals(true, app3.mOptRecord.shouldNotFreeze());
+
+        // Remove app1 from allowlist.
+        sService.mOomAdjuster.setUidTempAllowlistStateLSP(MOCKAPP_UID, false);
+        assertEquals(false, app.getUidRecord().isSetAllowListed());
+        assertEquals(true, app2.getUidRecord().isSetAllowListed());
+        assertEquals(false, app.mOptRecord.shouldNotFreeze());
+        assertEquals(true, app2.mOptRecord.shouldNotFreeze());
+        assertEquals(true, app3.mOptRecord.shouldNotFreeze());
+
+        // Now remove app2 from allowlist.
+        sService.mOomAdjuster.setUidTempAllowlistStateLSP(MOCKAPP2_UID, false);
+        assertEquals(false, app.getUidRecord().isSetAllowListed());
+        assertEquals(false, app2.getUidRecord().isSetAllowListed());
+        assertEquals(false, app.mOptRecord.shouldNotFreeze());
+        assertEquals(false, app2.mOptRecord.shouldNotFreeze());
+        assertEquals(false, app3.mOptRecord.shouldNotFreeze());
+    }
+
     private ProcessRecord makeDefaultProcessRecord(int pid, int uid, String processName,
             String packageName, boolean hasShownUi) {
         return new ProcessRecordBuilder(pid, uid, processName, packageName).setHasShownUi(
@@ -3057,6 +3122,14 @@
                 receivers.addCurReceiver(mock(BroadcastRecord.class));
             }
             providers.setLastProviderTime(mLastProviderTime);
+
+            UidRecord uidRec = sService.mOomAdjuster.mActiveUids.get(mUid);
+            if (uidRec == null) {
+                uidRec = new UidRecord(mUid, sService);
+                sService.mOomAdjuster.mActiveUids.put(mUid, uidRec);
+            }
+            uidRec.addProcess(app);
+            app.setUidRecord(uidRec);
             return app;
         }
     }
diff --git a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
index 67409a4..5c74a80 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -1067,7 +1067,7 @@
             wakelockMap.remove((String) inv.getArguments()[1]);
             return null;
         }).when(mNotifierMock).onWakeLockReleased(anyInt(), anyString(), anyString(), anyInt(),
-                anyInt(), any(), any(), any());
+                anyInt(), any(), any(), any(), anyInt());
 
         //
         // TEST STARTS HERE
@@ -2777,7 +2777,7 @@
 
         mService.getBinderServiceInstance().releaseWakeLock(token, 0);
         verify(mNotifierMock).onWakeLockReleased(anyInt(), eq(tag), eq(packageName), anyInt(),
-                anyInt(), any(), any(), same(callback));
+                anyInt(), any(), any(), same(callback), anyInt());
     }
 
     /**
@@ -2796,8 +2796,8 @@
         when(callback1.asBinder()).thenReturn(callbackBinder1);
         mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
                 null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, callback1);
-        verify(mNotifierMock).onWakeLockAcquired(anyInt(), eq(tag), eq(packageName), anyInt(),
-                anyInt(), any(), any(), same(callback1));
+        verify(mNotifierMock).onWakeLockAcquired(anyInt(), eq(tag), eq(packageName),
+                anyInt(), anyInt(), any(), any(), same(callback1));
 
         final IWakeLockCallback callback2 = Mockito.mock(IWakeLockCallback.class);
         final IBinder callbackBinder2 = Mockito.mock(Binder.class);
@@ -2810,7 +2810,7 @@
 
         mService.getBinderServiceInstance().releaseWakeLock(token, 0);
         verify(mNotifierMock).onWakeLockReleased(anyInt(), eq(tag), eq(packageName), anyInt(),
-                anyInt(), any(), any(), same(callback2));
+                anyInt(), any(), any(), same(callback2), anyInt());
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java
index bfaf4959..f1b356a 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java
@@ -122,8 +122,6 @@
 
     @Before
     public void setup() throws RemoteException {
-        mSetFlagsRule.initAllFlagsToReleaseConfigDefault();
-
         MockitoAnnotations.initMocks(this);
         final Resources resources = InstrumentationRegistry.getContext().getResources();
 
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
index 7d90a8b..2b81d78 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
@@ -339,7 +339,6 @@
         LocalServices.removeServiceForTest(DisplayManagerInternal.class);
         LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternalMock);
 
-        mSetFlagsRule.initAllFlagsToReleaseConfigDefault();
         mSetFlagsRule.enableFlags(com.android.input.flags.Flags.FLAG_ENABLE_POINTER_CHOREOGRAPHER);
 
         doNothing().when(mInputManagerInternalMock)
diff --git a/services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java b/services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java
new file mode 100644
index 0000000..698f094
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/power/WakefulnessSessionObserverTest.java
@@ -0,0 +1,323 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+import static android.os.PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON;
+import static android.os.PowerManager.GO_TO_SLEEP_REASON_TIMEOUT;
+import static android.os.PowerManager.WAKE_REASON_POWER_BUTTON;
+
+import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_UNKNOWN;
+import static com.android.server.power.ScreenTimeoutOverridePolicy.RELEASE_REASON_USER_ACTIVITY_TOUCH;
+import static com.android.server.power.WakefulnessSessionObserver.OFF_REASON_POWER_BUTTON;
+import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON;
+import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION;
+import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_TIMEOUT_SUCCESS;
+import static com.android.server.power.WakefulnessSessionObserver.OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.res.Resources;
+import android.os.PowerManager;
+import android.os.PowerManagerInternal;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.test.mock.MockContentResolver;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.server.testutils.OffsettableClock;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class WakefulnessSessionObserverTest {
+    private static final int DEFAULT_SCREEN_OFF_TIMEOUT_MS = 30000;
+    private static final int OVERRIDE_SCREEN_OFF_TIMEOUT_MS = 15000;
+    private WakefulnessSessionObserver mWakefulnessSessionObserver;
+    private Context mContext;
+    private OffsettableClock mTestClock;
+    @Mock
+    private WakefulnessSessionObserver.WakefulnessSessionFrameworkStatsLogger
+            mWakefulnessSessionFrameworkStatsLogger;
+    private WakefulnessSessionObserver.Injector mInjector =
+            new WakefulnessSessionObserver.Injector() {
+                @Override
+                WakefulnessSessionObserver.WakefulnessSessionFrameworkStatsLogger
+                        getWakefulnessSessionFrameworkStatsLogger() {
+                    return mWakefulnessSessionFrameworkStatsLogger;
+                }
+                @Override
+                WakefulnessSessionObserver.Clock getClock() {
+                    return mTestClock::now;
+                }
+            };
+
+    @Before
+    public void setUp() {
+        mTestClock = new OffsettableClock.Stopped();
+
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(new ContextWrapper(
+                InstrumentationRegistry.getInstrumentation().getTargetContext()));
+        doReturn(mContext).when(mContext).getApplicationContext();
+
+        final Resources res = spy(mContext.getResources());
+        doReturn(OVERRIDE_SCREEN_OFF_TIMEOUT_MS).when(res).getInteger(
+                com.android.internal.R.integer.config_screenTimeoutOverride);
+        when(mContext.getResources()).thenReturn(res);
+        FakeSettingsProvider.clearSettingsProvider();
+        MockContentResolver mockContentResolver = new MockContentResolver();
+        mockContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        when(mContext.getContentResolver()).thenReturn(mockContentResolver);
+        Settings.System.putIntForUser(mockContentResolver, Settings.System.SCREEN_OFF_TIMEOUT,
+                DEFAULT_SCREEN_OFF_TIMEOUT_MS, UserHandle.USER_CURRENT);
+
+        mWakefulnessSessionObserver = new WakefulnessSessionObserver(mContext, mInjector);
+    }
+
+    @After
+    public void tearDown() {
+        FakeSettingsProvider.clearSettingsProvider();
+    }
+
+    @Test
+    public void testOnUserActivity_updateActivity() {
+        int firstActivity = PowerManager.USER_ACTIVITY_EVENT_BUTTON;
+        long firstActivityTimestamp = mTestClock.now();
+        int powerGroupId = 1;
+        mWakefulnessSessionObserver.notifyUserActivity(
+                firstActivityTimestamp, powerGroupId, firstActivity);
+        assertThat(mWakefulnessSessionObserver.mPowerGroups.get(powerGroupId)
+                .mCurrentUserActivityEvent).isEqualTo(firstActivity);
+
+        int newActivity = PowerManager.USER_ACTIVITY_EVENT_ATTENTION;
+        advanceTime(10L);
+        long newActivityTimestamp = mTestClock.now();
+        mWakefulnessSessionObserver.notifyUserActivity(
+                newActivityTimestamp, powerGroupId, newActivity);
+        assertThat(mWakefulnessSessionObserver.mPowerGroups.get(powerGroupId)
+                .mCurrentUserActivityEvent).isEqualTo(newActivity);
+        assertThat(mWakefulnessSessionObserver.mPowerGroups.get(powerGroupId)
+                .mCurrentUserActivityTimestamp).isEqualTo(newActivityTimestamp);
+        assertThat(mWakefulnessSessionObserver.mPowerGroups.get(powerGroupId)
+                .mPrevUserActivityEvent).isEqualTo(firstActivity);
+        assertThat(mWakefulnessSessionObserver.mPowerGroups.get(powerGroupId)
+                .mPrevUserActivityTimestamp).isEqualTo(firstActivityTimestamp);
+
+        int otherPowerGroupId = 2;
+        mWakefulnessSessionObserver.notifyUserActivity(
+                firstActivityTimestamp, otherPowerGroupId, firstActivity);
+        assertThat(mWakefulnessSessionObserver.mPowerGroups.get(otherPowerGroupId)
+                .mCurrentUserActivityEvent).isEqualTo(firstActivity);
+        assertThat(mWakefulnessSessionObserver.mPowerGroups.get(otherPowerGroupId)
+                .mCurrentUserActivityTimestamp).isEqualTo(firstActivityTimestamp);
+    }
+
+    @Test
+    public void testOnWakeLockAcquired() {
+        mWakefulnessSessionObserver.onWakeLockAcquired(PowerManager.DOZE_WAKE_LOCK);
+        for (int idx = 0; idx < mWakefulnessSessionObserver.mPowerGroups.size(); idx++) {
+            assertThat(mWakefulnessSessionObserver.mPowerGroups.valueAt(idx).isInOverrideTimeout())
+                    .isFalse();
+        }
+
+        mWakefulnessSessionObserver.onWakeLockAcquired(
+                PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK);
+        for (int idx = 0; idx < mWakefulnessSessionObserver.mPowerGroups.size(); idx++) {
+            assertThat(mWakefulnessSessionObserver.mPowerGroups.valueAt(idx).isInOverrideTimeout())
+                    .isTrue();
+        }
+    }
+
+    @Test
+    public void testOnWakeLockReleased() {
+        mWakefulnessSessionObserver.onWakeLockReleased(
+                PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK, RELEASE_REASON_UNKNOWN);
+        for (int idx = 0; idx < mWakefulnessSessionObserver.mPowerGroups.size(); idx++) {
+            assertThat(mWakefulnessSessionObserver.mPowerGroups.valueAt(idx).isInOverrideTimeout())
+                    .isFalse();
+        }
+    }
+
+    @Test
+    public void testOnWakefulnessChangeStarted_onDozing_UserActivityAttention_OverrideTimeout() {
+        int powerGroupId = 1;
+        mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+                powerGroupId,
+                PowerManagerInternal.WAKEFULNESS_AWAKE,
+                WAKE_REASON_POWER_BUTTON,
+                mTestClock.now());
+        mWakefulnessSessionObserver.notifyUserActivity(
+                mTestClock.now(), powerGroupId, PowerManager.USER_ACTIVITY_EVENT_ATTENTION);
+        mWakefulnessSessionObserver.onWakeLockAcquired(
+                PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK);
+        mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+                powerGroupId,
+                PowerManagerInternal.WAKEFULNESS_DOZING,
+                GO_TO_SLEEP_REASON_TIMEOUT,
+                mTestClock.now());
+
+        verify(mWakefulnessSessionFrameworkStatsLogger)
+                .logTimeoutOverrideEvent(
+                        powerGroupId, // powerGroupId
+                        OVERRIDE_OUTCOME_TIMEOUT_SUCCESS, // overrideOutcome
+                        OVERRIDE_SCREEN_OFF_TIMEOUT_MS, // override timeout ms
+                        DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default timeout ms
+    }
+
+    @Test
+    public void testOnWakefulnessChangeStarted_onDozing_UserActivityButton() {
+        advanceTime(5000L); // reset current timestamp for new test case
+        int powerGroupId = 2;
+        mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+                powerGroupId,
+                PowerManagerInternal.WAKEFULNESS_AWAKE,
+                WAKE_REASON_POWER_BUTTON,
+                mTestClock.now());
+
+        int userActivity = PowerManager.USER_ACTIVITY_EVENT_DEVICE_STATE;
+        long userActivityTime = mTestClock.now();
+        mWakefulnessSessionObserver.notifyUserActivity(
+                userActivityTime, powerGroupId, userActivity);
+        long advancedTime = 10L;
+        advanceTime(advancedTime);
+        mWakefulnessSessionObserver.notifyUserActivity(
+                userActivityTime, powerGroupId, PowerManager.USER_ACTIVITY_EVENT_BUTTON);
+        mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+                powerGroupId,
+                PowerManagerInternal.WAKEFULNESS_DOZING,
+                GO_TO_SLEEP_REASON_POWER_BUTTON,
+                mTestClock.now());
+
+        verify(mWakefulnessSessionFrameworkStatsLogger)
+                .logSessionEvent(
+                        powerGroupId, // powerGroupId
+                        OFF_REASON_POWER_BUTTON, // interactiveStateOffReason
+                        advancedTime, // interactiveStateOnDurationMs
+                        userActivity, // userActivity
+                        advancedTime,  // lastUserActivityEventDurationMs
+                        0); // reducedInteractiveStateOnDurationMs;
+
+        verify(mWakefulnessSessionFrameworkStatsLogger, never())
+                .logTimeoutOverrideEvent(anyInt(), anyInt(), anyInt(), anyInt());
+    }
+
+    @Test
+    public void testOnWakefulnessChangeStarted_onDozing_UserActivityButton_OverrideTimeout() {
+        int powerGroupId = 1;
+        mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+                powerGroupId,
+                PowerManagerInternal.WAKEFULNESS_AWAKE,
+                WAKE_REASON_POWER_BUTTON,
+                mTestClock.now());
+        mWakefulnessSessionObserver.onWakeLockAcquired(
+                PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK);
+
+        int userActivity = PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY;
+        long userActivityTime = mTestClock.now();
+        mWakefulnessSessionObserver.notifyUserActivity(
+                userActivityTime, powerGroupId, userActivity);
+        long advancedTime = 10L;
+        advanceTime(advancedTime);
+        mWakefulnessSessionObserver.notifyUserActivity(
+                userActivityTime, powerGroupId, PowerManager.USER_ACTIVITY_EVENT_BUTTON);
+        mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+                powerGroupId,
+                PowerManagerInternal.WAKEFULNESS_DOZING,
+                GO_TO_SLEEP_REASON_POWER_BUTTON,
+                mTestClock.now());
+
+        verify(mWakefulnessSessionFrameworkStatsLogger)
+                .logTimeoutOverrideEvent(
+                        powerGroupId, // powerGroupId
+                        OVERRIDE_OUTCOME_CANCEL_POWER_BUTTON, // overrideOutcome
+                        OVERRIDE_SCREEN_OFF_TIMEOUT_MS, // override timeout ms
+                        DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default timeout ms
+
+        verify(mWakefulnessSessionFrameworkStatsLogger)
+                .logSessionEvent(
+                        powerGroupId, // powerGroupId
+                        OFF_REASON_POWER_BUTTON, // interactiveStateOffReason
+                        advancedTime, // interactiveStateOnDurationMs
+                        userActivity, // userActivity
+                        advancedTime,  // lastUserActivityEventDurationMs
+                        0); // reducedInteractiveStateOnDurationMs;
+    }
+
+    @Test
+    public void testOnWakefulnessChangeStarted_inTimeoutOverride_onAwake_After_onDozing() {
+        int powerGroupId = 1;
+        mWakefulnessSessionObserver.onWakeLockAcquired(
+                PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK);
+
+        mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+                powerGroupId, PowerManagerInternal.WAKEFULNESS_DOZING,
+                GO_TO_SLEEP_REASON_TIMEOUT, mTestClock.now());
+        // awake after dozing
+        advanceTime(10L);
+        mWakefulnessSessionObserver.onWakefulnessChangeStarted(
+                powerGroupId, PowerManagerInternal.WAKEFULNESS_AWAKE,
+                WAKE_REASON_POWER_BUTTON, mTestClock.now());
+
+        verify(mWakefulnessSessionFrameworkStatsLogger)
+                .logTimeoutOverrideEvent(
+                        powerGroupId,  // powerGroupId
+                        OVERRIDE_OUTCOME_TIMEOUT_USER_INITIATED_REVERT, // overrideOutcome
+                        OVERRIDE_SCREEN_OFF_TIMEOUT_MS, // override timeout ms
+                        DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default timeout ms
+    }
+
+    @Test
+    public void testOnWakeLockReleased_UserActivityTouch() {
+        int powerGroupId = 0;
+        mWakefulnessSessionObserver.onWakeLockAcquired(
+                PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK);
+        advanceTime(5000L);
+        mWakefulnessSessionObserver.onWakeLockReleased(
+                PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK,
+                RELEASE_REASON_USER_ACTIVITY_TOUCH);
+
+        verify(mWakefulnessSessionFrameworkStatsLogger)
+                .logTimeoutOverrideEvent(
+                        powerGroupId, // powerGroupId
+                        OVERRIDE_OUTCOME_CANCEL_USER_INTERACTION, // overrideOutcome
+                        OVERRIDE_SCREEN_OFF_TIMEOUT_MS, // override timeout ms
+                        DEFAULT_SCREEN_OFF_TIMEOUT_MS); // default timeout ms
+    }
+
+    private void advanceTime(long timeMs) {
+        mTestClock.fastForward(timeMs);
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentDeferredUpdateTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentDeferredUpdateTests.java
index 073b551..57118f2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentDeferredUpdateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentDeferredUpdateTests.java
@@ -65,9 +65,6 @@
 
     @Override
     protected void onBeforeSystemServicesCreated() {
-        // Set other flags to their default values
-        mSetFlagsRule.initAllFlagsToReleaseConfigDefault();
-
         mSetFlagsRule.enableFlags(Flags.FLAG_DEFER_DISPLAY_UPDATES);
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index dcf3dad..7756edd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -832,7 +832,8 @@
 
         // Assume the task is at the topmost position
         assertFalse(rootTask.isTopRootTaskInDisplayArea());
-        doReturn(taskDisplayArea.getHomeActivity()).when(taskDisplayArea).topRunningActivity();
+        doReturn(taskDisplayArea.getHomeActivity()).when(taskDisplayArea).topRunningActivity(
+                anyBoolean());
 
         // Use the task as target to resume.
         mRootWindowContainer.resumeFocusedTasksTopActivities();
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 43b424f..fb854c5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -1235,6 +1235,12 @@
         assertNotNull(o.mInfo);
         assertNotNull(o.mInfo.pictureInPictureParams);
 
+        // Bypass the quota check, which causes NPE in current test setup.
+        if (mWm.mAtmService.mActivityClientController.mSetPipAspectRatioQuotaTracker != null) {
+            mWm.mAtmService.mActivityClientController.mSetPipAspectRatioQuotaTracker
+                    .setEnabled(false);
+        }
+
         final PictureInPictureParams p2 = new PictureInPictureParams.Builder()
                 .setAspectRatio(new Rational(3, 4)).build();
         mWm.mAtmService.mActivityClientController.setPictureInPictureParams(record.token, p2);
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index b4e2758..4c81939 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -227,56 +227,3 @@
         ],
     },
 }
-
-cc_genrule {
-    name: "aapt2_results",
-    srcs: [
-        ":aapt2_tests",
-        "integration-tests/CompileTest/**/*",
-        "integration-tests/CommandTests/**/*",
-        "integration-tests/ConvertTest/**/*",
-        "integration-tests/DumpTest/**/*",
-    ],
-    host_supported: true,
-    device_supported: false,
-    target: {
-        windows: {
-            compile_multilib: "64",
-        },
-    },
-    out: ["result.xml"],
-    cmd: "mkdir -p $(genDir)/integration-tests/CompileTest/ && " +
-        "cp $(locations integration-tests/CompileTest/**/*) $(genDir)/integration-tests/CompileTest/ && " +
-        "mkdir -p $(genDir)/integration-tests/CommandTests/ && " +
-        "cp $(locations integration-tests/CommandTests/**/*) $(genDir)/integration-tests/CompileTest/ && " +
-        "mkdir -p $(genDir)/integration-tests/ConvertTest/ && " +
-        "cp $(locations integration-tests/ConvertTest/**/*) $(genDir)/integration-tests/ConvertTest/ && " +
-        "mkdir -p $(genDir)/integration-tests/DumpTest/ && " +
-        "cp $(locations integration-tests/DumpTest/**/*) $(genDir)/integration-tests/DumpTest/ && " +
-        "cp $(locations :aapt2_tests) $(genDir)/ && " +
-        "$(genDir)/aapt2_tests " +
-        "--gtest_output=xml:$(out) " +
-        ">/dev/null 2>&1 ; true",
-    dist: {
-        targets: ["aapt2_run_host_unit_tests"],
-        dir: "gtest",
-        dest: "aapt2_host_unit_tests_result.xml",
-    },
-    arch: {
-        x86: {
-            dist: {
-                suffix: "_x86",
-            },
-        },
-        x86_64: {
-            dist: {
-                suffix: "_x86_64",
-            },
-        },
-    },
-}
-
-phony_rule {
-    name: "aapt2_run_host_unit_tests",
-    phony_deps: ["aapt2_results"],
-}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
index 76bac92..16785d1 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AndroidHeuristicsFilter.kt
@@ -51,6 +51,8 @@
 }
 
 /**
+ * Effectively apply @RavenwoodKeepWholeClass to all classes with these names
+ *
  * @return if a given class "seems like" an feature flags class.
  */
 private fun ClassNodes.isFeatureFlagsClass(className: String): Boolean {
@@ -59,6 +61,7 @@
     return className.endsWith("/Flags")
             || className.endsWith("/FeatureFlags")
             || className.endsWith("/FeatureFlagsImpl")
+            || className.endsWith("/CustomFeatureFlags")
             || className.endsWith("/FakeFeatureFlagsImpl");
 }