Merge "Camera: Address an issue that the invalid memory is accessed" into udc-dev
diff --git a/ProtoLibraries.bp b/ProtoLibraries.bp
index d8f693c..fcff581 100644
--- a/ProtoLibraries.bp
+++ b/ProtoLibraries.bp
@@ -81,8 +81,6 @@
     name: "platformprotos",
     srcs: [
         ":ipconnectivity-proto-src",
-        ":libstats_atom_enum_protos",
-        ":libstats_atom_message_protos",
         ":libstats_internal_protos",
         ":statsd_internal_protos",
         "cmds/am/proto/instrumentation_data.proto",
diff --git a/TestProtoLibraries.bp b/TestProtoLibraries.bp
index 9e2a64c..2d87841 100644
--- a/TestProtoLibraries.bp
+++ b/TestProtoLibraries.bp
@@ -15,8 +15,6 @@
 java_library_host {
     name: "platformtestprotos",
     srcs: [
-        ":libstats_atom_enum_protos",
-        ":libstats_atom_message_protos",
         ":libstats_internal_protos",
         ":statsd_internal_protos",
     ],
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java b/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java
index a9f720a..515ddc8 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java
@@ -80,7 +80,7 @@
 
     private void prepareForNextRun() {
         SystemClock.sleep(COOL_OFF_PERIOD_MS);
-        ShellHelper.runShellCommand("am wait-for-broadcast-idle");
+        ShellHelper.runShellCommand("am wait-for-broadcast-idle --flush-broadcast-loopers");
         mStartTimeNs = System.nanoTime();
         mPausedDurationNs = 0;
     }
@@ -102,7 +102,7 @@
      * to avoid unnecessary waiting.
      */
     public void resumeTiming() {
-        ShellHelper.runShellCommand("am wait-for-broadcast-idle");
+        ShellHelper.runShellCommand("am wait-for-broadcast-idle --flush-broadcast-loopers");
         resumeTimer();
     }
 
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index 19a4766..6dba5b3 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -1541,7 +1541,8 @@
 
     private void waitForBroadcastIdle() {
         try {
-            ShellHelper.runShellCommandWithTimeout("am wait-for-broadcast-idle", TIMEOUT_IN_SECOND);
+            ShellHelper.runShellCommandWithTimeout(
+                    "am wait-for-broadcast-idle --flush-broadcast-loopers", TIMEOUT_IN_SECOND);
         } catch (TimeoutException e) {
             Log.e(TAG, "Ending waitForBroadcastIdle because it is taking too long", e);
         }
diff --git a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
index 8e9f474..17076bc 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java
@@ -98,6 +98,15 @@
     public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED = 1;
 
     /**
+     * Delay freezing the app when the broadcast is delivered. This flag is not required if
+     * TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED or
+     * TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED are specified, as those will
+     * already defer freezing during the allowlist duration.
+     * @hide temporarily until the next release
+     */
+    public static final int TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED = 1 << 2;
+
+    /**
      * The list of temp allow list types.
      * @hide
      */
@@ -105,6 +114,7 @@
             TEMPORARY_ALLOW_LIST_TYPE_NONE,
             TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
             TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED,
+            TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface TempAllowListType {}
@@ -216,6 +226,11 @@
      * Set temp-allow-list for transferring accounts between users.
      */
     public static final int REASON_ACCOUNT_TRANSFER = 104;
+    /**
+     * Set temp-allow-list for server push messaging that can be deferred.
+     * @hide temporarily until the next release
+     */
+    public static final int REASON_PUSH_MESSAGING_DEFERRABLE = 105;
 
     /* Reason code range 200-299 are reserved for broadcast actions */
     /**
@@ -449,6 +464,7 @@
             REASON_PUSH_MESSAGING_OVER_QUOTA,
             REASON_ACTIVITY_RECOGNITION,
             REASON_ACCOUNT_TRANSFER,
+            REASON_PUSH_MESSAGING_DEFERRABLE,
             REASON_BOOT_COMPLETED,
             REASON_PRE_BOOT_COMPLETED,
             REASON_LOCKED_BOOT_COMPLETED,
@@ -781,6 +797,8 @@
                 return "ACTIVITY_RECOGNITION";
             case REASON_ACCOUNT_TRANSFER:
                 return "REASON_ACCOUNT_TRANSFER";
+            case REASON_PUSH_MESSAGING_DEFERRABLE:
+                return "PUSH_MESSAGING_DEFERRABLE";
             case REASON_BOOT_COMPLETED:
                 return "BOOT_COMPLETED";
             case REASON_PRE_BOOT_COMPLETED:
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 3f552b6..92fc78e 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -2595,39 +2595,49 @@
         // or the user stopped the job somehow.
         if (internalStopReason == JobParameters.INTERNAL_STOP_REASON_SUCCESSFUL_FINISH
                 || internalStopReason == JobParameters.INTERNAL_STOP_REASON_TIMEOUT
+                || internalStopReason == JobParameters.INTERNAL_STOP_REASON_ANR
                 || stopReason == JobParameters.STOP_REASON_USER) {
             numFailures++;
         } else {
             numSystemStops++;
         }
-        final int backoffAttempts = Math.max(1,
-                numFailures + numSystemStops / mConstants.SYSTEM_STOP_TO_FAILURE_RATIO);
-        long delayMillis;
+        final int backoffAttempts =
+                numFailures + numSystemStops / mConstants.SYSTEM_STOP_TO_FAILURE_RATIO;
+        final long earliestRuntimeMs;
 
-        switch (job.getBackoffPolicy()) {
-            case JobInfo.BACKOFF_POLICY_LINEAR: {
-                long backoff = initialBackoffMillis;
-                if (backoff < mConstants.MIN_LINEAR_BACKOFF_TIME_MS) {
-                    backoff = mConstants.MIN_LINEAR_BACKOFF_TIME_MS;
+        if (backoffAttempts == 0) {
+            earliestRuntimeMs = JobStatus.NO_EARLIEST_RUNTIME;
+        } else {
+            long delayMillis;
+            switch (job.getBackoffPolicy()) {
+                case JobInfo.BACKOFF_POLICY_LINEAR: {
+                    long backoff = initialBackoffMillis;
+                    if (backoff < mConstants.MIN_LINEAR_BACKOFF_TIME_MS) {
+                        backoff = mConstants.MIN_LINEAR_BACKOFF_TIME_MS;
+                    }
+                    delayMillis = backoff * backoffAttempts;
                 }
-                delayMillis = backoff * backoffAttempts;
-            } break;
-            default:
-                if (DEBUG) {
-                    Slog.v(TAG, "Unrecognised back-off policy, defaulting to exponential.");
+                break;
+                default:
+                    if (DEBUG) {
+                        Slog.v(TAG, "Unrecognised back-off policy, defaulting to exponential.");
+                    }
+                    // Intentional fallthrough.
+                case JobInfo.BACKOFF_POLICY_EXPONENTIAL: {
+                    long backoff = initialBackoffMillis;
+                    if (backoff < mConstants.MIN_EXP_BACKOFF_TIME_MS) {
+                        backoff = mConstants.MIN_EXP_BACKOFF_TIME_MS;
+                    }
+                    delayMillis = (long) Math.scalb(backoff, backoffAttempts - 1);
                 }
-            case JobInfo.BACKOFF_POLICY_EXPONENTIAL: {
-                long backoff = initialBackoffMillis;
-                if (backoff < mConstants.MIN_EXP_BACKOFF_TIME_MS) {
-                    backoff = mConstants.MIN_EXP_BACKOFF_TIME_MS;
-                }
-                delayMillis = (long) Math.scalb(backoff, backoffAttempts - 1);
-            } break;
+                break;
+            }
+            delayMillis =
+                    Math.min(delayMillis, JobInfo.MAX_BACKOFF_DELAY_MILLIS);
+            earliestRuntimeMs = elapsedNowMillis + delayMillis;
         }
-        delayMillis =
-                Math.min(delayMillis, JobInfo.MAX_BACKOFF_DELAY_MILLIS);
         JobStatus newJob = new JobStatus(failureToReschedule,
-                elapsedNowMillis + delayMillis,
+                earliestRuntimeMs,
                 JobStatus.NO_LATEST_RUNTIME, numFailures, numSystemStops,
                 failureToReschedule.getLastSuccessfulRunTime(), sSystemClock.millis(),
                 failureToReschedule.getCumulativeExecutionTimeMs());
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index e42e526..9eb9d66 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -4156,6 +4156,7 @@
   public static class WindowInfosListenerForTest.WindowInfo {
     field @NonNull public final android.graphics.Rect bounds;
     field public final boolean isTrustedOverlay;
+    field public final boolean isVisible;
     field @NonNull public final String name;
     field @NonNull public final android.os.IBinder windowToken;
   }
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index ba5a9f7..ccd83f7 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -65,11 +65,9 @@
 import android.provider.DeviceConfig;
 import android.util.ArrayMap;
 import android.util.ArraySet;
-import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.LongSparseLongArray;
 import android.util.Pools;
-import android.util.Slog;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
@@ -182,8 +180,6 @@
  */
 @SystemService(Context.APP_OPS_SERVICE)
 public class AppOpsManager {
-    private static final String LOG_TAG = "AppOpsManager";
-
     /**
      * This is a subtle behavior change to {@link #startWatchingMode}.
      *
@@ -7542,7 +7538,6 @@
      */
     @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
     public void setUidMode(int code, int uid, @Mode int mode) {
-        logAnySeriousModeChanges(code, uid, null, mode);
         try {
             mService.setUidMode(code, uid, mode);
         } catch (RemoteException e) {
@@ -7563,7 +7558,6 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
     public void setUidMode(@NonNull String appOp, int uid, @Mode int mode) {
-        logAnySeriousModeChanges(strOpToOp(appOp), uid, null, mode);
         try {
             mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
         } catch (RemoteException e) {
@@ -7599,32 +7593,11 @@
         }
     }
 
-    private void logAnySeriousModeChanges(int code, int uid, String packageName, @Mode int mode) {
-        // TODO (b/280869337): Remove this once we have the required data.
-        if (code != OP_RUN_ANY_IN_BACKGROUND || mode == MODE_ALLOWED) {
-            return;
-        }
-        final StringBuilder log = new StringBuilder("Attempt to change RUN_ANY_IN_BACKGROUND to ")
-                .append(modeToName(mode))
-                .append(" for uid: ")
-                .append(UserHandle.formatUid(uid))
-                .append(" package: ")
-                .append(packageName)
-                .append(" by: ")
-                .append(mContext.getOpPackageName());
-        if (Process.myUid() == Process.SYSTEM_UID) {
-            Slog.wtfStack(LOG_TAG, log.toString());
-        } else {
-            Log.w(LOG_TAG, log.toString());
-        }
-    }
-
     /** @hide */
     @UnsupportedAppUsage
     @TestApi
     @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
     public void setMode(int code, int uid, String packageName, @Mode int mode) {
-        logAnySeriousModeChanges(code, uid, packageName, mode);
         try {
             mService.setMode(code, uid, packageName, mode);
         } catch (RemoteException e) {
@@ -7647,7 +7620,6 @@
     @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
     public void setMode(@NonNull String op, int uid, @Nullable String packageName,
             @Mode int mode) {
-        logAnySeriousModeChanges(strOpToOp(op), uid, packageName, mode);
         try {
             mService.setMode(strOpToOp(op), uid, packageName, mode);
         } catch (RemoteException e) {
diff --git a/core/java/android/app/ForegroundServiceTypePolicy.java b/core/java/android/app/ForegroundServiceTypePolicy.java
index c0c59a2..ac9c497 100644
--- a/core/java/android/app/ForegroundServiceTypePolicy.java
+++ b/core/java/android/app/ForegroundServiceTypePolicy.java
@@ -17,7 +17,9 @@
 package android.app;
 
 import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_DEFAULT;
 import static android.app.AppOpsManager.MODE_FOREGROUND;
+import static android.app.AppOpsManager.MODE_IGNORED;
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
@@ -36,6 +38,8 @@
 import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
 import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE;
 import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED;
+import static android.permission.PermissionCheckerManager.PERMISSION_HARD_DENIED;
+import static android.permission.PermissionCheckerManager.PERMISSION_SOFT_DENIED;
 
 import android.Manifest;
 import android.annotation.IntDef;
@@ -43,6 +47,7 @@
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.app.compat.CompatChanges;
+import android.app.role.RoleManager;
 import android.compat.Compatibility;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.Disabled;
@@ -58,6 +63,7 @@
 import android.hardware.usb.UsbManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.permission.PermissionCheckerManager;
 import android.provider.DeviceConfig;
 import android.text.TextUtils;
@@ -74,6 +80,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Optional;
 
 /**
@@ -264,7 +271,8 @@
             null /* allOfPermissions */,
             null /* anyOfPermissions */,
             null /* permissionEnforcementFlag */,
-            false /* permissionEnforcementFlagDefaultValue */
+            false /* permissionEnforcementFlagDefaultValue */,
+            false /* foregroundOnlyPermission */
     );
 
     /**
@@ -280,7 +288,8 @@
             null /* allOfPermissions */,
             null /* anyOfPermissions */,
             null /* permissionEnforcementFlag */,
-            false /* permissionEnforcementFlagDefaultValue */
+            false /* permissionEnforcementFlagDefaultValue */,
+            false /* foregroundOnlyPermission */
     );
 
     /**
@@ -298,7 +307,8 @@
             }, true),
             null /* anyOfPermissions */,
             FGS_TYPE_PERM_ENFORCEMENT_FLAG_DATA_SYNC /* permissionEnforcementFlag */,
-            true /* permissionEnforcementFlagDefaultValue */
+            true /* permissionEnforcementFlagDefaultValue */,
+            false /* foregroundOnlyPermission */
     );
 
     /**
@@ -316,7 +326,8 @@
             }, true),
             null /* anyOfPermissions */,
             FGS_TYPE_PERM_ENFORCEMENT_FLAG_MEDIA_PLAYBACK /* permissionEnforcementFlag */,
-            true /* permissionEnforcementFlagDefaultValue */
+            true /* permissionEnforcementFlagDefaultValue */,
+            false /* foregroundOnlyPermission */
     );
 
     /**
@@ -333,10 +344,12 @@
                 new RegularPermission(Manifest.permission.FOREGROUND_SERVICE_PHONE_CALL)
             }, true),
             new ForegroundServiceTypePermissions(new ForegroundServiceTypePermission[] {
-                new RegularPermission(Manifest.permission.MANAGE_OWN_CALLS)
+                new RegularPermission(Manifest.permission.MANAGE_OWN_CALLS),
+                new RolePermission(RoleManager.ROLE_DIALER)
             }, false),
             FGS_TYPE_PERM_ENFORCEMENT_FLAG_PHONE_CALL /* permissionEnforcementFlag */,
-            true /* permissionEnforcementFlagDefaultValue */
+            true /* permissionEnforcementFlagDefaultValue */,
+            false /* foregroundOnlyPermission */
     );
 
     /**
@@ -357,7 +370,8 @@
                 new RegularPermission(Manifest.permission.ACCESS_FINE_LOCATION),
             }, false),
             FGS_TYPE_PERM_ENFORCEMENT_FLAG_LOCATION /* permissionEnforcementFlag */,
-            true /* permissionEnforcementFlagDefaultValue */
+            true /* permissionEnforcementFlagDefaultValue */,
+            true /* foregroundOnlyPermission */
     );
 
     /**
@@ -387,7 +401,8 @@
                 new UsbAccessoryPermission(),
             }, false),
             FGS_TYPE_PERM_ENFORCEMENT_FLAG_CONNECTED_DEVICE /* permissionEnforcementFlag */,
-            true /* permissionEnforcementFlagDefaultValue */
+            true /* permissionEnforcementFlagDefaultValue */,
+            false /* foregroundOnlyPermission */
     );
 
     /**
@@ -408,7 +423,8 @@
                 new AppOpPermission(AppOpsManager.OP_PROJECT_MEDIA)
             }, false),
             FGS_TYPE_PERM_ENFORCEMENT_FLAG_MEDIA_PROJECTION /* permissionEnforcementFlag */,
-            true /* permissionEnforcementFlagDefaultValue */
+            true /* permissionEnforcementFlagDefaultValue */,
+            false /* foregroundOnlyPermission */
     );
 
     /**
@@ -429,7 +445,8 @@
                 new RegularPermission(Manifest.permission.SYSTEM_CAMERA),
             }, false),
             FGS_TYPE_PERM_ENFORCEMENT_FLAG_CAMERA /* permissionEnforcementFlag */,
-            true /* permissionEnforcementFlagDefaultValue */
+            true /* permissionEnforcementFlagDefaultValue */,
+            true /* foregroundOnlyPermission */
     );
 
     /**
@@ -454,7 +471,8 @@
                 new RegularPermission(Manifest.permission.RECORD_AUDIO),
             }, false),
             FGS_TYPE_PERM_ENFORCEMENT_FLAG_MICROPHONE /* permissionEnforcementFlag */,
-            true /* permissionEnforcementFlagDefaultValue */
+            true /* permissionEnforcementFlagDefaultValue */,
+            true /* foregroundOnlyPermission */
     );
 
     /**
@@ -476,7 +494,8 @@
                 new RegularPermission(Manifest.permission.HIGH_SAMPLING_RATE_SENSORS),
             }, false),
             FGS_TYPE_PERM_ENFORCEMENT_FLAG_HEALTH /* permissionEnforcementFlag */,
-            true /* permissionEnforcementFlagDefaultValue */
+            true /* permissionEnforcementFlagDefaultValue */,
+            false /* foregroundOnlyPermission */
     );
 
     /**
@@ -494,7 +513,8 @@
             }, true),
             null /* anyOfPermissions */,
             FGS_TYPE_PERM_ENFORCEMENT_FLAG_REMOTE_MESSAGING /* permissionEnforcementFlag */,
-            true /* permissionEnforcementFlagDefaultValue */
+            true /* permissionEnforcementFlagDefaultValue */,
+            false /* foregroundOnlyPermission */
     );
 
     /**
@@ -516,7 +536,8 @@
                 new AppOpPermission(AppOpsManager.OP_ACTIVATE_VPN),
             }, false),
             FGS_TYPE_PERM_ENFORCEMENT_FLAG_SYSTEM_EXEMPTED /* permissionEnforcementFlag */,
-            true /* permissionEnforcementFlagDefaultValue */
+            true /* permissionEnforcementFlagDefaultValue */,
+            false /* foregroundOnlyPermission */
     );
 
     /**
@@ -532,7 +553,8 @@
             null /* allOfPermissions */,
             null /* anyOfPermissions */,
             null /* permissionEnforcementFlag */,
-            false /* permissionEnforcementFlagDefaultValue */
+            false /* permissionEnforcementFlagDefaultValue */,
+            false /* foregroundOnlyPermission */
     );
 
     /**
@@ -550,7 +572,8 @@
             }, true),
             null /* anyOfPermissions */,
             null /* permissionEnforcementFlag */,
-            false /* permissionEnforcementFlagDefaultValue */
+            false /* permissionEnforcementFlagDefaultValue */,
+            false /* foregroundOnlyPermission */
     );
 
     /**
@@ -568,7 +591,8 @@
             }, true),
             null /* anyOfPermissions */,
             FGS_TYPE_PERM_ENFORCEMENT_FLAG_SPECIAL_USE /* permissionEnforcementFlag */,
-            true /* permissionEnforcementFlagDefaultValue */
+            true /* permissionEnforcementFlagDefaultValue */,
+            false /* foregroundOnlyPermission */
     );
 
     /**
@@ -636,6 +660,29 @@
     public @interface ForegroundServicePolicyCheckCode{}
 
     /**
+     * Whether or not to require that app to have actual access to certain foreground only
+     * permissions before starting the foreground service.
+     *
+     * <p>
+     * Examples here are microphone, camera and fg location related permissions.
+     * When the user grants the permission, its permission state is set to "granted",
+     * but the actual capability to access these sensors, is to be evaluated according to
+     * its process state. The Android {@link android.os.Build.VERSION_CODES#R} introduced
+     * the while-in-use permission, basically the background-started FGS will not have access
+     * to these sensors. In this context, there is no legitimate reasons to start a FGS from
+     * the background with these types. This flag controls the behavior of the enforcement,
+     * when it's enabled, in the aforementioned case, the FGS start will result in
+     * a SecurityException. </p>
+     */
+    private static final String FGS_TYPE_FG_PERM_ENFORCEMENT_FLAG =
+            "fgs_type_fg_perm_enforcement_flag";
+
+    /**
+     * The default value to the {@link #FGS_TYPE_FG_PERM_ENFORCEMENT_FLAG}.
+     */
+    private static final boolean DEFAULT_FGS_TYPE_FG_PERM_ENFORCEMENT_FLAG_VALUE = true;
+
+    /**
      * @return The policy info for the given type.
      */
     @NonNull
@@ -677,6 +724,11 @@
         }
     }
 
+    private static boolean isFgsTypeFgPermissionEnforcementEnabled() {
+        return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                FGS_TYPE_FG_PERM_ENFORCEMENT_FLAG, DEFAULT_FGS_TYPE_FG_PERM_ENFORCEMENT_FLAG_VALUE);
+    }
+
     /**
      * Constructor.
      *
@@ -734,6 +786,12 @@
         final boolean mPermissionEnforcementFlagDefaultValue;
 
         /**
+         * Whether or not the permissions here are limited to foreground only.
+         * Typical examples are microphone/camera/location.
+         */
+        final boolean mForegroundOnlyPermission;
+
+        /**
          * A customized check for the permissions.
          */
         @Nullable ForegroundServiceTypePermission mCustomPermission;
@@ -769,7 +827,8 @@
                 @Nullable ForegroundServiceTypePermissions allOfPermissions,
                 @Nullable ForegroundServiceTypePermissions anyOfPermissions,
                 @Nullable String permissionEnforcementFlag,
-                boolean permissionEnforcementFlagDefaultValue) {
+                boolean permissionEnforcementFlagDefaultValue,
+                boolean foregroundOnlyPermission) {
             mType = type;
             mDeprecationChangeId = deprecationChangeId;
             mDisabledChangeId = disabledChangeId;
@@ -778,6 +837,7 @@
             mPermissionEnforcementFlag = permissionEnforcementFlag;
             mPermissionEnforcementFlagDefaultValue = permissionEnforcementFlagDefaultValue;
             mPermissionEnforcementFlagValue = permissionEnforcementFlagDefaultValue;
+            mForegroundOnlyPermission = foregroundOnlyPermission;
         }
 
         /**
@@ -880,6 +940,14 @@
         }
 
         /**
+         * Whether or not the permissions here are limited to foreground only.
+         * Typical examples are microphone/camera/location.
+         */
+        public boolean hasForegroundOnlyPermission() {
+            return mForegroundOnlyPermission;
+        }
+
+        /**
          * Override the type disabling change Id.
          *
          * For test only.
@@ -1077,26 +1145,45 @@
         @PackageManager.PermissionResult
         int checkPermission(@NonNull Context context, @NonNull String name, int callerUid,
                 int callerPid, String packageName, boolean allowWhileInUse) {
-            // Simple case, check if it's already granted.
-            @PackageManager.PermissionResult int result;
-            if ((result = PermissionChecker.checkPermissionForPreflight(context, name,
-                    callerPid, callerUid, packageName)) == PERMISSION_GRANTED) {
-                return PERMISSION_GRANTED;
+            @PermissionCheckerManager.PermissionResult final int result =
+                    PermissionChecker.checkPermissionForPreflight(context, name,
+                            callerPid, callerUid, packageName);
+            if (result == PERMISSION_HARD_DENIED) {
+                // If the user didn't grant this permission at all.
+                return PERMISSION_DENIED;
             }
-            if (allowWhileInUse && result == PermissionCheckerManager.PERMISSION_SOFT_DENIED) {
-                // Check its appops
-                final int opCode = AppOpsManager.permissionToOpCode(name);
-                final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
-                if (opCode != AppOpsManager.OP_NONE) {
-                    final int currentMode = appOpsManager.unsafeCheckOpRawNoThrow(opCode, callerUid,
-                            packageName);
-                    if (currentMode == MODE_FOREGROUND) {
-                        // It's in foreground only mode and we're allowing while-in-use.
-                        return PERMISSION_GRANTED;
-                    }
-                }
+            final int opCode = AppOpsManager.permissionToOpCode(name);
+            if (opCode == AppOpsManager.OP_NONE) {
+                // Simple case, check if it's already granted.
+                return result == PermissionCheckerManager.PERMISSION_GRANTED
+                        ? PERMISSION_GRANTED : PERMISSION_DENIED;
             }
-            return PERMISSION_DENIED;
+            final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
+            final int mode = appOpsManager.unsafeCheckOpRawNoThrow(opCode, callerUid, packageName);
+            switch (mode) {
+                case MODE_ALLOWED:
+                    // The appop is just allowed, plain and simple.
+                    return PERMISSION_GRANTED;
+                case MODE_DEFAULT:
+                    // Follow the permission check result.
+                    return result == PermissionCheckerManager.PERMISSION_GRANTED
+                            ? PERMISSION_GRANTED : PERMISSION_DENIED;
+                case MODE_FOREGROUND:
+                    // If the enforcement flag is OFF, we silently allow it. Or, if it's in
+                    // the foreground only mode and we're allowing while-in-use, allow it.
+                    return !isFgsTypeFgPermissionEnforcementEnabled() || allowWhileInUse
+                            ? PERMISSION_GRANTED : PERMISSION_DENIED;
+                case MODE_IGNORED:
+                    // If it's soft denied with the mode "ignore", semantically it's a silent
+                    // failure and no exception should be thrown, we might not want to allow
+                    // the FGS. However, since the user has agreed with this permission
+                    // (otherwise it's going to be a hard denial), and we're allowing
+                    // while-in-use here, it's safe to allow the FGS run here.
+                    return allowWhileInUse && result == PERMISSION_SOFT_DENIED
+                            ? PERMISSION_GRANTED : PERMISSION_DENIED;
+                default:
+                    return PERMISSION_DENIED;
+            }
         }
     }
 
@@ -1123,6 +1210,29 @@
     }
 
     /**
+     * This represents a particular role an app needs to hold for a specific service type.
+     */
+    static class RolePermission extends ForegroundServiceTypePermission {
+        final String mRole;
+
+        RolePermission(@NonNull String role) {
+            super(role);
+            mRole = role;
+        }
+
+        @Override
+        @PackageManager.PermissionResult
+        public int checkPermission(@NonNull Context context, int callerUid, int callerPid,
+                String packageName, boolean allowWhileInUse) {
+            final RoleManager rm = context.getSystemService(RoleManager.class);
+            final List<String> holders = rm.getRoleHoldersAsUser(mRole,
+                    UserHandle.getUserHandleForUid(callerUid));
+            return holders != null && holders.contains(packageName)
+                    ? PERMISSION_GRANTED : PERMISSION_DENIED;
+        }
+    }
+
+    /**
      * This represents a special Android permission to be required for accessing usb devices.
      */
     static class UsbDevicePermission extends ForegroundServiceTypePermission {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index e15e08f..0ec3847 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -147,13 +147,13 @@
     int checkPermission(in String permission, int pid, int uid);
 
     /** Logs start of an API call to associate with an FGS, used for FGS Type Metrics */
-    void logFgsApiBegin(int apiType, int appUid, int appPid);
+    oneway void logFgsApiBegin(int apiType, int appUid, int appPid);
 
     /** Logs stop of an API call to associate with an FGS, used for FGS Type Metrics */
-    void logFgsApiEnd(int apiType, int appUid, int appPid);
+    oneway void logFgsApiEnd(int apiType, int appUid, int appPid);
 
     /** Logs API state change to associate with an FGS, used for FGS Type Metrics */
-    void logFgsApiStateChanged(int apiType, int state, int appUid, int appPid);
+    oneway void logFgsApiStateChanged(int apiType, int state, int appUid, int appPid);
     // =============== End of transactions used on native side as well ============================
 
     // Special low-level communication with activity manager.
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 3249b41..4e2b6fa 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -261,6 +261,9 @@
     void cancelTaskWindowTransition(int taskId);
 
     /**
+     * Fetches the snapshot for the task with the given id, taking a new snapshot if it is not in
+     * the task snapshot cache and it is requested.
+     *
      * @param taskId the id of the task to retrieve the sAutoapshots for
      * @param isLowResolution if set, if the snapshot needs to be loaded from disk, this will load
      *                          a reduced resolution of it, which is much faster
@@ -272,10 +275,14 @@
             int taskId, boolean isLowResolution, boolean takeSnapshotIfNeeded);
 
     /**
+     * Requests for a new snapshot to be taken for the task with the given id, storing it in the
+     * task snapshot cache only if requested.
+     *
      * @param taskId the id of the task to take a snapshot of
+     * @param updateCache whether to store the new snapshot in the system's task snapshot cache
      * @return a graphic buffer representing a screenshot of a task
      */
-    android.window.TaskSnapshot takeTaskSnapshot(int taskId);
+    android.window.TaskSnapshot takeTaskSnapshot(int taskId, boolean updateCache);
 
     /**
      * Return the user id of last resumed activity.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index df9257c..2eb6ca7 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2840,6 +2840,10 @@
      * @hide
      */
     public void visitUris(@NonNull Consumer<Uri> visitor) {
+        if (publicVersion != null) {
+            publicVersion.visitUris(visitor);
+        }
+
         visitor.accept(sound);
 
         if (tickerView != null) tickerView.visitUris(visitor);
@@ -5006,12 +5010,6 @@
             return mUserExtras;
         }
 
-        private Bundle getAllExtras() {
-            final Bundle saveExtras = (Bundle) mUserExtras.clone();
-            saveExtras.putAll(mN.extras);
-            return saveExtras;
-        }
-
         /**
          * Add an action to this notification. Actions are typically displayed by
          * the system as a button adjacent to the notification content.
@@ -6617,9 +6615,16 @@
                                 + " vs bubble: " + mN.mBubbleMetadata.getShortcutId());
             }
 
-            // first, add any extras from the calling code
+            // Adds any new extras provided by the user.
             if (mUserExtras != null) {
-                mN.extras = getAllExtras();
+                final Bundle saveExtras = (Bundle) mUserExtras.clone();
+                if (SystemProperties.getBoolean(
+                        "persist.sysui.notification.builder_extras_override", false)) {
+                    mN.extras.putAll(saveExtras);
+                } else {
+                    saveExtras.putAll(mN.extras);
+                    mN.extras = saveExtras;
+                }
             }
 
             mN.creationTime = System.currentTimeMillis();
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index a6313db..385fd50 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -24,9 +24,11 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.annotation.UserIdInt;
 import android.app.compat.CompatChanges;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.EnabledSince;
+import android.compat.annotation.LoggingOnly;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
@@ -49,6 +51,7 @@
 import android.view.KeyEvent;
 import android.view.View;
 
+import com.android.internal.compat.IPlatformCompat;
 import com.android.internal.statusbar.AppClipsServiceConnector;
 import com.android.internal.statusbar.IAddTileResultCallback;
 import com.android.internal.statusbar.IStatusBarService;
@@ -170,6 +173,8 @@
     public @interface Disable2Flags {}
     // LINT.ThenChange(frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/disableflags/DisableFlagsLogger.kt)
 
+    private static final String TAG = "StatusBarManager";
+
     /**
      * Default disable flags for setup
      *
@@ -571,12 +576,24 @@
     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
     private static final long MEDIA_CONTROL_SESSION_ACTIONS = 203800354L;
 
+    /**
+     * Media controls based on {@link android.app.Notification.MediaStyle} notifications should
+     * include a non-empty title, either in the {@link android.media.MediaMetadata} or
+     * notification title.
+     */
+    @ChangeId
+    @LoggingOnly
+    private static final long MEDIA_CONTROL_BLANK_TITLE = 274775190L;
+
     @UnsupportedAppUsage
     private Context mContext;
     private IStatusBarService mService;
     @UnsupportedAppUsage
     private IBinder mToken = new Binder();
 
+    private final IPlatformCompat mPlatformCompat = IPlatformCompat.Stub.asInterface(
+            ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+
     @UnsupportedAppUsage
     StatusBarManager(Context context) {
         mContext = context;
@@ -588,7 +605,7 @@
             mService = IStatusBarService.Stub.asInterface(
                     ServiceManager.getService(Context.STATUS_BAR_SERVICE));
             if (mService == null) {
-                Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
+                Slog.w(TAG, "warning: no STATUS_BAR_SERVICE");
             }
         }
         return mService;
@@ -1217,6 +1234,25 @@
     }
 
     /**
+     * Log that the given package has posted media controls with a blank title
+     *
+     * @param packageName App posting media controls
+     * @param userId Current user ID
+     * @throws RuntimeException if there is an error reporting the change
+     *
+     * @hide
+     */
+    public void logBlankMediaTitle(String packageName, @UserIdInt int userId)
+            throws RuntimeException {
+        try {
+            mPlatformCompat.reportChangeByPackageName(MEDIA_CONTROL_BLANK_TITLE, packageName,
+                        userId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Checks whether the supplied activity can {@link Activity#startActivityForResult(Intent, int)}
      * a system activity that captures content on the screen to take a screenshot.
      *
diff --git a/core/java/android/app/WallpaperColors.java b/core/java/android/app/WallpaperColors.java
index be1d8b8..b710644 100644
--- a/core/java/android/app/WallpaperColors.java
+++ b/core/java/android/app/WallpaperColors.java
@@ -588,7 +588,7 @@
 
         int hints = 0;
         double meanLuminance = totalLuminance / pixels.length;
-        if (meanLuminance > BRIGHT_IMAGE_MEAN_LUMINANCE && darkPixels < maxDarkPixels) {
+        if (meanLuminance > BRIGHT_IMAGE_MEAN_LUMINANCE && darkPixels <= maxDarkPixels) {
             hints |= HINT_SUPPORTS_DARK_TEXT;
         }
         if (meanLuminance < DARK_THEME_MEAN_LUMINANCE) {
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index be06792..57935e3 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -1680,14 +1680,14 @@
      * @hide
      */
     public void addOnColorsChangedListener(@NonNull LocalWallpaperColorConsumer callback,
-            List<RectF> regions) throws IllegalArgumentException {
+            List<RectF> regions, int which) throws IllegalArgumentException {
         for (RectF region : regions) {
             if (!LOCAL_COLOR_BOUNDS.contains(region)) {
                 throw new IllegalArgumentException("Regions must be within bounds "
                         + LOCAL_COLOR_BOUNDS);
             }
         }
-        sGlobals.addOnColorsChangedListener(callback, regions, FLAG_SYSTEM,
+        sGlobals.addOnColorsChangedListener(callback, regions, which,
                                                  mContext.getUserId(), mContext.getDisplayId());
     }
 
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index e9fb811..783e7d3 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -8359,6 +8359,26 @@
      * from Android {@link android.os.Build.VERSION_CODES#R}, requests to disable camera from
      * legacy device admins targeting SDK version {@link android.os.Build.VERSION_CODES#P} or
      * below will be silently ignored.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, after the camera disabled
+     * policy has been set, {@link PolicyUpdateReceiver#onPolicySetResult(Context, String,
+     * Bundle, TargetUser, PolicyUpdateResult)} will notify the admin on whether the policy was
+     * successfully set or not. This callback will contain:
+     * <ul>
+     * <li> The policy identifier returned from
+     * {@link DevicePolicyIdentifiers#getIdentifierForUserRestriction(String)} with user restriction
+     * {@link UserManager#DISALLOW_CAMERA}
+     * <li> The {@link TargetUser} that this policy relates to
+     * <li> The {@link PolicyUpdateResult}, which will be
+     * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully set or the
+     * reason the policy failed to be set
+     * (e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY})
+     * </ul>
+     * If there has been a change to the policy,
+     * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser,
+     * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the
+     * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult}
+     * will contain the reason why the policy changed.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with or null if
                      the caller is not a device admin
@@ -9783,6 +9803,27 @@
      * <p>
      * The calling device admin must be a profile owner or device owner. If it is not, a security
      * exception will be thrown.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, after the persistent preferred
+     * activity policy has been set, {@link PolicyUpdateReceiver#onPolicySetResult(Context, String,
+     * Bundle, TargetUser, PolicyUpdateResult)} will notify the admin on whether the policy was
+     * successfully set or not. This callback will contain:
+     * <ul>
+     * <li> The policy identifier
+     * {@link DevicePolicyIdentifiers#PERSISTENT_PREFERRED_ACTIVITY_POLICY}
+     * <li> The additional policy params bundle, which contains
+     * {@link PolicyUpdateReceiver#EXTRA_INTENT_FILTER} the intent filter the policy applies to
+     * <li> The {@link TargetUser} that this policy relates to
+     * <li> The {@link PolicyUpdateResult}, which will be
+     * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully set or the
+     * reason the policy failed to be set
+     * (e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY})
+     * </ul>
+     * If there has been a change to the policy,
+     * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser,
+     * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the
+     * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult}
+     * will contain the reason why the policy changed.
      *
      * <p>NOTE: Performs disk I/O and shouldn't be called on the main thread.
      *
@@ -9816,6 +9857,27 @@
      * <p>
      * The calling device admin must be a profile owner. If it is not, a security exception will be
      * thrown.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, after the persistent preferred
+     * activity policy has been cleared, {@link PolicyUpdateReceiver#onPolicySetResult(Context,
+     * String, Bundle, TargetUser, PolicyUpdateResult)} will notify the admin on whether the policy
+     * was successfully cleared or not. This callback will contain:
+     * <ul>
+     * <li> The policy identifier
+     * {@link DevicePolicyIdentifiers#PERSISTENT_PREFERRED_ACTIVITY_POLICY}
+     * <li> The additional policy params bundle, which contains
+     * {@link PolicyUpdateReceiver#EXTRA_INTENT_FILTER} the intent filter the policy applies to
+     * <li> The {@link TargetUser} that this policy relates to
+     * <li> The {@link PolicyUpdateResult}, which will be
+     * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully cleared or the
+     * reason the policy failed to be cleared
+     * (e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY})
+     * </ul>
+     * If there has been a change to the policy,
+     * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser,
+     * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the
+     * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult}
+     * will contain the reason why the policy changed.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the
      *              caller is not a device admin.
@@ -9862,6 +9924,9 @@
      *                                  profile owner of an organization-owned managed profile.
      * @throws IllegalArgumentException if called on the parent profile and the package
      *                                  provided is not a pre-installed system package.
+     * @throws IllegalStateException while trying to set default sms app on the profile and
+     *                             {@link ManagedSubscriptionsPolicy#TYPE_ALL_MANAGED_SUBSCRIPTIONS}
+     *                             policy is not set.
      */
     @RequiresPermission(value = MANAGE_DEVICE_POLICY_DEFAULT_SMS, conditional = true)
     public void setDefaultSmsApplication(@Nullable ComponentName admin,
@@ -11472,6 +11537,26 @@
      * {@link #getParentProfileInstance(ComponentName)}. To set a restriction globally, call
      * {@link #addUserRestrictionGlobally} instead.
      *
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, after the user restriction
+     * policy has been set, {@link PolicyUpdateReceiver#onPolicySetResult(Context, String,
+     * Bundle, TargetUser, PolicyUpdateResult)} will notify the admin on whether the policy was
+     * successfully set or not. This callback will contain:
+     * <ul>
+     * <li> The policy identifier returned from
+     * {@link DevicePolicyIdentifiers#getIdentifierForUserRestriction(String)}
+     * <li> The {@link TargetUser} that this policy relates to
+     * <li> The {@link PolicyUpdateResult}, which will be
+     * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully set or the
+     * reason the policy failed to be set
+     * (e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY})
+     * </ul>
+     * If there has been a change to the policy,
+     * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser,
+     * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the
+     * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult}
+     * will contain the reason why the policy changed.
+     *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param key   The key of the restriction.
      * @throws SecurityException if {@code admin} is not a device or profile owner and if the caller
@@ -11504,6 +11589,25 @@
      * <p> See the constants in {@link android.os.UserManager} for the list of restrictions that can
      * be enforced device-wide. These constants will also state in their documentation which
      * permission is required to manage the restriction using this API.
+     * <p>
+     * After the user restriction policy has been set,
+     * {@link PolicyUpdateReceiver#onPolicySetResult(Context, String, Bundle, TargetUser,
+     * PolicyUpdateResult)} will notify the admin on whether the policy was successfully set or not.
+     * This callback will contain:
+     * <ul>
+     * <li> The policy identifier returned from
+     * {@link DevicePolicyIdentifiers#getIdentifierForUserRestriction(String)}
+     * <li> The {@link TargetUser} that this policy relates to
+     * <li> The {@link PolicyUpdateResult}, which will be
+     * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully set or the
+     * reason the policy failed to be set
+     * (e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY})
+     * </ul>
+     * If there has been a change to the policy,
+     * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser,
+     * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the
+     * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult}
+     * will contain the reason why the policy changed.
      *
      * @param key The key of the restriction.
      * @throws SecurityException if {@code admin} is not a device or profile owner and if the
@@ -11541,6 +11645,26 @@
      * above, calling this API will result in clearing any local and global restriction with the
      * specified key that was previously set by the caller.
      *
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, after the user restriction
+     * policy has been cleared, {@link PolicyUpdateReceiver#onPolicySetResult(Context, String,
+     * Bundle, TargetUser, PolicyUpdateResult)} will notify the admin on whether the policy was
+     * successfully cleared or not. This callback will contain:
+     * <ul>
+     * <li> The policy identifier returned from
+     * {@link DevicePolicyIdentifiers#getIdentifierForUserRestriction(String)}
+     * <li> The {@link TargetUser} that this policy relates to
+     * <li> The {@link PolicyUpdateResult}, which will be
+     * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully cleared or the
+     * reason the policy failed to be cleared
+     * (e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY})
+     * </ul>
+     * If there has been a change to the policy,
+     * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser,
+     * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the
+     * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult}
+     * will contain the reason why the policy changed.
+     *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param key   The key of the restriction.
      * @throws SecurityException if {@code admin} is not a device or profile owner  and if the
@@ -11689,6 +11813,27 @@
      * {@link #getParentProfileInstance(ComponentName)}, where the caller must be the profile owner
      * of an organization-owned managed profile and the package must be a system package. If called
      * on the parent instance, then the package is hidden or unhidden in the personal profile.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, after the application hidden
+     * policy has been set, {@link PolicyUpdateReceiver#onPolicySetResult(Context, String,
+     * Bundle, TargetUser, PolicyUpdateResult)} will notify the admin on whether the policy was
+     * successfully set or not. This callback will contain:
+     * <ul>
+     * <li> The policy identifier
+     * {@link DevicePolicyIdentifiers#APPLICATION_HIDDEN_POLICY}
+     * <li> The additional policy params bundle, which contains
+     * {@link PolicyUpdateReceiver#EXTRA_PACKAGE_NAME} the package name the policy applies to
+     * <li> The {@link TargetUser} that this policy relates to
+     * <li> The {@link PolicyUpdateResult}, which will be
+     * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully set or the
+     * reason the policy failed to be set
+     * (e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY})
+     * </ul>
+     * If there has been a change to the policy,
+     * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser,
+     * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the
+     * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult}
+     * will contain the reason why the policy changed.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
      *            {@code null} if the caller is not a device admin.
@@ -11728,6 +11873,9 @@
      * of an organization-owned managed profile and the package must be a system package. If called
      * on the parent instance, this will determine whether the package is hidden or unhidden in the
      * personal profile.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, the returned policy will be the
+     * current resolved policy rather than the policy set by the calling admin.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
      *            {@code null} if the caller is not a device admin.
@@ -11852,6 +12000,27 @@
      * {@link #getParentProfileInstance(ComponentName)} by the profile owner on an
      * organization-owned device, to restrict accounts that may not be managed on the primary
      * profile.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, after the account management
+     * disabled policy has been set, {@link PolicyUpdateReceiver#onPolicySetResult(Context, String,
+     * Bundle, TargetUser, PolicyUpdateResult)} will notify the admin on whether the policy was
+     * successfully set or not. This callback will contain:
+     * <ul>
+     * <li> The policy identifier
+     * {@link DevicePolicyIdentifiers#ACCOUNT_MANAGEMENT_DISABLED_POLICY}
+     * <li> The additional policy params bundle, which contains
+     * {@link PolicyUpdateReceiver#EXTRA_ACCOUNT_TYPE} the account type the policy applies to
+     * <li> The {@link TargetUser} that this policy relates to
+     * <li> The {@link PolicyUpdateResult}, which will be
+     * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully set or the
+     * reason the policy failed to be set
+     * (e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY})
+     * </ul>
+     * If there has been a change to the policy,
+     * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser,
+     * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the
+     * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult}
+     * will contain the reason why the policy changed.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the
      *              caller is not a device admin.
@@ -11984,6 +12153,28 @@
      * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK_TASK}. See
      * {@link #isAffiliatedUser}.
      * Any package set via this method will be cleared if the user becomes unaffiliated.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, after the lock task policy has
+     * been set, {@link PolicyUpdateReceiver#onPolicySetResult(Context, String, Bundle, TargetUser,
+     * PolicyUpdateResult)} will notify the admin on whether the policy was successfully set or not.
+     * This callback will contain:
+     * <ul>
+     * <li> The policy identifier {@link DevicePolicyIdentifiers#LOCK_TASK_POLICY}
+     * <li> The {@link TargetUser} that this policy relates to
+     * <li> The {@link PolicyUpdateResult}, which will be
+     * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully set or the
+     * reason the policy failed to be set
+     * (e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY})
+     * </ul>
+     * If there has been a change to the policy,
+     * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser,
+     * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the
+     * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult}
+     * will contain the reason why the policy changed.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, lock task features and lock task
+     * packages are bundled as one policy. A failure to apply one will result in a failure to apply
+     * the other.
      *
      * @param packages The list of packages allowed to enter lock task mode
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the
@@ -12013,6 +12204,9 @@
 
     /**
      * Returns the list of packages allowed to start the lock task mode.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, the returned policy will be the
+     * current resolved policy rather than the policy set by the calling admin.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the
      *              caller is not a device admin.
@@ -12065,6 +12259,28 @@
      * permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK_TASK}. See
      * {@link #isAffiliatedUser}.
      * Any features set using this method are cleared if the user becomes unaffiliated.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, after the lock task features
+     * policy has been set, {@link PolicyUpdateReceiver#onPolicySetResult(Context, String, Bundle,
+     * TargetUser, PolicyUpdateResult)} will notify the admin on whether the policy was
+     * successfully set or not. This callback will contain:
+     * <ul>
+     * <li> The policy identifier {@link DevicePolicyIdentifiers#LOCK_TASK_POLICY}
+     * <li> The {@link TargetUser} that this policy relates to
+     * <li> The {@link PolicyUpdateResult}, which will be
+     * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully set or the
+     * reason the policy failed to be set
+     * (e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY})
+     * </ul>
+     * If there has been a change to the policy,
+     * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser,
+     * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the
+     * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult}
+     * will contain the reason why the policy changed.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, lock task features and lock task
+     * packages are bundled as one policy. A failure to apply one will result in a failure to apply
+     * the other.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the
      *               caller is not a device admin.
@@ -12089,6 +12305,9 @@
 
     /**
      * Gets which system features are enabled for LockTask mode.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, the returned policy will be the
+     * current resolved policy rather than the policy set by the calling admin.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the
      *               caller is not a device admin.
@@ -12574,6 +12793,27 @@
      * profile owner, or by a delegate given the {@link #DELEGATION_BLOCK_UNINSTALL} scope via
      * {@link #setDelegatedScopes} or holders of the permission
      * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_APPS_CONTROL}.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, after the set uninstall blocked
+     * policy has been set, {@link PolicyUpdateReceiver#onPolicySetResult(Context, String,
+     * Bundle, TargetUser, PolicyUpdateResult)} will notify the admin on whether the policy was
+     * successfully set or not. This callback will contain:
+     * <ul>
+     * <li> The policy identifier
+     * {@link DevicePolicyIdentifiers#PACKAGE_UNINSTALL_BLOCKED_POLICY}
+     * <li> The additional policy params bundle, which contains
+     * {@link PolicyUpdateReceiver#EXTRA_PACKAGE_NAME} the package name the policy applies to
+     * <li> The {@link TargetUser} that this policy relates to
+     * <li> The {@link PolicyUpdateResult}, which will be
+     * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully set or the
+     * reason the policy failed to be set
+     * (e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY})
+     * </ul>
+     * If there has been a change to the policy,
+     * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser,
+     * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the
+     * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult}
+     * will contain the reason why the policy changed.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the
      *               caller is not a device admin.
@@ -12611,6 +12851,9 @@
      * <strong>Note:</strong> If your app targets Android 11 (API level 30) or higher,
      * this method returns a filtered result. Learn more about how to
      * <a href="/training/basics/intents/package-visibility">manage package visibility</a>.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, the returned policy will be the
+     * current resolved policy rather than the policy set by the calling admin.
      *
      * @param admin The name of the admin component whose blocking policy will be checked, or
      *            {@code null} to check whether any admin has blocked the uninstallation. Starting
@@ -15492,7 +15735,7 @@
         throwIfParentInstance("getAllCrossProfilePackages");
         if (mService != null) {
             try {
-                return new ArraySet<>(mService.getAllCrossProfilePackages());
+                return new ArraySet<>(mService.getAllCrossProfilePackages(mContext.getUserId()));
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -15720,6 +15963,25 @@
      * control over apps. User will not be able to clear app data or force-stop packages. When
      * called by a device owner, applies to all users on the device. Packages with user control
      * disabled are exempted from App Standby Buckets.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, after the user control disabled
+     * packages policy has been set, {@link PolicyUpdateReceiver#onPolicySetResult(Context, String,
+     * Bundle, TargetUser, PolicyUpdateResult)} will notify the admin on whether the policy was
+     * successfully set or not. This callback will contain:
+     * <ul>
+     * <li> The policy identifier
+     * {@link DevicePolicyIdentifiers#USER_CONTROL_DISABLED_PACKAGES_POLICY}
+     * <li> The {@link TargetUser} that this policy relates to
+     * <li> The {@link PolicyUpdateResult}, which will be
+     * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully set or the
+     * reason the policy failed to be set
+     * (e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY})
+     * </ul>
+     * If there has been a change to the policy,
+     * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser,
+     * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the
+     * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult}
+     * will contain the reason why the policy changed.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the
      *               caller is not a device admin.
@@ -15746,6 +16008,9 @@
      * Returns the list of packages over which user control is disabled by a device or profile
      * owner or holders of the permission
      * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_APPS_CONTROL}.
+     * <p>
+     * Starting from {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, the returned policy will be the
+     * current resolved policy rather than the policy set by the calling admin.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the
      *               caller is not a device admin.
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java
index 5345947..0e78275 100644
--- a/core/java/android/app/admin/DevicePolicyManagerInternal.java
+++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java
@@ -23,6 +23,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.UserHandle;
+import android.os.UserManager.EnforcingUser;
 
 import java.util.List;
 import java.util.Set;
@@ -206,7 +207,7 @@
      *
      * @hide
      */
-    public abstract List<String> getAllCrossProfilePackages();
+    public abstract List<String> getAllCrossProfilePackages(int userId);
 
     /**
      * Returns the default package names set by the OEM that are allowed to communicate
@@ -326,4 +327,10 @@
      */
     public abstract List<Bundle> getApplicationRestrictionsPerAdminForUser(
             String packageName, @UserIdInt int userId);
+
+    /**
+     *  Returns a list of users who set a user restriction on a given user.
+     */
+    public abstract List<EnforcingUser> getUserRestrictionSources(String restriction,
+                @UserIdInt int userId);
 }
diff --git a/core/java/android/app/admin/DevicePolicyResources.java b/core/java/android/app/admin/DevicePolicyResources.java
index 0512c75..456c6af 100644
--- a/core/java/android/app/admin/DevicePolicyResources.java
+++ b/core/java/android/app/admin/DevicePolicyResources.java
@@ -1864,9 +1864,54 @@
             public static final String WORK_PROFILE_TELEPHONY_PAUSED_TURN_ON_BUTTON =
                     PREFIX + "TURN_ON_WORK_PROFILE_BUTTON_TEXT";
 
+            /**
+             * Information section shown on a dialog when the user is unable to place a call in
+             * the personal profile due to admin restrictions, and must choose whether to place
+             * the call from the work profile or cancel.
+             */
+            public static final String MINIRESOLVER_WORK_TELEPHONY_CALL_BLOCKED_INFORMATION =
+                    PREFIX + "MINIRESOLVER_WORK_TELEPHONY_INFORMATION";
+
+            /**
+             * Information section shown on a dialog when the user is unable to send a text in
+             * the personal profile due to admin restrictions, and must choose whether to place
+             * the call from the work profile or cancel.
+             */
+            public static final String MINIRESOLVER_WORK_TELEPHONY_TEXT_BLOCKED_INFORMATION =
+                    PREFIX + "MINIRESOLVER_WORK_TELEPHONY_INFORMATION";
+
+
+            /**
+             * Button for a dialog shown when the user is unable to place a call in the personal
+             * profile due to admin restrictions, and must choose whether to place the call from
+             * the work profile or cancel.
+             */
+            public static final String MINIRESOLVER_CALL_FROM_WORK =
+                    PREFIX + "MINIRESOLVER_CALL_FROM_WORK";
+
+            /**
+             * Button for a dialog shown when the user has no apps capable of handling an intent
+             * in the personal profile, and must choose whether to open the intent in a
+             * cross-profile app in the work profile, or cancel.
+             */
+            public static final String MINIRESOLVER_SWITCH_TO_WORK =
+                    PREFIX + "MINIRESOLVER_SWITCH_TO_WORK";
+
+            /**
+             * Title for a dialog shown when the user has no apps capable of handling an intent
+             * in the personal profile, and must choose whether to open the intent in a
+             * cross-profile app in the work profile, or open in the same profile browser. Accepts
+             * the app name as a param.
+             */
             public static final String MINIRESOLVER_OPEN_IN_WORK =
                     PREFIX + "MINIRESOLVER_OPEN_IN_WORK";
 
+            /**
+             * Title for a dialog shown when the user has no apps capable of handling an intent
+             * in the personal profile, and must choose whether to open the intent in a
+             * cross-profile app in the personal profile, or open in the same profile browser.
+             * Accepts the app name as a param.
+             */
             public static final String MINIRESOLVER_OPEN_IN_PERSONAL =
                     PREFIX + "MINIRESOLVER_OPEN_IN_PERSONAL";
 
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 9795cab..003e804 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -515,7 +515,7 @@
     void setCrossProfilePackages(in ComponentName admin, in List<String> packageNames);
     List<String> getCrossProfilePackages(in ComponentName admin);
 
-    List<String> getAllCrossProfilePackages();
+    List<String> getAllCrossProfilePackages(int userId);
     List<String> getDefaultCrossProfilePackages();
 
     boolean isManagedKiosk();
diff --git a/core/java/android/app/assist/OWNERS b/core/java/android/app/assist/OWNERS
index e857c72..80ecaa4 100644
--- a/core/java/android/app/assist/OWNERS
+++ b/core/java/android/app/assist/OWNERS
@@ -3,3 +3,5 @@
 markpun@google.com
 lpeter@google.com
 tymtsai@google.com
+hackz@google.com
+volnov@google.com
\ No newline at end of file
diff --git a/core/java/android/app/backup/BackupManagerMonitorWrapper.java b/core/java/android/app/backup/BackupManagerMonitorWrapper.java
index 0b18995..39bfb1b 100644
--- a/core/java/android/app/backup/BackupManagerMonitorWrapper.java
+++ b/core/java/android/app/backup/BackupManagerMonitorWrapper.java
@@ -16,9 +16,12 @@
 
 package android.app.backup;
 
+import android.annotation.Nullable;
 import android.os.Bundle;
 import android.os.RemoteException;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  * Wrapper around {@link BackupManagerMonitor} that helps with IPC between the caller of backup
  * APIs and the backup service.
@@ -26,16 +29,24 @@
  * The caller implements {@link BackupManagerMonitor} and passes it into framework APIs that run on
  * the caller's process. Those framework APIs will then wrap it around this class when doing the
  * actual IPC.
+ *
+ * @hide
  */
-class BackupManagerMonitorWrapper extends IBackupManagerMonitor.Stub {
+@VisibleForTesting
+public class BackupManagerMonitorWrapper extends IBackupManagerMonitor.Stub {
+    @Nullable
     private final BackupManagerMonitor mMonitor;
 
-    BackupManagerMonitorWrapper(BackupManagerMonitor monitor) {
+    public BackupManagerMonitorWrapper(@Nullable BackupManagerMonitor monitor) {
         mMonitor = monitor;
     }
 
     @Override
     public void onEvent(final Bundle event) throws RemoteException {
+        if (mMonitor == null) {
+            // It's valid for the underlying monitor to be null, so just return.
+            return;
+        }
         mMonitor.onEvent(event);
     }
 }
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index af5c6dd..2e67225 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -1331,10 +1331,12 @@
 
     /**
      * Enable or disable secure transport for testing. Defaults to enabled.
+     * Should not be used outside of testing.
      *
      * @param enabled true to enable. false to disable.
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES)
     public void enableSecureTransport(boolean enabled) {
         try {
             mService.enableSecureTransport(enabled);
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index fa99b59..2200af6 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -145,7 +145,7 @@
     private boolean mExported;
     private boolean mNoPerms;
     private boolean mSingleUser;
-    private SparseBooleanArray mUsersRedirectedToOwner = new SparseBooleanArray();
+    private SparseBooleanArray mUsersRedirectedToOwnerForMedia = new SparseBooleanArray();
 
     private ThreadLocal<AttributionSource> mCallingAttributionSource;
 
@@ -874,34 +874,43 @@
             return true;
         }
 
-        if (isAuthorityRedirectedForCloneProfile(mAuthority)) {
-            if (mUsersRedirectedToOwner.indexOfKey(callingUserId) >= 0) {
-                return mUsersRedirectedToOwner.get(callingUserId);
+        // Provider user-id will be determined from User Space of the calling app.
+        return isContentRedirectionAllowedForUser(callingUserId);
+    }
+
+    /**
+     * Verify that content redirection is allowed or not.
+     * We check:
+     * 1. Type of Authority
+     * 2. UserProperties allow content sharing
+     *
+     * @param incomingUserId - Provider's user-id to be passed should be based upon:
+     *                       1. If client is a cloned app running in user 10, it should be that (10)
+     *                       2. If client is accessing content by hinting user space of content,
+     *                       like sysUi (residing in user 0) accessing 'content://11@media/external'
+     *                       then it should be 11.
+     */
+    private boolean isContentRedirectionAllowedForUser(int incomingUserId) {
+        if (MediaStore.AUTHORITY.equals(mAuthority)) {
+            int incomingUserIdIndex = mUsersRedirectedToOwnerForMedia.indexOfKey(incomingUserId);
+            if (incomingUserIdIndex >= 0) {
+                return mUsersRedirectedToOwnerForMedia.valueAt(incomingUserIdIndex);
             }
 
             // Haven't seen this user yet, look it up
-            try {
-                UserHandle callingUser = UserHandle.getUserHandleForUid(uid);
-                Context callingUserContext = mContext.createPackageContextAsUser("system",
-                        0, callingUser);
-                UserManager um = callingUserContext.getSystemService(UserManager.class);
-
-                if (um != null && um.isCloneProfile()) {
-                    UserHandle parent = um.getProfileParent(callingUser);
-
-                    if (parent != null && parent.equals(myUserHandle())) {
-                        mUsersRedirectedToOwner.put(callingUserId, true);
-                        return true;
-                    }
+            UserManager um = mContext.getSystemService(UserManager.class);
+            if (um != null && um.getUserProperties(UserHandle.of(incomingUserId))
+                    .isMediaSharedWithParent()) {
+                UserHandle parent = um.getProfileParent(UserHandle.of(incomingUserId));
+                if (parent != null && parent.equals(myUserHandle())) {
+                    mUsersRedirectedToOwnerForMedia.put(incomingUserId, true);
+                    return true;
                 }
-            } catch (PackageManager.NameNotFoundException e) {
-                // ignore
             }
 
-            mUsersRedirectedToOwner.put(callingUserId, false);
+            mUsersRedirectedToOwnerForMedia.put(incomingUserId, false);
             return false;
         }
-
         return false;
     }
 
@@ -2734,7 +2743,11 @@
         String auth = uri.getAuthority();
         if (!mSingleUser) {
             int userId = getUserIdFromAuthority(auth, UserHandle.USER_CURRENT);
-            if (userId != UserHandle.USER_CURRENT && userId != mContext.getUserId()) {
+            if (userId != UserHandle.USER_CURRENT
+                    && userId != mContext.getUserId()
+                    // Since userId specified in content uri, the provider userId would be
+                    // determined from it.
+                    && !isContentRedirectionAllowedForUser(userId)) {
                 throw new SecurityException("trying to query a ContentProvider in user "
                         + mContext.getUserId() + " with a uri belonging to user " + userId);
             }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 307f306..e763e95 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -6907,7 +6907,7 @@
      *
      * @hide
      */
-    public static final int FLAG_IGNORE_EPHEMERAL = 0x00000200;
+    public static final int FLAG_IGNORE_EPHEMERAL = 0x80000000;
 
     /**
      * If set, the new activity is not kept in the history stack.  As soon as
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index b5d2f2c..036a4eb 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1698,27 +1698,6 @@
     }
 
     /**
-     * Returns whether the activity supports size changes.
-     * @hide
-     */
-    @SizeChangesSupportMode
-    public int supportsSizeChanges() {
-        if (isChangeEnabled(FORCE_NON_RESIZE_APP)) {
-            return SIZE_CHANGES_UNSUPPORTED_OVERRIDE;
-        }
-
-        if (supportsSizeChanges) {
-            return SIZE_CHANGES_SUPPORTED_METADATA;
-        }
-
-        if (isChangeEnabled(FORCE_RESIZE_APP)) {
-            return SIZE_CHANGES_SUPPORTED_OVERRIDE;
-        }
-
-        return SIZE_CHANGES_UNSUPPORTED_METADATA;
-    }
-
-    /**
      * Returns if the activity should never be sandboxed to the activity window bounds.
      * @hide
      */
diff --git a/core/java/android/content/pm/CrossProfileApps.java b/core/java/android/content/pm/CrossProfileApps.java
index 7ac8f37..c3df17d 100644
--- a/core/java/android/content/pm/CrossProfileApps.java
+++ b/core/java/android/content/pm/CrossProfileApps.java
@@ -27,6 +27,7 @@
 import android.annotation.TestApi;
 import android.annotation.UserHandleAware;
 import android.app.Activity;
+import android.app.ActivityOptions;
 import android.app.AppOpsManager.Mode;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
@@ -110,8 +111,8 @@
                     component,
                     targetUser.getIdentifier(),
                     true,
-                    null,
-                    null);
+                    mContext.getActivityToken(),
+                    ActivityOptions.makeBasic().toBundle());
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
         }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index d802b46..47a5db8 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -791,4 +791,6 @@
     void setKeepUninstalledPackages(in List<String> packageList);
 
     boolean[] canPackageQuery(String sourcePackageName, in String[] targetPackageNames, int userId);
+
+    boolean waitForHandler(long timeoutMillis, boolean forBackgroundHandler);
 }
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index afe375c..96118f6 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -616,6 +616,7 @@
     /** {@hide} */
     public PackageInstaller(IPackageInstaller installer,
             String installerPackageName, String installerAttributionTag, int userId) {
+        Objects.requireNonNull(installer, "installer cannot be null");
         mInstaller = installer;
         mInstallerPackageName = installerPackageName;
         mAttributionTag = installerAttributionTag;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 7f19897..8fafb18 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2883,6 +2883,20 @@
             "android.software.car.templates_host";
 
     /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:If this
+     * feature is supported, the device should also declare {@link #FEATURE_AUTOMOTIVE} and show
+     * a UI that can display multiple tasks at the same time on a single display. The user can
+     * perform multiple actions on different tasks simultaneously. Apps open in split screen mode
+     * by default, instead of full screen. Unlike Android's multi-window mode, where users can
+     * choose how to display apps, the device determines how apps are shown.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_CAR_SPLITSCREEN_MULTITASKING =
+            "android.software.car.splitscreen_multitasking";
+
+    /**
      * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature(String, int)}: If this feature is supported, the device supports
      * {@link android.security.identity.IdentityCredentialStore} implemented in secure hardware
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 7e0954a..be8b2a2 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -168,7 +168,8 @@
      * <p>Starting foreground service with this type from apps targeting API level
      * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and later, will require permission
      * {@link android.Manifest.permission#FOREGROUND_SERVICE_PHONE_CALL} and
-     * {@link android.Manifest.permission#MANAGE_OWN_CALLS}.
+     * {@link android.Manifest.permission#MANAGE_OWN_CALLS} or holding the default
+     * {@link android.app.role.RoleManager#ROLE_DIALER dialer role}.
      */
     @RequiresPermission(
             allOf = {
diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING
index b601275..3ffbe1d 100644
--- a/core/java/android/content/pm/TEST_MAPPING
+++ b/core/java/android/content/pm/TEST_MAPPING
@@ -1,223 +1,170 @@
 {
-  "imports": [
-    {
-      "path": "frameworks/base/core/tests/coretests/src/android/content/pm"
-    },
-    {
-      "path": "frameworks/base/services/tests/PackageManagerServiceTests"
-    },
-    {
-      "path": "frameworks/base/services/tests/PackageManager"
-    },
-    {
-      "path": "frameworks/base/services/tests/PackageManagerComponentOverrideTests"
-    },
-    {
-      "path": "frameworks/base/services/tests/servicestests/src/com/android/server/pm"
-    },
-    {
-      "path": "cts/tests/tests/packageinstaller"
-    },
-    {
-      "path": "cts/hostsidetests/stagedinstall"
-    },
-    {
-      "path": "cts/hostsidetests/packagemanager"
-    },
-    {
-      "path": "cts/hostsidetests/os/test_mappings/packagemanager"
-    },
-    {
-      "path": "cts/hostsidetests/appsearch"
-    },
-    {
-      "path": "system/apex/tests"
-    },
-    {
-      "path": "cts/tests/tests/content/pm/SecureFrp"
-    }
-  ],
-  "presubmit": [
-    {
-      "name": "CtsInstantAppTests",
-      "file_patterns": ["(/|^)InstantApp[^/]*"]
-    },
-    {
-      "name": "CarrierAppIntegrationTestCases"
-    },
-    {
-      "name": "ApkVerityTest"
-    },
-    {
-      "name": "CtsSilentUpdateHostTestCases"
-    },
-    {
-      "name": "CtsSuspendAppsTestCases"
-    },
-    {
-      "name": "CtsAppFgsTestCases",
-      "file_patterns": ["(/|^)ServiceInfo[^/]*"],
-      "options": [
+    "imports":[
         {
-          "include-annotation": "android.platform.test.annotations.Presubmit"
+            "path":"frameworks/base/core/tests/coretests/src/android/content/pm"
         },
         {
-          "exclude-annotation": "androidx.test.filters.LargeTest"
+            "path":"frameworks/base/services/tests/PackageManagerServiceTests"
         },
         {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
+            "path":"frameworks/base/services/tests/PackageManager"
+        },
+        {
+            "path":"frameworks/base/services/tests/PackageManagerComponentOverrideTests"
+        },
+        {
+            "path":"frameworks/base/services/tests/servicestests/src/com/android/server/pm"
+        },
+        {
+            "path":"cts/tests/tests/packageinstaller"
+        },
+        {
+            "path":"cts/hostsidetests/stagedinstall"
+        },
+        {
+            "path":"cts/hostsidetests/packagemanager"
+        },
+        {
+            "path":"cts/hostsidetests/os/test_mappings/packagemanager"
+        },
+        {
+            "path":"cts/hostsidetests/appsearch"
+        },
+        {
+            "path":"system/apex/tests"
+        },
+        {
+            "path":"cts/tests/tests/content/pm/SecureFrp"
         }
-      ]
-    },
-    {
-      "name": "CtsShortFgsTestCases",
-      "file_patterns": ["(/|^)ServiceInfo[^/]*"],
-      "options": [
+    ],
+    "presubmit":[
         {
-          "include-annotation": "android.platform.test.annotations.Presubmit"
+            "name":"CtsInstantAppTests",
+            "file_patterns":[
+                "(/|^)InstantApp[^/]*"
+            ]
         },
         {
-          "exclude-annotation": "androidx.test.filters.LargeTest"
+            "name":"CarrierAppIntegrationTestCases"
         },
         {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
+            "name":"ApkVerityTest"
+        },
+        {
+            "name":"CtsSilentUpdateHostTestCases"
+        },
+        {
+            "name":"CtsSuspendAppsTestCases"
+        },
+        {
+            "name":"CtsAppFgsTestCases",
+            "file_patterns":[
+                "(/|^)ServiceInfo[^/]*"
+            ],
+            "options":[
+                {
+                    "include-annotation":"android.platform.test.annotations.Presubmit"
+                },
+                {
+                    "exclude-annotation":"androidx.test.filters.LargeTest"
+                },
+                {
+                    "exclude-annotation":"androidx.test.filters.FlakyTest"
+                }
+            ]
+        },
+        {
+            "name":"CtsShortFgsTestCases",
+            "file_patterns":[
+                "(/|^)ServiceInfo[^/]*"
+            ],
+            "options":[
+                {
+                    "include-annotation":"android.platform.test.annotations.Presubmit"
+                },
+                {
+                    "exclude-annotation":"androidx.test.filters.LargeTest"
+                },
+                {
+                    "exclude-annotation":"androidx.test.filters.FlakyTest"
+                }
+            ]
+        },
+        {
+            "name":"CtsIncrementalInstallHostTestCases",
+            "options":[
+                {
+                    "include-filter":"android.incrementalinstall.cts.IncrementalFeatureTest"
+                }
+            ]
         }
-      ]
-    },
-    {
-      "name": "CtsIncrementalInstallHostTestCases",
-      "options": [
+    ],
+    "presubmit-large":[
         {
-          "include-filter": "android.incrementalinstall.cts.IncrementalFeatureTest"
-        }
-      ]
-    }
-  ],
-  "presubmit-large": [
-    {
-      "name": "CtsContentTestCases",
-      "options": [
-        {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
+            "name":"CtsContentTestCases",
+            "options":[
+                {
+                    "exclude-annotation":"androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation":"org.junit.Ignore"
+                },
+                {
+                    "include-filter":"android.content.pm.cts"
+                }
+            ]
         },
         {
-          "exclude-annotation": "org.junit.Ignore"
+            "name":"CtsUsesNativeLibraryTest",
+            "options":[
+                {
+                    "exclude-annotation":"androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation":"org.junit.Ignore"
+                }
+            ]
         },
         {
-          "include-filter": "android.content.pm.cts"
-        }
-      ]
-    },
-    {
-      "name": "CtsUsesNativeLibraryTest",
-      "options": [
-        {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
+            "name":"CtsSuspendAppsPermissionTestCases",
+            "options":[
+                {
+                    "exclude-annotation":"androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation":"org.junit.Ignore"
+                }
+            ]
         },
         {
-          "exclude-annotation": "org.junit.Ignore"
+            "name":"CtsAppSecurityHostTestCases",
+            "options":[
+                {
+                    "include-annotation":"android.platform.test.annotations.Presubmit"
+                },
+                {
+                    "exclude-annotation":"android.platform.test.annotations.Postsubmit"
+                },
+                {
+                    "exclude-annotation":"androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation":"org.junit.Ignore"
+                }
+            ]
         }
-      ]
-    },
-    {
-      "name": "CtsSuspendAppsPermissionTestCases",
-      "options": [
+    ],
+    "postsubmit":[
         {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
+            "name":"CtsAppSecurityHostTestCases",
+            "options":[
+                {
+                    "include-filter":"android.appsecurity.cts.AppSecurityTests#testPermissionDiffCert"
+                }
+            ]
         },
         {
-          "exclude-annotation": "org.junit.Ignore"
+            "name":"CtsInstallHostTestCases"
         }
-      ]
-    },
-    {
-      "name": "CtsAppSecurityHostTestCases",
-      "options": [
-        {
-          "include-annotation": "android.platform.test.annotations.Presubmit"
-        },
-        {
-          "exclude-annotation": "android.platform.test.annotations.Postsubmit"
-        },
-        {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
-        },
-        {
-          "exclude-annotation": "org.junit.Ignore"
-        }
-      ]
-    }
-  ],
-  "postsubmit": [
-    {
-      "name": "CtsAppSecurityHostTestCases",
-      "options": [
-        {
-          "include-filter": "android.appsecurity.cts.AppSecurityTests#testPermissionDiffCert"
-        }
-      ]
-    },
-    {
-      "name": "CtsInstallHostTestCases"
-    }
-  ],
-  "staged-platinum-postsubmit": [
-    {
-      "name": "CtsIncrementalInstallHostTestCases"
-    },
-    {
-      "name": "CtsAppSecurityHostTestCases",
-      "options": [
-        {
-          "include-filter": "android.appsecurity.cts.SplitTests"
-        },
-        {
-          "include-filter": "android.appsecurity.cts.EphemeralTest"
-        }
-      ]
-    },
-    {
-      "name": "CtsContentTestCases",
-      "options": [
-        {
-          "include-filter": "android.content.cts.IntentFilterTest"
-        }
-      ]
-    }
-  ],
-  "platinum-postsubmit": [
-      {
-        "name": "CtsIncrementalInstallHostTestCases",
-        "options": [
-            {
-                "exclude-annotation": "androidx.test.filters.FlakyTest"
-            }
-        ]
-      },
-      {
-        "name": "CtsAppSecurityHostTestCases",
-        "options": [
-            {
-                "include-filter": "android.appsecurity.cts.SplitTests"
-            },
-            {
-                "include-filter": "android.appsecurity.cts.EphemeralTest"
-            },
-            {
-                "exclude-annotation": "androidx.test.filters.FlakyTest"
-            }
-        ]
-      },
-      {
-        "name": "CtsContentTestCases",
-        "options":[
-            {
-                "include-filter": "android.content.cts.IntentFilterTest"
-            },
-            {
-                "exclude-annotation": "androidx.test.filters.FlakyTest"
-            }
-        ]
-      }
-  ]
-}
+    ]
+}
\ No newline at end of file
diff --git a/core/java/android/content/pm/parsing/ApkLite.java b/core/java/android/content/pm/parsing/ApkLite.java
index 408f7ed..269bec2 100644
--- a/core/java/android/content/pm/parsing/ApkLite.java
+++ b/core/java/android/content/pm/parsing/ApkLite.java
@@ -138,11 +138,6 @@
      */
     private final boolean mIsSdkLibrary;
 
-    /**
-     * Indicates if this package allows an installer to declare update ownership of it.
-     */
-    private final boolean mAllowUpdateOwnership;
-
     public ApkLite(String path, String packageName, String splitName, boolean isFeatureSplit,
             String configForSplit, String usesSplitName, boolean isSplitRequired, int versionCode,
             int versionCodeMajor, int revisionCode, int installLocation,
@@ -153,7 +148,7 @@
             String requiredSystemPropertyName, String requiredSystemPropertyValue,
             int minSdkVersion, int targetSdkVersion, int rollbackDataPolicy,
             Set<String> requiredSplitTypes, Set<String> splitTypes,
-            boolean hasDeviceAdminReceiver, boolean isSdkLibrary, boolean allowUpdateOwnership) {
+            boolean hasDeviceAdminReceiver, boolean isSdkLibrary) {
         mPath = path;
         mPackageName = packageName;
         mSplitName = splitName;
@@ -187,7 +182,6 @@
         mRollbackDataPolicy = rollbackDataPolicy;
         mHasDeviceAdminReceiver = hasDeviceAdminReceiver;
         mIsSdkLibrary = isSdkLibrary;
-        mAllowUpdateOwnership = allowUpdateOwnership;
     }
 
     /**
@@ -480,9 +474,6 @@
         return mRollbackDataPolicy;
     }
 
-    /**
-     * Indicates if this app contains a {@link android.app.admin.DeviceAdminReceiver}.
-     */
     @DataClass.Generated.Member
     public boolean isHasDeviceAdminReceiver() {
         return mHasDeviceAdminReceiver;
@@ -496,19 +487,11 @@
         return mIsSdkLibrary;
     }
 
-    /**
-     * Indicates if this package allows an installer to declare update ownership of it.
-     */
-    @DataClass.Generated.Member
-    public boolean isAllowUpdateOwnership() {
-        return mAllowUpdateOwnership;
-    }
-
     @DataClass.Generated(
-            time = 1680122754650L,
+            time = 1643063342990L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ApkLite.java",
-            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mRevisionCode\nprivate final  int mInstallLocation\nprivate final  int mMinSdkVersion\nprivate final  int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final  boolean mFeatureSplit\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mProfileableByShell\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final  boolean mOverlayIsStatic\nprivate final  int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final  int mRollbackDataPolicy\nprivate final  boolean mHasDeviceAdminReceiver\nprivate final  boolean mIsSdkLibrary\nprivate final  boolean mAllowUpdateOwnership\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mRevisionCode\nprivate final  int mInstallLocation\nprivate final  int mMinSdkVersion\nprivate final  int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final  boolean mFeatureSplit\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mProfileableByShell\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final  boolean mOverlayIsStatic\nprivate final  int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final  int mRollbackDataPolicy\nprivate final  boolean mHasDeviceAdminReceiver\nprivate final  boolean mIsSdkLibrary\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index d209b35..4f6bcb6 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -127,8 +127,7 @@
                             null /* isFeatureSplits */, null /* usesSplitNames */,
                             null /* configForSplit */, null /* splitApkPaths */,
                             null /* splitRevisionCodes */, baseApk.getTargetSdkVersion(),
-                            null /* requiredSplitTypes */, null, /* splitTypes */
-                            baseApk.isAllowUpdateOwnership()));
+                            null /* requiredSplitTypes */, null /* splitTypes */));
         } finally {
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
@@ -154,8 +153,7 @@
                             null /* isFeatureSplits */, null /* usesSplitNames */,
                             null /* configForSplit */, null /* splitApkPaths */,
                             null /* splitRevisionCodes */, baseApk.getTargetSdkVersion(),
-                            null /* requiredSplitTypes */, null, /* splitTypes */
-                            baseApk.isAllowUpdateOwnership()));
+                            null /* requiredSplitTypes */, null /* splitTypes */));
         } finally {
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
@@ -187,37 +185,41 @@
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parseApkLite");
         try {
             for (File file : files) {
-                if (isApkFile(file)) {
-                    final ParseResult<ApkLite> result = parseApkLite(input, file, flags);
-                    if (result.isError()) {
-                        return input.error(result);
-                    }
+                if (!isApkFile(file)) {
+                    continue;
+                }
 
-                    final ApkLite lite = result.getResult();
-                    // Assert that all package names and version codes are
-                    // consistent with the first one we encounter.
-                    if (packageName == null) {
-                        packageName = lite.getPackageName();
-                        versionCode = lite.getVersionCode();
-                    } else {
-                        if (!packageName.equals(lite.getPackageName())) {
-                            return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
-                                    "Inconsistent package " + lite.getPackageName() + " in " + file
-                                            + "; expected " + packageName);
-                        }
-                        if (versionCode != lite.getVersionCode()) {
-                            return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
-                                    "Inconsistent version " + lite.getVersionCode() + " in " + file
-                                            + "; expected " + versionCode);
-                        }
-                    }
+                final ParseResult<ApkLite> result = parseApkLite(input, file, flags);
+                if (result.isError()) {
+                    return input.error(result);
+                }
 
-                    // Assert that each split is defined only oncuses-static-libe
-                    if (apks.put(lite.getSplitName(), lite) != null) {
+                final ApkLite lite = result.getResult();
+                // Assert that all package names and version codes are
+                // consistent with the first one we encounter.
+                if (packageName == null) {
+                    packageName = lite.getPackageName();
+                    versionCode = lite.getVersionCode();
+                } else {
+                    if (!packageName.equals(lite.getPackageName())) {
                         return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
-                                "Split name " + lite.getSplitName()
-                                        + " defined more than once; most recent was " + file);
+                                "Inconsistent package " + lite.getPackageName() + " in " + file
+                                        + "; expected " + packageName);
                     }
+                    if (versionCode != lite.getVersionCode()) {
+                        return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
+                                "Inconsistent version " + lite.getVersionCode() + " in " + file
+                                        + "; expected " + versionCode);
+                    }
+                }
+
+                // Assert that each split is defined only once
+                ApkLite prev = apks.put(lite.getSplitName(), lite);
+                if (prev != null) {
+                    return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
+                            "Split name " + lite.getSplitName()
+                                    + " defined more than once; most recent was " + file
+                                    + ", previous was " + prev.getPath());
                 }
             }
             baseApk = apks.remove(null);
@@ -301,8 +303,7 @@
         return input.success(
                 new PackageLite(codePath, baseCodePath, baseApk, splitNames, isFeatureSplits,
                         usesSplitNames, configForSplits, splitCodePaths, splitRevisionCodes,
-                        baseApk.getTargetSdkVersion(), requiredSplitTypes, splitTypes,
-                        baseApk.isAllowUpdateOwnership()));
+                        baseApk.getTargetSdkVersion(), requiredSplitTypes, splitTypes));
     }
 
     /**
@@ -429,8 +430,6 @@
                 "isFeatureSplit", false);
         boolean isSplitRequired = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE,
                 "isSplitRequired", false);
-        boolean allowUpdateOwnership = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE,
-                "allowUpdateOwnership", true);
         String configForSplit = parser.getAttributeValue(null, "configForSplit");
 
         int targetSdkVersion = DEFAULT_TARGET_SDK_VERSION;
@@ -614,7 +613,7 @@
                         overlayIsStatic, overlayPriority, requiredSystemPropertyName,
                         requiredSystemPropertyValue, minSdkVersion, targetSdkVersion,
                         rollbackDataPolicy, requiredSplitTypes.first, requiredSplitTypes.second,
-                        hasDeviceAdminReceiver, isSdkLibrary, allowUpdateOwnership));
+                        hasDeviceAdminReceiver, isSdkLibrary));
     }
 
     private static boolean isDeviceAdminReceiver(
diff --git a/core/java/android/content/pm/parsing/PackageLite.java b/core/java/android/content/pm/parsing/PackageLite.java
index e24b932..e2789c9 100644
--- a/core/java/android/content/pm/parsing/PackageLite.java
+++ b/core/java/android/content/pm/parsing/PackageLite.java
@@ -110,16 +110,10 @@
      */
     private final boolean mIsSdkLibrary;
 
-    /**
-     * Indicates if this package allows an installer to declare update ownership of it.
-     */
-    private final boolean mAllowUpdateOwnership;
-
     public PackageLite(String path, String baseApkPath, ApkLite baseApk,
             String[] splitNames, boolean[] isFeatureSplits, String[] usesSplitNames,
             String[] configForSplit, String[] splitApkPaths, int[] splitRevisionCodes,
-            int targetSdk, Set<String>[] requiredSplitTypes, Set<String>[] splitTypes,
-            boolean allowUpdateOwnership) {
+            int targetSdk, Set<String>[] requiredSplitTypes, Set<String>[] splitTypes) {
         // The following paths may be different from the path in ApkLite because we
         // move or rename the APK files. Use parameters to indicate the correct paths.
         mPath = path;
@@ -150,7 +144,6 @@
         mSplitApkPaths = splitApkPaths;
         mSplitRevisionCodes = splitRevisionCodes;
         mTargetSdk = targetSdk;
-        mAllowUpdateOwnership = allowUpdateOwnership;
     }
 
     /**
@@ -421,19 +414,12 @@
         return mIsSdkLibrary;
     }
 
-    /**
-     * Indicates if this package allows an installer to declare update ownership of it.
-     */
-    @DataClass.Generated.Member
-    public boolean isAllowUpdateOwnership() {
-        return mAllowUpdateOwnership;
-    }
-
     @DataClass.Generated(
-            time = 1680125514341L,
+            time = 1643132127068L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/content/pm/parsing/PackageLite.java",
-            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mTargetSdk\nprivate final  int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final  int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mProfileableByShell\nprivate final  boolean mUseEmbeddedDex\nprivate final  boolean mIsSdkLibrary\nprivate final  boolean mAllowUpdateOwnership\npublic  java.util.List<java.lang.String> getAllApkPaths()\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+            inputSignatures =
+                    "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mTargetSdk\nprivate final  int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final  int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mProfileableByShell\nprivate final  boolean mUseEmbeddedDex\nprivate final  boolean mIsSdkLibrary\npublic  java.util.List<java.lang.String> getAllApkPaths()\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/hardware/CameraSessionStats.java b/core/java/android/hardware/CameraSessionStats.java
index d59295e..1c2cbbc 100644
--- a/core/java/android/hardware/CameraSessionStats.java
+++ b/core/java/android/hardware/CameraSessionStats.java
@@ -65,6 +65,7 @@
     private String mUserTag;
     private int mVideoStabilizationMode;
     private int mSessionIndex;
+    private CameraExtensionSessionStats mCameraExtensionSessionStats;
 
     public CameraSessionStats() {
         mFacing = -1;
@@ -82,6 +83,7 @@
         mStreamStats = new ArrayList<CameraStreamStats>();
         mVideoStabilizationMode = -1;
         mSessionIndex = 0;
+        mCameraExtensionSessionStats = new CameraExtensionSessionStats();
     }
 
     public CameraSessionStats(String cameraId, int facing, int newCameraState,
@@ -101,6 +103,7 @@
         mInternalReconfigure = internalReconfigure;
         mStreamStats = new ArrayList<CameraStreamStats>();
         mSessionIndex = sessionIdx;
+        mCameraExtensionSessionStats = new CameraExtensionSessionStats();
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<CameraSessionStats> CREATOR =
@@ -145,6 +148,7 @@
         dest.writeString(mUserTag);
         dest.writeInt(mVideoStabilizationMode);
         dest.writeInt(mSessionIndex);
+        mCameraExtensionSessionStats.writeToParcel(dest, 0);
     }
 
     public void readFromParcel(Parcel in) {
@@ -170,6 +174,7 @@
         mUserTag = in.readString();
         mVideoStabilizationMode = in.readInt();
         mSessionIndex = in.readInt();
+        mCameraExtensionSessionStats = CameraExtensionSessionStats.CREATOR.createFromParcel(in);
     }
 
     public String getCameraId() {
@@ -243,4 +248,8 @@
     public int getSessionIndex() {
         return mSessionIndex;
     }
+
+    public CameraExtensionSessionStats getExtensionSessionStats() {
+        return mCameraExtensionSessionStats;
+    }
 }
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index 6b044fc..82694ee 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -97,27 +97,6 @@
     public @interface BiometricError {}
 
     /**
-     * Single sensor or unspecified multi-sensor behavior (prefer an explicit choice if the
-     * device is multi-sensor).
-     * @hide
-     */
-    public static final int BIOMETRIC_MULTI_SENSOR_DEFAULT = 0;
-
-    /**
-     * Use face and fingerprint sensors together.
-     * @hide
-     */
-    public static final int BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE = 1;
-
-    /**
-     * @hide
-     */
-    @IntDef({BIOMETRIC_MULTI_SENSOR_DEFAULT,
-            BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface BiometricMultiSensorMode {}
-
-    /**
      * Types of authenticators, defined at a level of granularity supported by
      * {@link BiometricManager} and {@link BiometricPrompt}.
      *
diff --git a/core/java/android/hardware/biometrics/ComponentInfoInternal.java b/core/java/android/hardware/biometrics/ComponentInfoInternal.java
index 2e708de..3b61a56 100644
--- a/core/java/android/hardware/biometrics/ComponentInfoInternal.java
+++ b/core/java/android/hardware/biometrics/ComponentInfoInternal.java
@@ -19,8 +19,6 @@
 import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.IndentingPrintWriter;
 
 /**
  * The internal class for storing the component info for a subsystem of the biometric sensor,
@@ -92,19 +90,12 @@
         dest.writeString(softwareVersion);
     }
 
-    /**
-     * Print the component info into the given stream.
-     *
-     * @param pw The stream to dump the info into.
-     * @hide
-     */
-    public void dump(@NonNull IndentingPrintWriter pw) {
-        pw.println(TextUtils.formatSimple("componentId: %s", componentId));
-        pw.increaseIndent();
-        pw.println(TextUtils.formatSimple("hardwareVersion: %s", hardwareVersion));
-        pw.println(TextUtils.formatSimple("firmwareVersion: %s", firmwareVersion));
-        pw.println(TextUtils.formatSimple("serialNumber: %s", serialNumber));
-        pw.println(TextUtils.formatSimple("softwareVersion: %s", softwareVersion));
-        pw.decreaseIndent();
+    @Override
+    public String toString() {
+        return "ComponentId: " + componentId
+                + ", HardwareVersion: " + hardwareVersion
+                + ", FirmwareVersion: " + firmwareVersion
+                + ", SerialNumber " + serialNumber
+                + ", SoftwareVersion: " + softwareVersion;
     }
 }
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
index 1286046..18c8d1b 100644
--- a/core/java/android/hardware/biometrics/IBiometricService.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -58,10 +58,10 @@
     boolean hasEnrolledBiometrics(int userId, String opPackageName);
 
     // Registers an authenticator (e.g. face, fingerprint, iris).
-    // Sensor Id in sensor props must be unique, whereas modality doesn't need to be.
+    // Id must be unique, whereas strength and modality don't need to be.
     // TODO(b/123321528): Turn strength and modality into enums.
     @EnforcePermission("USE_BIOMETRIC_INTERNAL")
-    void registerAuthenticator(int modality, in SensorPropertiesInternal props,
+    void registerAuthenticator(int id, int modality, int strength,
             IBiometricAuthenticator authenticator);
 
     // Register callback for when keyguard biometric eligibility changes.
diff --git a/core/java/android/hardware/biometrics/IBiometricSysuiReceiver.aidl b/core/java/android/hardware/biometrics/IBiometricSysuiReceiver.aidl
index 450c5ce..45f1c8a 100644
--- a/core/java/android/hardware/biometrics/IBiometricSysuiReceiver.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricSysuiReceiver.aidl
@@ -29,5 +29,7 @@
     // Notifies the client that an internal event, e.g. back button has occurred.
     void onSystemEvent(int event);
     // Notifies that the dialog has finished animating.
-    void onDialogAnimatedIn();
+    void onDialogAnimatedIn(boolean startFingerprintNow);
+    // Notifies that the fingerprint should start now (after onDialogAnimatedIn(false)).
+    void onStartFingerprintNow();
 }
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index e908ced..48b5cac 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -212,14 +212,7 @@
     @GuardedBy("mLock")
     private boolean mFoldedDeviceState;
 
-    private final CameraManager.DeviceStateListener mFoldStateListener =
-            new CameraManager.DeviceStateListener() {
-                @Override
-                public final void onDeviceStateChanged(boolean folded) {
-                    synchronized (mLock) {
-                        mFoldedDeviceState = folded;
-                    }
-                }};
+    private CameraManager.DeviceStateListener mFoldStateListener;
 
     private static final String TAG = "CameraCharacteristics";
 
@@ -245,7 +238,18 @@
     /**
      * Return the device state listener for this Camera characteristics instance
      */
-    CameraManager.DeviceStateListener getDeviceStateListener() { return mFoldStateListener; }
+    CameraManager.DeviceStateListener getDeviceStateListener() {
+        if (mFoldStateListener == null) {
+            mFoldStateListener = new CameraManager.DeviceStateListener() {
+                        @Override
+                        public final void onDeviceStateChanged(boolean folded) {
+                            synchronized (mLock) {
+                                mFoldedDeviceState = folded;
+                            }
+                        }};
+        }
+        return mFoldStateListener;
+    }
 
     /**
      * Overrides the property value
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index c6fc69e..85f8ca6 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -30,6 +30,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.graphics.Point;
+import android.hardware.CameraExtensionSessionStats;
 import android.hardware.CameraStatus;
 import android.hardware.ICameraService;
 import android.hardware.ICameraServiceListener;
@@ -1727,6 +1728,30 @@
     }
 
     /**
+     * Reports {@link CameraExtensionSessionStats} to the {@link ICameraService} to be logged for
+     * currently active session. Validation is done downstream.
+     *
+     * @param extStats Extension Session stats to be logged by cameraservice
+     *
+     * @return the key to be used with the next call.
+     *         See {@link ICameraService#reportExtensionSessionStats}.
+     * @hide
+     */
+    public static String reportExtensionSessionStats(CameraExtensionSessionStats extStats) {
+        ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
+        if (cameraService == null) {
+            Log.e(TAG, "CameraService not available. Not reporting extension stats.");
+            return "";
+        }
+        try {
+            return cameraService.reportExtensionSessionStats(extStats);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to report extension session stats to cameraservice.", e);
+        }
+        return "";
+    }
+
+    /**
      * A per-process global camera manager instance, to retain a connection to the camera service,
      * and to distribute camera availability notices to API-registered callbacks
      */
@@ -1811,6 +1836,7 @@
                         ctx.getSystemService(DeviceStateManager.class).registerCallback(
                                 new HandlerExecutor(mDeviceStateHandler), mFoldStateListener);
                     } catch (IllegalStateException e) {
+                        mFoldStateListener = null;
                         Log.v(TAG, "Failed to register device state listener!");
                         Log.v(TAG, "Device state dependent characteristics updates will not be" +
                                 "functional!");
diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
index e787779..d87226c 100644
--- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
@@ -53,6 +53,7 @@
 import android.hardware.camera2.params.ExtensionSessionConfiguration;
 import android.hardware.camera2.params.OutputConfiguration;
 import android.hardware.camera2.params.SessionConfiguration;
+import android.hardware.camera2.utils.ExtensionSessionStatsAggregator;
 import android.hardware.camera2.utils.SurfaceUtils;
 import android.media.Image;
 import android.media.ImageReader;
@@ -96,6 +97,7 @@
     private CameraCaptureSession mCaptureSession = null;
     private ISessionProcessorImpl mSessionProcessor = null;
     private final InitializeSessionHandler mInitializeHandler;
+    private final ExtensionSessionStatsAggregator mStatsAggregator;
 
     private boolean mInitialized;
 
@@ -205,6 +207,10 @@
                 extender, cameraDevice, characteristicsMapNative, repeatingRequestSurface,
                 burstCaptureSurface, postviewSurface, config.getStateCallback(),
                 config.getExecutor(), sessionId);
+
+        ret.mStatsAggregator.setClientName(ctx.getOpPackageName());
+        ret.mStatsAggregator.setExtensionType(config.getExtension());
+
         ret.initialize();
 
         return ret;
@@ -234,6 +240,9 @@
         mInitializeHandler = new InitializeSessionHandler();
         mSessionId = sessionId;
         mInterfaceLock = cameraDevice.mInterfaceLock;
+
+        mStatsAggregator = new ExtensionSessionStatsAggregator(mCameraDevice.getId(),
+                /*isAdvanced=*/true);
     }
 
     /**
@@ -523,11 +532,26 @@
                     Log.e(TAG, "Failed to stop the repeating request or end the session,"
                             + " , extension service does not respond!") ;
                 }
+                // Commit stats before closing the capture session
+                mStatsAggregator.commit(/*isFinal*/true);
                 mCaptureSession.close();
             }
         }
     }
 
+    /**
+     * Called by {@link CameraDeviceImpl} right before the capture session is closed, and before it
+     * calls {@link #release}
+     */
+    public void commitStats() {
+        synchronized (mInterfaceLock) {
+            if (mInitialized) {
+                // Only commit stats if a capture session was initialized
+                mStatsAggregator.commit(/*isFinal*/true);
+            }
+        }
+    }
+
     public void release(boolean skipCloseNotification) {
         boolean notifyClose = false;
 
@@ -608,6 +632,8 @@
         public void onConfigured(@NonNull CameraCaptureSession session) {
             synchronized (mInterfaceLock) {
                 mCaptureSession = session;
+                // Commit basic stats as soon as the capture session is created
+                mStatsAggregator.commit(/*isFinal*/false);
             }
 
             try {
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index b8e451c..e23bbc6 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -700,6 +700,14 @@
                         + " input configuration yet.");
             }
 
+            if (mCurrentExtensionSession != null) {
+                mCurrentExtensionSession.commitStats();
+            }
+
+            if (mCurrentAdvancedExtensionSession != null) {
+                mCurrentAdvancedExtensionSession.commitStats();
+            }
+
             // Notify current session that it's going away, before starting camera operations
             // After this call completes, the session is not allowed to call into CameraDeviceImpl
             if (mCurrentSession != null) {
@@ -1414,6 +1422,15 @@
                 mOfflineSwitchService = null;
             }
 
+            // Let extension sessions commit stats before disconnecting remoteDevice
+            if (mCurrentExtensionSession != null) {
+                mCurrentExtensionSession.commitStats();
+            }
+
+            if (mCurrentAdvancedExtensionSession != null) {
+                mCurrentAdvancedExtensionSession.commitStats();
+            }
+
             if (mRemoteDevice != null) {
                 mRemoteDevice.disconnect();
                 mRemoteDevice.unlinkToDeath(this, /*flags*/0);
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
index 8e7c7e0..9ebef0b 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -30,7 +30,6 @@
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CameraExtensionCharacteristics;
 import android.hardware.camera2.CameraExtensionSession;
-import android.hardware.camera2.CameraManager;
 import android.hardware.camera2.CaptureFailure;
 import android.hardware.camera2.CaptureRequest;
 import android.hardware.camera2.CaptureResult;
@@ -49,6 +48,7 @@
 import android.hardware.camera2.params.ExtensionSessionConfiguration;
 import android.hardware.camera2.params.OutputConfiguration;
 import android.hardware.camera2.params.SessionConfiguration;
+import android.hardware.camera2.utils.ExtensionSessionStatsAggregator;
 import android.hardware.camera2.utils.SurfaceUtils;
 import android.media.Image;
 import android.media.ImageReader;
@@ -90,6 +90,7 @@
     private final int mSessionId;
     private final Set<CaptureRequest.Key> mSupportedRequestKeys;
     private final Set<CaptureResult.Key> mSupportedResultKeys;
+    private final ExtensionSessionStatsAggregator mStatsAggregator;
     private boolean mCaptureResultsSupported;
 
     private CameraCaptureSession mCaptureSession = null;
@@ -242,6 +243,9 @@
                 extensionChars.getAvailableCaptureRequestKeys(config.getExtension()),
                 extensionChars.getAvailableCaptureResultKeys(config.getExtension()));
 
+        session.mStatsAggregator.setClientName(ctx.getOpPackageName());
+        session.mStatsAggregator.setExtensionType(config.getExtension());
+
         session.initialize();
 
         return session;
@@ -280,6 +284,9 @@
         mSupportedResultKeys = resultKeys;
         mCaptureResultsSupported = !resultKeys.isEmpty();
         mInterfaceLock = cameraDevice.mInterfaceLock;
+
+        mStatsAggregator = new ExtensionSessionStatsAggregator(mCameraDevice.getId(),
+                /*isAdvanced=*/false);
     }
 
     private void initializeRepeatingRequestPipeline() throws RemoteException {
@@ -793,11 +800,27 @@
                             new CloseRequestHandler(mRepeatingRequestImageCallback), mHandler);
                 }
 
+                mStatsAggregator.commit(/*isFinal*/true); // Commit stats before closing session
                 mCaptureSession.close();
             }
         }
     }
 
+    /**
+     * Called by {@link CameraDeviceImpl} right before the capture session is closed, and before it
+     * calls {@link #release}
+     *
+     * @hide
+     */
+    public void commitStats() {
+        synchronized (mInterfaceLock) {
+            if (mInitialized) {
+                // Only commit stats if a capture session was initialized
+                mStatsAggregator.commit(/*isFinal*/true);
+            }
+        }
+    }
+
     private void setInitialCaptureRequest(List<CaptureStageImpl> captureStageList,
                                           InitialRequestHandler requestHandler)
             throws CameraAccessException {
@@ -828,7 +851,7 @@
 
         synchronized (mInterfaceLock) {
             mInternalRepeatingRequestEnabled = false;
-            mHandlerThread.quitSafely();
+            mHandlerThread.quit();
 
             try {
                 mPreviewExtender.onDeInit();
@@ -955,6 +978,8 @@
         public void onConfigured(@NonNull CameraCaptureSession session) {
             synchronized (mInterfaceLock) {
                 mCaptureSession = session;
+                // Commit basic stats as soon as the capture session is created
+                mStatsAggregator.commit(/*isFinal*/false);
                 try {
                     finishPipelineInitialization();
                     CameraExtensionCharacteristics.initializeSession(mInitializeHandler);
@@ -1368,88 +1393,98 @@
         @Override
         public void onImageAvailable(ImageReader reader) {
             Image img;
-            try {
-                img = reader.acquireNextImage();
-            } catch (IllegalStateException e) {
-                Log.e(TAG, "Failed to acquire image, too many images pending!");
-                mOutOfBuffers = true;
-                return;
-            }
-            if (img == null) {
-                Log.e(TAG, "Invalid image!");
-                return;
-            }
-
-            Long timestamp = img.getTimestamp();
-            if (mImageListenerMap.containsKey(timestamp)) {
-                Pair<Image, OnImageAvailableListener> entry = mImageListenerMap.remove(timestamp);
-                if (entry.second != null) {
-                    entry.second.onImageAvailable(reader, img);
-                } else {
-                    Log.w(TAG, "Invalid image listener, dropping frame!");
-                    img.close();
+            synchronized (mInterfaceLock) {
+                try {
+                    img = reader.acquireNextImage();
+                } catch (IllegalStateException e) {
+                    Log.e(TAG, "Failed to acquire image, too many images pending!");
+                    mOutOfBuffers = true;
+                    return;
                 }
-            } else {
-                mImageListenerMap.put(img.getTimestamp(), new Pair<>(img, null));
-            }
+                if (img == null) {
+                    Log.e(TAG, "Invalid image!");
+                    return;
+                }
 
-            notifyDroppedImages(timestamp);
+                Long timestamp = img.getTimestamp();
+                if (mImageListenerMap.containsKey(timestamp)) {
+                    Pair<Image, OnImageAvailableListener> entry = mImageListenerMap.remove(
+                            timestamp);
+                    if (entry.second != null) {
+                        entry.second.onImageAvailable(reader, img);
+                    } else {
+                        Log.w(TAG, "Invalid image listener, dropping frame!");
+                        img.close();
+                    }
+                } else {
+                    mImageListenerMap.put(timestamp, new Pair<>(img, null));
+                }
+
+                notifyDroppedImages(timestamp);
+            }
         }
 
         private void notifyDroppedImages(long timestamp) {
-            Set<Long> timestamps = mImageListenerMap.keySet();
-            ArrayList<Long> removedTs = new ArrayList<>();
-            for (long ts : timestamps) {
-                if (ts < timestamp) {
-                    Log.e(TAG, "Dropped image with ts: " + ts);
-                    Pair<Image, OnImageAvailableListener> entry = mImageListenerMap.get(ts);
-                    if (entry.second != null) {
-                        entry.second.onImageDropped(ts);
+            synchronized (mInterfaceLock) {
+                Set<Long> timestamps = mImageListenerMap.keySet();
+                ArrayList<Long> removedTs = new ArrayList<>();
+                for (long ts : timestamps) {
+                    if (ts < timestamp) {
+                        Log.e(TAG, "Dropped image with ts: " + ts);
+                        Pair<Image, OnImageAvailableListener> entry = mImageListenerMap.get(ts);
+                        if (entry.second != null) {
+                            entry.second.onImageDropped(ts);
+                        }
+                        if (entry.first != null) {
+                            entry.first.close();
+                        }
+                        removedTs.add(ts);
                     }
-                    if (entry.first != null) {
-                        entry.first.close();
-                    }
-                    removedTs.add(ts);
                 }
-            }
-            for (long ts : removedTs) {
-                mImageListenerMap.remove(ts);
+                for (long ts : removedTs) {
+                    mImageListenerMap.remove(ts);
+                }
             }
         }
 
         public void registerListener(Long timestamp, OnImageAvailableListener listener) {
-            if (mImageListenerMap.containsKey(timestamp)) {
-                Pair<Image, OnImageAvailableListener> entry = mImageListenerMap.remove(timestamp);
-                if (entry.first != null) {
-                    listener.onImageAvailable(mImageReader, entry.first);
-                    if (mOutOfBuffers) {
-                        mOutOfBuffers = false;
-                        Log.w(TAG,"Out of buffers, retry!");
-                        onImageAvailable(mImageReader);
+            synchronized (mInterfaceLock) {
+                if (mImageListenerMap.containsKey(timestamp)) {
+                    Pair<Image, OnImageAvailableListener> entry = mImageListenerMap.remove(
+                            timestamp);
+                    if (entry.first != null) {
+                        listener.onImageAvailable(mImageReader, entry.first);
+                        if (mOutOfBuffers) {
+                            mOutOfBuffers = false;
+                            Log.w(TAG,"Out of buffers, retry!");
+                            onImageAvailable(mImageReader);
+                        }
+                    } else {
+                        Log.w(TAG, "No valid image for listener with ts: " +
+                                timestamp.longValue());
                     }
                 } else {
-                    Log.w(TAG, "No valid image for listener with ts: " +
-                            timestamp.longValue());
+                    mImageListenerMap.put(timestamp, new Pair<>(null, listener));
                 }
-            } else {
-                mImageListenerMap.put(timestamp, new Pair<>(null, listener));
             }
         }
 
         @Override
         public void close() {
-            for (Pair<Image, OnImageAvailableListener> entry : mImageListenerMap.values()) {
-                if (entry.first != null) {
-                    entry.first.close();
+            synchronized (mInterfaceLock) {
+                for (Pair<Image, OnImageAvailableListener> entry : mImageListenerMap.values()) {
+                    if (entry.first != null) {
+                        entry.first.close();
+                    }
                 }
-            }
-            for (long timestamp : mImageListenerMap.keySet()) {
-                Pair<Image, OnImageAvailableListener> entry = mImageListenerMap.get(timestamp);
-                if (entry.second != null) {
-                    entry.second.onImageDropped(timestamp);
+                for (long timestamp : mImageListenerMap.keySet()) {
+                    Pair<Image, OnImageAvailableListener> entry = mImageListenerMap.get(timestamp);
+                    if (entry.second != null) {
+                        entry.second.onImageDropped(timestamp);
+                    }
                 }
+                mImageListenerMap.clear();
             }
-            mImageListenerMap.clear();
         }
     }
 
diff --git a/core/java/android/hardware/camera2/utils/ExtensionSessionStatsAggregator.java b/core/java/android/hardware/camera2/utils/ExtensionSessionStatsAggregator.java
new file mode 100644
index 0000000..8cd5e83
--- /dev/null
+++ b/core/java/android/hardware/camera2/utils/ExtensionSessionStatsAggregator.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.camera2.utils;
+
+import android.annotation.NonNull;
+import android.hardware.CameraExtensionSessionStats;
+import android.hardware.camera2.CameraManager;
+import android.util.Log;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Utility class to aggregate metrics specific to Camera Extensions and pass them to
+ * {@link CameraManager}. {@link android.hardware.camera2.CameraExtensionSession} should call
+ * {@link #commit} before closing the session.
+ *
+ * @hide
+ */
+public class ExtensionSessionStatsAggregator {
+    private static final boolean DEBUG = false;
+    private static final String TAG = ExtensionSessionStatsAggregator.class.getSimpleName();
+
+    private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
+
+    private final Object mLock = new Object(); // synchronizes access to all fields of the class
+    private boolean mIsDone = false; // marks the aggregator as "done".
+                                     // Mutations and commits become no-op if this is true.
+    private final CameraExtensionSessionStats mStats;
+
+    public ExtensionSessionStatsAggregator(@NonNull String cameraId, boolean isAdvanced) {
+        if (DEBUG) {
+            Log.v(TAG, "Creating new Extension Session Stats Aggregator");
+        }
+        mStats = new CameraExtensionSessionStats();
+        mStats.key = "";
+        mStats.cameraId = cameraId;
+        mStats.isAdvanced = isAdvanced;
+    }
+
+    /**
+     * Set client package name
+     *
+     * @param clientName package name of the client that these stats are associated with.
+     */
+    public void setClientName(@NonNull String clientName) {
+        synchronized (mLock) {
+            if (mIsDone) {
+                return;
+            }
+            if (DEBUG) {
+                Log.v(TAG, "Setting clientName: " + clientName);
+            }
+            mStats.clientName = clientName;
+        }
+    }
+
+    /**
+     * Set extension type.
+     *
+     * @param extensionType Type of extension. Must match one of
+     *                      {@code CameraExtensionCharacteristics#EXTENSION_*}
+     */
+    public void setExtensionType(int extensionType) {
+        synchronized (mLock) {
+            if (mIsDone) {
+                return;
+            }
+            if (DEBUG) {
+                Log.v(TAG, "Setting type: " + extensionType);
+            }
+            mStats.type = extensionType;
+        }
+    }
+
+    /**
+     * Asynchronously commits the stats to CameraManager on a background thread.
+     *
+     * @param isFinal marks the stats as final and prevents any further commits or changes. This
+     *                should be set to true when the stats are considered final for logging,
+     *                for example right before the capture session is about to close
+     */
+    public void commit(boolean isFinal) {
+        // Call binder on a background thread to reduce latencies from metrics logging.
+        mExecutor.execute(() -> {
+            synchronized (mLock) {
+                if (mIsDone) {
+                    return;
+                }
+                mIsDone = isFinal;
+                if (DEBUG) {
+                    Log.v(TAG, "Committing: " + prettyPrintStats(mStats));
+                }
+                mStats.key = CameraManager.reportExtensionSessionStats(mStats);
+            }
+        });
+    }
+
+    private static String prettyPrintStats(@NonNull CameraExtensionSessionStats stats) {
+        return CameraExtensionSessionStats.class.getSimpleName() + ":\n"
+                + "  key: '" + stats.key + "'\n"
+                + "  cameraId: '" + stats.cameraId + "'\n"
+                + "  clientName: '" + stats.clientName + "'\n"
+                + "  type: '" + stats.type + "'\n"
+                + "  isAdvanced: '" + stats.isAdvanced + "'\n";
+    }
+}
diff --git a/core/java/android/hardware/devicestate/IDeviceStateManager.aidl b/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
index 0993160..3e72d81 100644
--- a/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
+++ b/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
@@ -21,7 +21,14 @@
 
 /** @hide */
 interface IDeviceStateManager {
-    /** Returns the current device state info. */
+    /**
+     * Returns the current device state info. This {@link DeviceStateInfo} object will always
+     * include the list of supported states. If there has been no base state or committed state
+     * provided yet to the system server, this {@link DeviceStateInfo} object will include
+     * {@link DeviceStateManager#INVALID_DEVICE_STATE} for each respectively.
+     *
+     * This method should not be used to notify callback clients.
+     */
     DeviceStateInfo getDeviceStateInfo();
 
     /**
diff --git a/core/java/android/hardware/display/BrightnessChangeEvent.java b/core/java/android/hardware/display/BrightnessChangeEvent.java
index 6b7d8c3..7ae88b8 100644
--- a/core/java/android/hardware/display/BrightnessChangeEvent.java
+++ b/core/java/android/hardware/display/BrightnessChangeEvent.java
@@ -22,6 +22,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.Arrays;
 import java.util.Objects;
 
 /**
@@ -233,6 +234,31 @@
         dest.writeLong(colorSampleDuration);
     }
 
+    @Override
+    public String toString() {
+        return "BrightnessChangeEvent{"
+                + "brightness: " + brightness
+                + ", timeStamp: " + timeStamp
+                + ", packageName: " + packageName
+                + ", userId: " + userId
+                + ", uniqueDisplayId: " + uniqueDisplayId
+                + ", luxValues: " + Arrays.toString(luxValues)
+                + ", luxTimestamps: " + Arrays.toString(luxTimestamps)
+                + ", batteryLevel: " + batteryLevel
+                + ", powerBrightnessFactor: " + powerBrightnessFactor
+                + ", nightMode: " + nightMode
+                + ", colorTemperature: " + colorTemperature
+                + ", reduceBrightColors: " + reduceBrightColors
+                + ", reduceBrightColorsStrength: " + reduceBrightColorsStrength
+                + ", reduceBrightColorsOffset: " + reduceBrightColorsOffset
+                + ", lastBrightness: " + lastBrightness
+                + ", isDefaultBrightnessConfig: " + isDefaultBrightnessConfig
+                + ", isUserSetBrightness: " + isUserSetBrightness
+                + ", colorValueBuckets: " + Arrays.toString(colorValueBuckets)
+                + ", colorSampleDuration: " + colorSampleDuration
+                + "}";
+    }
+
     /** @hide */
     public static class Builder {
         private float mBrightness;
diff --git a/core/java/android/inputmethodservice/NavigationBarController.java b/core/java/android/inputmethodservice/NavigationBarController.java
index 6910501..78388ef 100644
--- a/core/java/android/inputmethodservice/NavigationBarController.java
+++ b/core/java/android/inputmethodservice/NavigationBarController.java
@@ -246,8 +246,7 @@
         @Override
         public void updateTouchableInsets(@NonNull InputMethodService.Insets originalInsets,
                 @NonNull ViewTreeObserver.InternalInsetsInfo dest) {
-            if (!mImeDrawsImeNavBar || mNavigationBarFrame == null
-                    || mService.isExtractViewShown()) {
+            if (!mImeDrawsImeNavBar || mNavigationBarFrame == null) {
                 return;
             }
 
@@ -255,53 +254,58 @@
             if (systemInsets != null) {
                 final Window window = mService.mWindow.getWindow();
                 final View decor = window.getDecorView();
-                Region touchableRegion = null;
-                final View inputFrame = mService.mInputFrame;
-                switch (originalInsets.touchableInsets) {
-                    case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
-                        if (inputFrame.getVisibility() == View.VISIBLE) {
-                            inputFrame.getLocationInWindow(mTempPos);
-                            mTempRect.set(mTempPos[0], mTempPos[1],
-                                    mTempPos[0] + inputFrame.getWidth(),
-                                    mTempPos[1] + inputFrame.getHeight());
-                            touchableRegion = new Region(mTempRect);
-                        }
-                        break;
-                    case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:
-                        if (inputFrame.getVisibility() == View.VISIBLE) {
-                            inputFrame.getLocationInWindow(mTempPos);
-                            mTempRect.set(mTempPos[0], originalInsets.contentTopInsets,
-                                    mTempPos[0] + inputFrame.getWidth() ,
-                                    mTempPos[1] + inputFrame.getHeight());
-                            touchableRegion = new Region(mTempRect);
-                        }
-                        break;
-                    case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:
-                        if (inputFrame.getVisibility() == View.VISIBLE) {
-                            inputFrame.getLocationInWindow(mTempPos);
-                            mTempRect.set(mTempPos[0], originalInsets.visibleTopInsets,
-                                    mTempPos[0] + inputFrame.getWidth(),
-                                    mTempPos[1] + inputFrame.getHeight());
-                            touchableRegion = new Region(mTempRect);
-                        }
-                        break;
-                    case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION:
-                        touchableRegion = new Region();
-                        touchableRegion.set(originalInsets.touchableRegion);
-                        break;
-                }
-                // Hereafter "mTempRect" means a navigation bar rect.
-                mTempRect.set(decor.getLeft(), decor.getBottom() - systemInsets.bottom,
-                        decor.getRight(), decor.getBottom());
-                if (touchableRegion == null) {
-                    touchableRegion = new Region(mTempRect);
-                } else {
-                    touchableRegion.union(mTempRect);
-                }
 
-                dest.touchableRegion.set(touchableRegion);
-                dest.setTouchableInsets(
-                        ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+                // If the extract view is shown, everything is touchable, so no need to update
+                // touchable insets, but we still update normal insets below.
+                if (!mService.isExtractViewShown()) {
+                    Region touchableRegion = null;
+                    final View inputFrame = mService.mInputFrame;
+                    switch (originalInsets.touchableInsets) {
+                        case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
+                            if (inputFrame.getVisibility() == View.VISIBLE) {
+                                inputFrame.getLocationInWindow(mTempPos);
+                                mTempRect.set(mTempPos[0], mTempPos[1],
+                                        mTempPos[0] + inputFrame.getWidth(),
+                                        mTempPos[1] + inputFrame.getHeight());
+                                touchableRegion = new Region(mTempRect);
+                            }
+                            break;
+                        case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:
+                            if (inputFrame.getVisibility() == View.VISIBLE) {
+                                inputFrame.getLocationInWindow(mTempPos);
+                                mTempRect.set(mTempPos[0], originalInsets.contentTopInsets,
+                                        mTempPos[0] + inputFrame.getWidth(),
+                                        mTempPos[1] + inputFrame.getHeight());
+                                touchableRegion = new Region(mTempRect);
+                            }
+                            break;
+                        case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:
+                            if (inputFrame.getVisibility() == View.VISIBLE) {
+                                inputFrame.getLocationInWindow(mTempPos);
+                                mTempRect.set(mTempPos[0], originalInsets.visibleTopInsets,
+                                        mTempPos[0] + inputFrame.getWidth(),
+                                        mTempPos[1] + inputFrame.getHeight());
+                                touchableRegion = new Region(mTempRect);
+                            }
+                            break;
+                        case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION:
+                            touchableRegion = new Region();
+                            touchableRegion.set(originalInsets.touchableRegion);
+                            break;
+                    }
+                    // Hereafter "mTempRect" means a navigation bar rect.
+                    mTempRect.set(decor.getLeft(), decor.getBottom() - systemInsets.bottom,
+                            decor.getRight(), decor.getBottom());
+                    if (touchableRegion == null) {
+                        touchableRegion = new Region(mTempRect);
+                    } else {
+                        touchableRegion.union(mTempRect);
+                    }
+
+                    dest.touchableRegion.set(touchableRegion);
+                    dest.setTouchableInsets(
+                            ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+                }
 
                 // TODO(b/215443343): See if we can use View#OnLayoutChangeListener().
                 // TODO(b/215443343): See if we can replace DecorView#mNavigationColorViewState.view
diff --git a/core/java/android/os/BatteryStatsManager.java b/core/java/android/os/BatteryStatsManager.java
index 071bdea..955fad3 100644
--- a/core/java/android/os/BatteryStatsManager.java
+++ b/core/java/android/os/BatteryStatsManager.java
@@ -520,14 +520,10 @@
      * @param uid calling package uid
      * @param reason why Bluetooth has been turned on
      * @param packageName package responsible for this change
+     * @Deprecated Bluetooth self report its state and no longer call this
      */
     @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
     public void reportBluetoothOn(int uid, int reason, @NonNull String packageName) {
-        try {
-            mBatteryStats.noteBluetoothOn(uid, reason, packageName);
-        } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
-        }
     }
 
     /**
@@ -536,14 +532,10 @@
      * @param uid calling package uid
      * @param reason why Bluetooth has been turned on
      * @param packageName package responsible for this change
+     * @Deprecated Bluetooth self report its state and no longer call this
      */
     @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
     public void reportBluetoothOff(int uid, int reason, @NonNull String packageName) {
-        try {
-            mBatteryStats.noteBluetoothOff(uid, reason, packageName);
-        } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
-        }
     }
 
     /**
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 8606687..7d68b44 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -250,6 +250,10 @@
      * use {@link android.accounts.AccountManager} APIs to add or remove accounts when account
      * management is disallowed.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_ACCOUNT_MANAGEMENT}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -267,6 +271,9 @@
      * primary user or by a profile owner of an organization-owned managed profile on the parent
      * profile, it disallows the primary user from changing Wi-Fi access points.
      *
+     * <p>Holders of the permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_WIFI}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -285,6 +292,9 @@
      * When it is set by any of these owners, it applies globally - i.e., it disables airplane mode
      * from changing Wi-Fi state.
      *
+     * <p>Holders of the permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_WIFI}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -306,6 +316,9 @@
      * When it is set by any of these owners, it prevents all users from using
      * Wi-Fi tethering. Other forms of tethering are not affected.
      *
+     * <p>Holders of the permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_WIFI}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * This user restriction disables only Wi-Fi tethering.
      * Use {@link #DISALLOW_CONFIG_TETHERING} to limit all forms of tethering.
      * When {@link #DISALLOW_CONFIG_TETHERING} is set, this user restriction becomes obsolete.
@@ -346,6 +359,9 @@
      * sharing Wi-Fi for networks configured by these owners.
      * Other networks not configured by these owners are not affected.
      *
+     * <p>Holders of the permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_WIFI}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -365,6 +381,9 @@
      * When it is set by any of these owners, it prevents all users from using
      * Wi-Fi Direct.
      *
+     * <p>Holders of the permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_WIFI}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -384,6 +403,9 @@
      * a new Wi-Fi configuration. This does not limit the owner and carrier's ability
      * to add a new configuration.
      *
+     * <p>Holders of the permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_WIFI}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -398,6 +420,9 @@
      * Specifies if a user is disallowed from changing the device
      * language. The default value is <code>false</code>.
      *
+     * <p>Holders of the permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCALE}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -411,6 +436,10 @@
      * prevents device owners and profile owners installing apps. The default value is
      * {@code false}.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_APPS_CONTROL}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -423,6 +452,10 @@
      * Specifies if a user is disallowed from uninstalling applications.
      * The default value is <code>false</code>.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_APPS_CONTROL}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -442,6 +475,10 @@
      * managed profile on the parent profile, it prevents the primary user from turning on
      * location sharing.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCATION}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -460,6 +497,10 @@
      * When it is set by any of these owners, it applies globally - i.e., it disables airplane mode
      * on the entire device.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_AIRPLANE_MODE}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -476,6 +517,10 @@
      *
      * <p>The default value is <code>false</code>.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_DISPLAY}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>This user restriction has no effect on managed profiles.
      * <p>Key for user restrictions.
      * <p>Type: Boolean
@@ -490,6 +535,10 @@
      *
      * <p>The default value is <code>false</code>.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_DISPLAY}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>This user restriction has no effect on managed profiles.
      * <p>Key for user restrictions.
      * <p>Type: Boolean
@@ -504,6 +553,10 @@
      *
      * <p>The default value is <code>false</code>.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_DISPLAY}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>This user restriction has no effect on managed profiles.
      * <p>Key for user restrictions.
      * <p>Type: Boolean
@@ -519,6 +572,10 @@
      * Unknown sources exclude adb and special apps such as trusted app stores.
      * The default value is <code>false</code>.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_INSTALL_UNKNOWN_SOURCES}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -536,6 +593,10 @@
      * This restriction can be enabled by the profile owner, in which case all accounts and
      * profiles will be affected.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_INSTALL_UNKNOWN_SOURCES}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -559,6 +620,10 @@
      * primary user or by a profile owner of an organization-owned managed profile on the parent
      * profile, it disallows the primary user from configuring bluetooth.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_BLUETOOTH}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -581,6 +646,10 @@
      * profile, it disables the primary user from using bluetooth and configuring bluetooth
      * in Settings.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_BLUETOOTH}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -599,6 +668,10 @@
      * profile owner of an organization-owned managed profile on the parent profile, it disables
      * the primary user from any outgoing bluetooth sharing.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_BLUETOOTH}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Default is <code>true</code> for managed profiles and false otherwise.
      *
      * <p>When a device upgrades to {@link android.os.Build.VERSION_CODES#O}, the system sets it
@@ -626,6 +699,10 @@
      * user on the device is able to use file transfer over USB because the UI for file transfer
      * is always associated with the primary user.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_USB_FILE_TRANSFER}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -640,6 +717,10 @@
      * Specifies if a user is disallowed from configuring user
      * credentials. The default value is <code>false</code>.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -654,6 +735,10 @@
      * This restriction has no effect on managed profiles.
      * The default value is <code>false</code>.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_USERS}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -692,6 +777,10 @@
      * that user only, including starting activities, making service calls, accessing content
      * providers, sending broadcasts, installing/uninstalling packages, clearing user data, etc.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_DEBUGGING_FEATURES}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -712,6 +801,10 @@
      * <p>From Android 12 ({@linkplain android.os.Build.VERSION_CODES#S API level 31}) enforcing
      * this restriction clears currently active VPN if it was configured by the user.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_VPN}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -729,6 +822,10 @@
      * managed profile on the parent profile, it disallows the primary user from turning location
      * on or off.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCATION}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>This user restriction is different from {@link #DISALLOW_SHARE_LOCATION},
@@ -755,6 +852,10 @@
      * from configuring date, time and timezone and disables all configuring of date, time and
      * timezone in Settings.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_TIME}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -776,6 +877,10 @@
      * the parent profile, it disables the primary user from using Tethering and hotspots and
      * disables all configuring of Tethering and hotspots in Settings.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_MOBILE_NETWORK}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>In Android 9.0 or higher, if tethering is enabled when this restriction is set,
@@ -796,6 +901,10 @@
      * <p>This restriction has no effect on secondary users and managed profiles since only the
      * primary user can reset the network settings of the device.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_MOBILE_NETWORK}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -811,6 +920,10 @@
      * <p>This restriction has no effect on non-admin users since they cannot factory reset the
      * device.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_FACTORY_RESET}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -827,6 +940,10 @@
      * <p> When the device is an organization-owned device provisioned with a managed profile,
      * this restriction will be set as a base restriction which cannot be removed by any admin.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_USERS}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -858,6 +975,10 @@
      * <p>The default value for an unmanaged user is <code>false</code>.
      * For users with a device owner set, the default is <code>true</code>.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_PROFILES}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -876,6 +997,10 @@
      * the system enforces app verification across all users on the device. Running in earlier
      * Android versions, this restriction affects only the profile that sets it.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_INSTALL_UNKNOWN_SOURCES}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -893,6 +1018,10 @@
      * on the primary user or by a profile owner of an organization-owned managed profile on
      * the parent profile, it disables the primary user from configuring cell broadcasts.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_MOBILE_NETWORK}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>This restriction has no effect on secondary users and managed profiles since only the
@@ -915,6 +1044,10 @@
      * on the primary user or by a profile owner of an organization-owned managed profile on
      * the parent profile, it disables the primary user from configuring mobile networks.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_MOBILE_NETWORK}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>This restriction has no effect on secondary users and managed profiles since only the
@@ -949,6 +1082,10 @@
      * {@link DevicePolicyManager#addPersistentPreferredActivity(ComponentName, IntentFilter, ComponentName)}
      * to add a default intent handler for a given intent filter.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_APPS_CONTROL}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -966,6 +1103,10 @@
      * on the primary user or by a profile owner of an organization-owned managed profile on
      * the parent profile, it disables the primary user from mounting physical external media.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_PHYSICAL_MEDIA}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -986,6 +1127,10 @@
      * organization-owned managed profile on the parent profile, it will disallow the primary user
      * from adjusting the microphone volume.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_MICROPHONE}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -1004,6 +1149,10 @@
      * <p>When the restriction is set by profile owners, then it only applies to relevant
      * profiles.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_AUDIO_OUTPUT}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>This restriction has no effect on managed profiles.
      * <p>Key for user restrictions.
      * <p>Type: Boolean
@@ -1022,6 +1171,10 @@
      * primary user or by a profile owner of an organization-owned managed profile on the parent
      * profile, it disallows the primary user from making outgoing phone calls.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_CALLS}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -1041,6 +1194,10 @@
      * on the primary user or by a profile owner of an organization-owned managed profile on
      * the parent profile, it disables the primary user from sending or receiving SMS messages.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_SMS}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -1056,6 +1213,10 @@
      * device owner may wish to prevent the user from experiencing amusement or
      * joy while using the device. The default value is <code>false</code>.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_FUN}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1073,6 +1234,10 @@
      * <p>This can only be set by device owners and profile owners on the primary user.
      * The default value is <code>false</code>.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_WINDOWS}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1091,6 +1256,10 @@
      * the profile owner of the primary user or a secondary user, the restriction affects only the
      * calling user. This user restriction has no effect on managed profiles.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_SYSTEM_DIALOGS}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1108,6 +1277,10 @@
      * optical character recognition (OCR), we strongly recommend combining this user restriction
      * with {@link DevicePolicyManager#setScreenCaptureDisabled(ComponentName, boolean)}.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_PROFILE_INTERACTION}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1120,6 +1293,10 @@
      * Specifies if the user is not allowed to use NFC to beam out data from apps.
      * The default value is <code>false</code>.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_NEARBY_COMMUNICATION}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1145,6 +1322,10 @@
      * are able to set wallpaper regardless of this restriction.
      * The default value is <code>false</code>.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_WALLPAPER}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1163,6 +1344,10 @@
      * the parent profile, it disables the primary user from rebooting the device into safe
      * boot mode.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_SAFE_BOOT}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -1191,6 +1376,10 @@
      *
      * <p>This restriction can be set by device owners and profile owners.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_RUN_IN_BACKGROUND}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
      * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
      * @see #getUserRestrictions()
@@ -1208,6 +1397,10 @@
      * profile owner of an organization-owned managed profile on the parent profile, it disables
      * the primary user from using camera.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_CAMERA}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1220,6 +1413,10 @@
     /**
      * Specifies if a user is not allowed to unmute the device's global volume.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_AUDIO_OUTPUT}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * @see DevicePolicyManager#setMasterVolumeMuted(ComponentName, boolean)
      * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
      * @see #getUserRestrictions()
@@ -1236,6 +1433,10 @@
      * on the primary user or by a profile owner of an organization-owned managed profile on
      * the parent profile, it disables the primary user from using cellular data when roaming.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_MOBILE_NETWORK}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1249,6 +1450,10 @@
      * can set this restriction. When it is set by device owner, only the target user will be
      * affected. The default value is <code>false</code>.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_USERS}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1285,6 +1490,11 @@
      *
      * <p>Can be set by profile owners. It only has effect on managed profiles when set by managed
      * profile owner. Has no effect on non-managed profiles or users.
+     *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1302,7 +1512,12 @@
      * {@link android.content.Intent#ACTION_VIEW},
      * category {@link android.content.Intent#CATEGORY_BROWSABLE}, scheme http or https, and which
      * define a host can handle intents from the managed profile.
-     * The default value is <code>false</code>.
+     *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_PROFILES}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
+     * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
@@ -1319,6 +1534,10 @@
      * <p>Device owner and profile owner can set this restriction. When it is set by device owner,
      * only the target user will be affected.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_AUTOFILL}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1336,6 +1555,10 @@
      * managed profile on the parent profile, it disables the primary user's screen from being
      * captured for artificial intelligence purposes.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_SCREEN_CONTENT}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1353,6 +1576,10 @@
      * managed profile on the parent profile, it disables the primary user from receiving content
      * suggestions for selections based on the contents of their screen.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_SCREEN_CONTENT}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1369,6 +1596,10 @@
      * {@link DevicePolicyManager#switchUser(ComponentName, UserHandle)} when this restriction is
      * set.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_USERS}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1391,7 +1622,12 @@
      * This restriction is only meaningful when set by profile owner. When it is set by device
      * owner, it does not have any effect.
      * <p>
-     * The default value is <code>false</code>.
+     *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_PROFILE_INTERACTION}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
+     * <p>The default value is <code>false</code>.
      *
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
      * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
@@ -1404,6 +1640,10 @@
      *
      * This restriction can be set by device or profile owner.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_PRINTING}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * The default value is {@code false}.
      *
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1419,6 +1659,10 @@
      * organization-owned managed profile on the parent profile. When it is set by either of these
      * owners, it applies globally.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_RESTRICT_PRIVATE_DNS}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -1525,6 +1769,10 @@
      * In all cases, the setting applies globally on the device and will prevent the device from
      * scanning for or connecting to 2g networks, except in the case of an emergency.
      *
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_MOBILE_NETWORK}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
+     *
      * <p>The default value is <code>false</code>.
      *
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
@@ -1537,15 +1785,19 @@
      * This user restriction specifies if Ultra-wideband is disallowed on the device. If
      * Ultra-wideband is disallowed it cannot be turned on via Settings.
      *
+     * <p>
+     * Ultra-wideband (UWB) is a radio technology that can use a very low energy level
+     * for short-range, high-bandwidth communications over a large portion of the radio spectrum.
+     *
      * <p>This restriction can only be set by a device owner or a profile owner of an
      * organization-owned managed profile on the parent profile.
      * In both cases, the restriction applies globally on the device and will turn off the
      * ultra-wideband radio if it's currently on and prevent the radio from being turned on in
      * the future.
      *
-     * <p>
-     * Ultra-wideband (UWB) is a radio technology that can use a very low energy level
-     * for short-range, high-bandwidth communications over a large portion of the radio spectrum.
+     * <p>Holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_NEARBY_COMMUNICATION}
+     * can set this restriction using the DevicePolicyManager APIs mentioned below.
      *
      * <p>Default is <code>false</code>.
      *
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index 6f2a915..3f40139 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -37,7 +37,6 @@
 import android.os.HandlerThread;
 import android.os.Message;
 import android.preference.VolumePreference.VolumeStore;
-import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.provider.Settings.Global;
 import android.provider.Settings.System;
@@ -47,7 +46,6 @@
 import android.widget.SeekBar.OnSeekBarChangeListener;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.os.SomeArgs;
 
 import java.util.concurrent.TimeUnit;
@@ -295,14 +293,8 @@
         if (zenMuted) {
             mSeekBar.setProgress(mLastAudibleStreamVolume, true);
         } else if (mNotificationOrRing && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
-            /**
-             * the first variable above is preserved and the conditions below are made explicit
-             * so that when user attempts to slide the notification seekbar out of vibrate the
-             * seekbar doesn't wrongly snap back to 0 when the streams aren't aliased
-             */
-            if (!DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
-                    SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, false)
-                    || mStreamType == AudioManager.STREAM_RING
+            // For ringer-mode affected streams, show volume as zero when ringermode is vibrate
+            if (mStreamType == AudioManager.STREAM_RING
                     || (mStreamType == AudioManager.STREAM_NOTIFICATION && mMuted)) {
                 mSeekBar.setProgress(0, true);
             }
@@ -397,9 +389,7 @@
         // set the time of stop volume
         if ((mStreamType == AudioManager.STREAM_VOICE_CALL
                 || mStreamType == AudioManager.STREAM_RING
-                || (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, false)
-                && mStreamType == AudioManager.STREAM_NOTIFICATION)
+                || mStreamType == AudioManager.STREAM_NOTIFICATION
                 || mStreamType == AudioManager.STREAM_ALARM)) {
             sStopVolumeTime = java.lang.System.currentTimeMillis();
         }
@@ -686,10 +676,7 @@
         }
 
         private void updateVolumeSlider(int streamType, int streamValue) {
-            final boolean streamMatch =  !DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
-                    SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, false)
-                    && mNotificationOrRing ? isNotificationOrRing(streamType) :
-                    streamType == mStreamType;
+            final boolean streamMatch = (streamType == mStreamType);
             if (mSeekBar != null && streamMatch && streamValue != -1) {
                 final boolean muted = mAudioManager.isStreamMute(mStreamType)
                         || streamValue == 0;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a42af1a..d695c0c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3036,7 +3036,9 @@
 
         public void destroy() {
             try {
-                if (!mArray.isClosed()) {
+                // If this process is the system server process, mArray is the same object as
+                // the memory int array kept inside SettingsProvider, so skipping the close()
+                if (!Settings.isInSystemServer() && !mArray.isClosed()) {
                     mArray.close();
                 }
             } catch (IOException e) {
@@ -12446,6 +12448,17 @@
                 "bypass_device_policy_management_role_qualifications";
 
         /**
+         * Whether work profile telephony feature is enabled for non
+         * {@link android.app.role.RoleManager#ROLE_DEVICE_POLICY_MANAGEMENT} holders.
+         * ("0" = false, "1" = true).
+         *
+         * @hide
+         */
+        @Readable
+        public static final String ALLOW_WORK_PROFILE_TELEPHONY_FOR_NON_DPM_ROLE_HOLDERS =
+                "allow_work_profile_telephony_for_non_dpm_role_holders";
+
+        /**
          * Indicates whether mobile data should be allowed while the device is being provisioned.
          * This allows the provisioning process to turn off mobile data before the user
          * has an opportunity to set things up, preventing other processes from burning
@@ -15297,18 +15310,6 @@
         public static final String ANGLE_EGL_FEATURES = "angle_egl_features";
 
         /**
-         * Comma-separated list of package names that ANGLE may have issues with
-         * @hide
-         */
-        public static final String ANGLE_DEFERLIST = "angle_deferlist";
-
-        /**
-         * Integer mode of the logic for applying `angle_deferlist`
-         * @hide
-         */
-        public static final String ANGLE_DEFERLIST_MODE = "angle_deferlist_mode";
-
-        /**
          * Show the "ANGLE In Use" dialog box to the user when ANGLE is the OpenGL driver.
          * The value is a boolean (1 or 0).
          * @hide
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index 5f7486a..d04ff8e 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -123,47 +123,50 @@
      */
     public static final int PICK_REASON_UNKNOWN = 0;
     /**
-     * This dataset is picked because of autofill provider detection was chosen.
+     * This dataset is picked because pcc wasn't enabled.
      * @hide
      */
-    public static final int PICK_REASON_AUTOFILL_PROVIDER_DETECTION = 1;
+    public static final int PICK_REASON_NO_PCC = 1;
+    /**
+     * This dataset is picked because provider gave this dataset.
+     * @hide
+     */
+    public static final int PICK_REASON_PROVIDER_DETECTION_ONLY = 2;
+    /**
+     * This dataset is picked because provider detection was preferred. However, provider also made
+     * this dataset available for PCC detected types, so they could've been picked up by PCC
+     * detection. This however doesn't imply that this dataset would've been chosen for sure. For
+     * eg, if PCC Detection was preferred, and PCC detected other field types, which wasn't
+     * applicable to this dataset, it wouldn't have been shown.
+     * @hide
+     */
+    public static final int PICK_REASON_PROVIDER_DETECTION_PREFERRED_WITH_PCC = 3;
     /**
      * This dataset is picked because of PCC detection was chosen.
      * @hide
      */
-    public static final int PICK_REASON_PCC_DETECTION = 2;
+    public static final int PICK_REASON_PCC_DETECTION_ONLY = 4;
     /**
-     * This dataset is picked because of Framework detection was chosen.
+     * This dataset is picked because of PCC Detection was preferred. However, Provider also gave
+     * this dataset, so if PCC wasn't enabled, this dataset would've been eligible anyway.
      * @hide
      */
-    public static final int PICK_REASON_FRAMEWORK_DETECTION = 3;
-    /**
-     * This dataset is picked because of Autofill Provider being a fallback.
-     * @hide
-     */
-    public static final int PICK_REASON_AUTOFILL_PROVIDER_FALLBACK = 4;
-    /**
-     * This dataset is picked because of PCC detection being a fallback.
-     * @hide
-     */
-    public static final int PICK_REASON_PCC_DETECTION_FALLBACK = 5;
-    /**
-     * This dataset is picked because of Framework detection being a fallback.
-     * @hide
-     */
-    public static final int PICK_REASON_FRAMEWORK_FALLBACK = 6;
+    public static final int PICK_REASON_PCC_DETECTION_PREFERRED_WITH_PROVIDER = 5;
 
+    /**
+     * Reason why the dataset was eligible for autofill.
+     * @hide
+     */
     @IntDef(prefix = { "PICK_REASON_" }, value = {
             PICK_REASON_UNKNOWN,
-            PICK_REASON_AUTOFILL_PROVIDER_DETECTION,
-            PICK_REASON_PCC_DETECTION,
-            PICK_REASON_FRAMEWORK_DETECTION,
-            PICK_REASON_AUTOFILL_PROVIDER_FALLBACK,
-            PICK_REASON_PCC_DETECTION_FALLBACK,
-            PICK_REASON_FRAMEWORK_FALLBACK,
+            PICK_REASON_NO_PCC,
+            PICK_REASON_PROVIDER_DETECTION_ONLY,
+            PICK_REASON_PROVIDER_DETECTION_PREFERRED_WITH_PCC,
+            PICK_REASON_PCC_DETECTION_ONLY,
+            PICK_REASON_PCC_DETECTION_PREFERRED_WITH_PROVIDER,
     })
     @Retention(RetentionPolicy.SOURCE)
-    @interface DatasetEligibleReason{}
+    public @interface DatasetEligibleReason{}
 
     private @DatasetEligibleReason int mEligibleReason;
 
diff --git a/core/java/android/service/notification/ZenModeDiff.java b/core/java/android/service/notification/ZenModeDiff.java
index c7b89eb..a4f129e 100644
--- a/core/java/android/service/notification/ZenModeDiff.java
+++ b/core/java/android/service/notification/ZenModeDiff.java
@@ -205,12 +205,24 @@
         private final ArrayMap<String, RuleDiff> mAutomaticRulesDiff = new ArrayMap<>();
         private RuleDiff mManualRuleDiff;
 
-        // Helpers for string generation
-        private static final String ALLOW_CALLS_FROM_FIELD = "allowCallsFrom";
-        private static final String ALLOW_MESSAGES_FROM_FIELD = "allowMessagesFrom";
-        private static final String ALLOW_CONVERSATIONS_FROM_FIELD = "allowConversationsFrom";
+        // Field name constants
+        public static final String FIELD_USER = "user";
+        public static final String FIELD_ALLOW_ALARMS = "allowAlarms";
+        public static final String FIELD_ALLOW_MEDIA = "allowMedia";
+        public static final String FIELD_ALLOW_SYSTEM = "allowSystem";
+        public static final String FIELD_ALLOW_CALLS = "allowCalls";
+        public static final String FIELD_ALLOW_REMINDERS = "allowReminders";
+        public static final String FIELD_ALLOW_EVENTS = "allowEvents";
+        public static final String FIELD_ALLOW_REPEAT_CALLERS = "allowRepeatCallers";
+        public static final String FIELD_ALLOW_MESSAGES = "allowMessages";
+        public static final String FIELD_ALLOW_CONVERSATIONS = "allowConversations";
+        public static final String FIELD_ALLOW_CALLS_FROM = "allowCallsFrom";
+        public static final String FIELD_ALLOW_MESSAGES_FROM = "allowMessagesFrom";
+        public static final String FIELD_ALLOW_CONVERSATIONS_FROM = "allowConversationsFrom";
+        public static final String FIELD_SUPPRESSED_VISUAL_EFFECTS = "suppressedVisualEffects";
+        public static final String FIELD_ARE_CHANNELS_BYPASSING_DND = "areChannelsBypassingDnd";
         private static final Set<String> PEOPLE_TYPE_FIELDS =
-                Set.of(ALLOW_CALLS_FROM_FIELD, ALLOW_MESSAGES_FROM_FIELD);
+                Set.of(FIELD_ALLOW_CALLS_FROM, FIELD_ALLOW_MESSAGES_FROM);
 
         /**
          * Create a diff that contains diffs between the "from" and "to" ZenModeConfigs.
@@ -232,57 +244,57 @@
 
             // Now we compare all the fields, knowing there's a diff and that neither is null
             if (from.user != to.user) {
-                addField("user", new FieldDiff<>(from.user, to.user));
+                addField(FIELD_USER, new FieldDiff<>(from.user, to.user));
             }
             if (from.allowAlarms != to.allowAlarms) {
-                addField("allowAlarms", new FieldDiff<>(from.allowAlarms, to.allowAlarms));
+                addField(FIELD_ALLOW_ALARMS, new FieldDiff<>(from.allowAlarms, to.allowAlarms));
             }
             if (from.allowMedia != to.allowMedia) {
-                addField("allowMedia", new FieldDiff<>(from.allowMedia, to.allowMedia));
+                addField(FIELD_ALLOW_MEDIA, new FieldDiff<>(from.allowMedia, to.allowMedia));
             }
             if (from.allowSystem != to.allowSystem) {
-                addField("allowSystem", new FieldDiff<>(from.allowSystem, to.allowSystem));
+                addField(FIELD_ALLOW_SYSTEM, new FieldDiff<>(from.allowSystem, to.allowSystem));
             }
             if (from.allowCalls != to.allowCalls) {
-                addField("allowCalls", new FieldDiff<>(from.allowCalls, to.allowCalls));
+                addField(FIELD_ALLOW_CALLS, new FieldDiff<>(from.allowCalls, to.allowCalls));
             }
             if (from.allowReminders != to.allowReminders) {
-                addField("allowReminders",
+                addField(FIELD_ALLOW_REMINDERS,
                         new FieldDiff<>(from.allowReminders, to.allowReminders));
             }
             if (from.allowEvents != to.allowEvents) {
-                addField("allowEvents", new FieldDiff<>(from.allowEvents, to.allowEvents));
+                addField(FIELD_ALLOW_EVENTS, new FieldDiff<>(from.allowEvents, to.allowEvents));
             }
             if (from.allowRepeatCallers != to.allowRepeatCallers) {
-                addField("allowRepeatCallers",
+                addField(FIELD_ALLOW_REPEAT_CALLERS,
                         new FieldDiff<>(from.allowRepeatCallers, to.allowRepeatCallers));
             }
             if (from.allowMessages != to.allowMessages) {
-                addField("allowMessages",
+                addField(FIELD_ALLOW_MESSAGES,
                         new FieldDiff<>(from.allowMessages, to.allowMessages));
             }
             if (from.allowConversations != to.allowConversations) {
-                addField("allowConversations",
+                addField(FIELD_ALLOW_CONVERSATIONS,
                         new FieldDiff<>(from.allowConversations, to.allowConversations));
             }
             if (from.allowCallsFrom != to.allowCallsFrom) {
-                addField("allowCallsFrom",
+                addField(FIELD_ALLOW_CALLS_FROM,
                         new FieldDiff<>(from.allowCallsFrom, to.allowCallsFrom));
             }
             if (from.allowMessagesFrom != to.allowMessagesFrom) {
-                addField("allowMessagesFrom",
+                addField(FIELD_ALLOW_MESSAGES_FROM,
                         new FieldDiff<>(from.allowMessagesFrom, to.allowMessagesFrom));
             }
             if (from.allowConversationsFrom != to.allowConversationsFrom) {
-                addField("allowConversationsFrom",
+                addField(FIELD_ALLOW_CONVERSATIONS_FROM,
                         new FieldDiff<>(from.allowConversationsFrom, to.allowConversationsFrom));
             }
             if (from.suppressedVisualEffects != to.suppressedVisualEffects) {
-                addField("suppressedVisualEffects",
+                addField(FIELD_SUPPRESSED_VISUAL_EFFECTS,
                         new FieldDiff<>(from.suppressedVisualEffects, to.suppressedVisualEffects));
             }
             if (from.areChannelsBypassingDnd != to.areChannelsBypassingDnd) {
-                addField("areChannelsBypassingDnd",
+                addField(FIELD_ARE_CHANNELS_BYPASSING_DND,
                         new FieldDiff<>(from.areChannelsBypassingDnd, to.areChannelsBypassingDnd));
             }
 
@@ -366,7 +378,7 @@
                     sb.append(ZenModeConfig.sourceToString((int) diff.from()));
                     sb.append("->");
                     sb.append(ZenModeConfig.sourceToString((int) diff.to()));
-                } else if (key.equals(ALLOW_CONVERSATIONS_FROM_FIELD)) {
+                } else if (key.equals(FIELD_ALLOW_CONVERSATIONS_FROM)) {
                     sb.append(key);
                     sb.append(":");
                     sb.append(ZenPolicy.conversationTypeToString((int) diff.from()));
@@ -428,6 +440,24 @@
      * Diff class representing a change between two ZenRules.
      */
     public static class RuleDiff extends BaseDiff {
+        public static final String FIELD_ENABLED = "enabled";
+        public static final String FIELD_SNOOZING = "snoozing";
+        public static final String FIELD_NAME = "name";
+        public static final String FIELD_ZEN_MODE = "zenMode";
+        public static final String FIELD_CONDITION_ID = "conditionId";
+        public static final String FIELD_CONDITION = "condition";
+        public static final String FIELD_COMPONENT = "component";
+        public static final String FIELD_CONFIGURATION_ACTIVITY = "configurationActivity";
+        public static final String FIELD_ID = "id";
+        public static final String FIELD_CREATION_TIME = "creationTime";
+        public static final String FIELD_ENABLER = "enabler";
+        public static final String FIELD_ZEN_POLICY = "zenPolicy";
+        public static final String FIELD_MODIFIED = "modified";
+        public static final String FIELD_PKG = "pkg";
+
+        // Special field to track whether this rule became active or inactive
+        FieldDiff<Boolean> mActiveDiff;
+
         /**
          * Create a RuleDiff representing the difference between two ZenRule objects.
          * @param from previous ZenRule
@@ -440,54 +470,64 @@
             if (from == null && to == null) {
                 return;
             }
+
+            // Even if added or removed, there may be a change in whether or not it was active.
+            // This only applies to automatic rules.
+            boolean fromActive = from != null ? from.isAutomaticActive() : false;
+            boolean toActive = to != null ? to.isAutomaticActive() : false;
+            if (fromActive != toActive) {
+                mActiveDiff = new FieldDiff<>(fromActive, toActive);
+            }
+
             // Return if the diff was added or removed
             if (hasExistenceChange()) {
                 return;
             }
 
             if (from.enabled != to.enabled) {
-                addField("enabled", new FieldDiff<>(from.enabled, to.enabled));
+                addField(FIELD_ENABLED, new FieldDiff<>(from.enabled, to.enabled));
             }
             if (from.snoozing != to.snoozing) {
-                addField("snoozing", new FieldDiff<>(from.snoozing, to.snoozing));
+                addField(FIELD_SNOOZING, new FieldDiff<>(from.snoozing, to.snoozing));
             }
             if (!Objects.equals(from.name, to.name)) {
-                addField("name", new FieldDiff<>(from.name, to.name));
+                addField(FIELD_NAME, new FieldDiff<>(from.name, to.name));
             }
             if (from.zenMode != to.zenMode) {
-                addField("zenMode", new FieldDiff<>(from.zenMode, to.zenMode));
+                addField(FIELD_ZEN_MODE, new FieldDiff<>(from.zenMode, to.zenMode));
             }
             if (!Objects.equals(from.conditionId, to.conditionId)) {
-                addField("conditionId", new FieldDiff<>(from.conditionId, to.conditionId));
+                addField(FIELD_CONDITION_ID, new FieldDiff<>(from.conditionId,
+                        to.conditionId));
             }
             if (!Objects.equals(from.condition, to.condition)) {
-                addField("condition", new FieldDiff<>(from.condition, to.condition));
+                addField(FIELD_CONDITION, new FieldDiff<>(from.condition, to.condition));
             }
             if (!Objects.equals(from.component, to.component)) {
-                addField("component", new FieldDiff<>(from.component, to.component));
+                addField(FIELD_COMPONENT, new FieldDiff<>(from.component, to.component));
             }
             if (!Objects.equals(from.configurationActivity, to.configurationActivity)) {
-                addField("configurationActivity", new FieldDiff<>(
+                addField(FIELD_CONFIGURATION_ACTIVITY, new FieldDiff<>(
                         from.configurationActivity, to.configurationActivity));
             }
             if (!Objects.equals(from.id, to.id)) {
-                addField("id", new FieldDiff<>(from.id, to.id));
+                addField(FIELD_ID, new FieldDiff<>(from.id, to.id));
             }
             if (from.creationTime != to.creationTime) {
-                addField("creationTime",
+                addField(FIELD_CREATION_TIME,
                         new FieldDiff<>(from.creationTime, to.creationTime));
             }
             if (!Objects.equals(from.enabler, to.enabler)) {
-                addField("enabler", new FieldDiff<>(from.enabler, to.enabler));
+                addField(FIELD_ENABLER, new FieldDiff<>(from.enabler, to.enabler));
             }
             if (!Objects.equals(from.zenPolicy, to.zenPolicy)) {
-                addField("zenPolicy", new FieldDiff<>(from.zenPolicy, to.zenPolicy));
+                addField(FIELD_ZEN_POLICY, new FieldDiff<>(from.zenPolicy, to.zenPolicy));
             }
             if (from.modified != to.modified) {
-                addField("modified", new FieldDiff<>(from.modified, to.modified));
+                addField(FIELD_MODIFIED, new FieldDiff<>(from.modified, to.modified));
             }
             if (!Objects.equals(from.pkg, to.pkg)) {
-                addField("pkg", new FieldDiff<>(from.pkg, to.pkg));
+                addField(FIELD_PKG, new FieldDiff<>(from.pkg, to.pkg));
             }
         }
 
@@ -536,7 +576,35 @@
                 sb.append(diff);
             }
 
+            if (becameActive()) {
+                if (!first) {
+                    sb.append(", ");
+                }
+                sb.append("(->active)");
+            } else if (becameInactive()) {
+                if (!first) {
+                    sb.append(", ");
+                }
+                sb.append("(->inactive)");
+            }
+
             return sb.append("}").toString();
         }
+
+        /**
+         * Returns whether this diff indicates that this (automatic) rule became active.
+         */
+        public boolean becameActive() {
+            // if the "to" side is true, then it became active
+            return mActiveDiff != null && mActiveDiff.to();
+        }
+
+        /**
+         * Returns whether this diff indicates that this (automatic) rule became inactive.
+         */
+        public boolean becameInactive() {
+            // if the "to" side is false, then it became inactive
+            return mActiveDiff != null && !mActiveDiff.to();
+        }
     }
 }
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 4b761c1..ab9ae0a 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -1066,7 +1066,9 @@
         synchronized (mLock) {
             mActiveDetectors.forEach(detector -> {
                 try {
-                    if (detector != mActiveVisualQueryDetector.getInitializationDelegate()
+                    // Skip destroying VisualQueryDetector if HotwordDetectors are created
+                    if (!(mActiveVisualQueryDetector != null
+                            && detector == mActiveVisualQueryDetector.getInitializationDelegate())
                             || shouldShutDownVisualQueryDetector) {
                         detector.destroy();
                     }
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 230f511..7f0a666 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -2231,7 +2231,7 @@
 
             mDestroyed = true;
 
-            if (mIWallpaperEngine.mDisplayManager != null) {
+            if (mIWallpaperEngine != null && mIWallpaperEngine.mDisplayManager != null) {
                 mIWallpaperEngine.mDisplayManager.unregisterDisplayListener(mDisplayListener);
             }
 
diff --git a/core/java/android/speech/OWNERS b/core/java/android/speech/OWNERS
index 462d8be..162e029 100644
--- a/core/java/android/speech/OWNERS
+++ b/core/java/android/speech/OWNERS
@@ -2,3 +2,4 @@
 eugeniom@google.com
 schfan@google.com
 andreaambu@google.com
+hackz@google.com
\ No newline at end of file
diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java
index dacb25c..bb5dd7f 100644
--- a/core/java/android/speech/SpeechRecognizer.java
+++ b/core/java/android/speech/SpeechRecognizer.java
@@ -812,7 +812,7 @@
             Intent recognizerIntent,
             Executor callbackExecutor,
             RecognitionSupportCallback recognitionSupportCallback) {
-        if (!maybeInitializeManagerService()) {
+        if (!maybeInitializeManagerService() || !checkOpenConnection()) {
             return;
         }
         try {
@@ -831,7 +831,7 @@
             Intent recognizerIntent,
             @Nullable Executor callbackExecutor,
             @Nullable ModelDownloadListener modelDownloadListener) {
-        if (!maybeInitializeManagerService()) {
+        if (!maybeInitializeManagerService() || !checkOpenConnection()) {
             return;
         }
 
diff --git a/core/java/android/view/ContentRecordingSession.java b/core/java/android/view/ContentRecordingSession.java
index fdecb8b..a89f795 100644
--- a/core/java/android/view/ContentRecordingSession.java
+++ b/core/java/android/view/ContentRecordingSession.java
@@ -87,7 +87,7 @@
      *
      * <p>Only set on the server side to sanitize any input from the client process.
      */
-    private boolean mWaitingToRecord = false;
+    private boolean mWaitingForConsent = false;
 
     /**
      * Default instance, with recording the display.
@@ -181,7 +181,7 @@
             @RecordContent int contentToRecord,
             int displayToRecord,
             @Nullable IBinder tokenToRecord,
-            boolean waitingToRecord) {
+            boolean waitingForConsent) {
         this.mVirtualDisplayId = virtualDisplayId;
         this.mContentToRecord = contentToRecord;
 
@@ -195,7 +195,7 @@
 
         this.mDisplayToRecord = displayToRecord;
         this.mTokenToRecord = tokenToRecord;
-        this.mWaitingToRecord = waitingToRecord;
+        this.mWaitingForConsent = waitingForConsent;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -246,8 +246,8 @@
      * <p>Only set on the server side to sanitize any input from the client process.
      */
     @DataClass.Generated.Member
-    public boolean isWaitingToRecord() {
-        return mWaitingToRecord;
+    public boolean isWaitingForConsent() {
+        return mWaitingForConsent;
     }
 
     /**
@@ -309,8 +309,8 @@
      * <p>Only set on the server side to sanitize any input from the client process.
      */
     @DataClass.Generated.Member
-    public @NonNull ContentRecordingSession setWaitingToRecord( boolean value) {
-        mWaitingToRecord = value;
+    public @NonNull ContentRecordingSession setWaitingForConsent( boolean value) {
+        mWaitingForConsent = value;
         return this;
     }
 
@@ -325,7 +325,7 @@
                 "contentToRecord = " + recordContentToString(mContentToRecord) + ", " +
                 "displayToRecord = " + mDisplayToRecord + ", " +
                 "tokenToRecord = " + mTokenToRecord + ", " +
-                "waitingToRecord = " + mWaitingToRecord +
+                "waitingForConsent = " + mWaitingForConsent +
         " }";
     }
 
@@ -346,7 +346,7 @@
                 && mContentToRecord == that.mContentToRecord
                 && mDisplayToRecord == that.mDisplayToRecord
                 && java.util.Objects.equals(mTokenToRecord, that.mTokenToRecord)
-                && mWaitingToRecord == that.mWaitingToRecord;
+                && mWaitingForConsent == that.mWaitingForConsent;
     }
 
     @Override
@@ -360,7 +360,7 @@
         _hash = 31 * _hash + mContentToRecord;
         _hash = 31 * _hash + mDisplayToRecord;
         _hash = 31 * _hash + java.util.Objects.hashCode(mTokenToRecord);
-        _hash = 31 * _hash + Boolean.hashCode(mWaitingToRecord);
+        _hash = 31 * _hash + Boolean.hashCode(mWaitingForConsent);
         return _hash;
     }
 
@@ -371,7 +371,7 @@
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
         byte flg = 0;
-        if (mWaitingToRecord) flg |= 0x10;
+        if (mWaitingForConsent) flg |= 0x10;
         if (mTokenToRecord != null) flg |= 0x8;
         dest.writeByte(flg);
         dest.writeInt(mVirtualDisplayId);
@@ -392,7 +392,7 @@
         // static FieldType unparcelFieldName(Parcel in) { ... }
 
         byte flg = in.readByte();
-        boolean waitingToRecord = (flg & 0x10) != 0;
+        boolean waitingForConsent = (flg & 0x10) != 0;
         int virtualDisplayId = in.readInt();
         int contentToRecord = in.readInt();
         int displayToRecord = in.readInt();
@@ -411,7 +411,7 @@
 
         this.mDisplayToRecord = displayToRecord;
         this.mTokenToRecord = tokenToRecord;
-        this.mWaitingToRecord = waitingToRecord;
+        this.mWaitingForConsent = waitingForConsent;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -441,7 +441,7 @@
         private @RecordContent int mContentToRecord;
         private int mDisplayToRecord;
         private @Nullable IBinder mTokenToRecord;
-        private boolean mWaitingToRecord;
+        private boolean mWaitingForConsent;
 
         private long mBuilderFieldsSet = 0L;
 
@@ -506,10 +506,10 @@
          * <p>Only set on the server side to sanitize any input from the client process.
          */
         @DataClass.Generated.Member
-        public @NonNull Builder setWaitingToRecord(boolean value) {
+        public @NonNull Builder setWaitingForConsent(boolean value) {
             checkNotUsed();
             mBuilderFieldsSet |= 0x10;
-            mWaitingToRecord = value;
+            mWaitingForConsent = value;
             return this;
         }
 
@@ -531,14 +531,14 @@
                 mTokenToRecord = null;
             }
             if ((mBuilderFieldsSet & 0x10) == 0) {
-                mWaitingToRecord = false;
+                mWaitingForConsent = false;
             }
             ContentRecordingSession o = new ContentRecordingSession(
                     mVirtualDisplayId,
                     mContentToRecord,
                     mDisplayToRecord,
                     mTokenToRecord,
-                    mWaitingToRecord);
+                    mWaitingForConsent);
             return o;
         }
 
@@ -551,10 +551,10 @@
     }
 
     @DataClass.Generated(
-            time = 1679855157534L,
+            time = 1683628463074L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/view/ContentRecordingSession.java",
-            inputSignatures = "public static final  int RECORD_CONTENT_DISPLAY\npublic static final  int RECORD_CONTENT_TASK\nprivate  int mVirtualDisplayId\nprivate @android.view.ContentRecordingSession.RecordContent int mContentToRecord\nprivate  int mDisplayToRecord\nprivate @android.annotation.Nullable android.os.IBinder mTokenToRecord\nprivate  boolean mWaitingToRecord\npublic static  android.view.ContentRecordingSession createDisplaySession(int)\npublic static  android.view.ContentRecordingSession createTaskSession(android.os.IBinder)\npublic static  boolean isValid(android.view.ContentRecordingSession)\npublic static  boolean isProjectionOnSameDisplay(android.view.ContentRecordingSession,android.view.ContentRecordingSession)\nclass ContentRecordingSession extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genSetters=true, genEqualsHashCode=true)")
+            inputSignatures = "public static final  int RECORD_CONTENT_DISPLAY\npublic static final  int RECORD_CONTENT_TASK\nprivate  int mVirtualDisplayId\nprivate @android.view.ContentRecordingSession.RecordContent int mContentToRecord\nprivate  int mDisplayToRecord\nprivate @android.annotation.Nullable android.os.IBinder mTokenToRecord\nprivate  boolean mWaitingForConsent\npublic static  android.view.ContentRecordingSession createDisplaySession(int)\npublic static  android.view.ContentRecordingSession createTaskSession(android.os.IBinder)\npublic static  boolean isValid(android.view.ContentRecordingSession)\npublic static  boolean isProjectionOnSameDisplay(android.view.ContentRecordingSession,android.view.ContentRecordingSession)\nclass ContentRecordingSession extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genSetters=true, genEqualsHashCode=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 60529c7..4b96d74 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -1638,7 +1638,7 @@
      * bounds of the window.
      * <p></p>
      * Handling multi-window mode correctly is necessary since applications are not always
-     * fullscreen. A user on a large screen device, such as a tablet or Chrome OS devices, is more
+     * fullscreen. A user on a large screen device, such as a tablet or ChromeOS devices, is more
      * likely to use multi-window modes.
      * <p></p>
      * For example, consider a device with a display partitioned into two halves. The user may have
@@ -1708,7 +1708,7 @@
      * bounds of the window.
      * <p></p>
      * Handling multi-window mode correctly is necessary since applications are not always
-     * fullscreen. A user on a large screen device, such as a tablet or Chrome OS devices, is more
+     * fullscreen. A user on a large screen device, such as a tablet or ChromeOS devices, is more
      * likely to use multi-window modes.
      * <p></p>
      * For example, consider a device with a display partitioned into two halves. The user may have
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index d8bff1c..f570c6d 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -658,6 +658,9 @@
     /** Set of inset types which cannot be controlled by the user animation */
     private @InsetsType int mDisabledUserAnimationInsetsTypes;
 
+    /** Set of inset types which are existing */
+    private @InsetsType int mExistingTypes = 0;
+
     /** Set of inset types which are visible */
     private @InsetsType int mVisibleTypes = WindowInsets.Type.defaultVisible();
 
@@ -906,6 +909,12 @@
             }
             mVisibleTypes = visibleTypes;
         }
+        if (mExistingTypes != existingTypes) {
+            if (WindowInsets.Type.hasCompatSystemBars(mExistingTypes ^ existingTypes)) {
+                mCompatSysUiVisibilityStaled = true;
+            }
+            mExistingTypes = existingTypes;
+        }
         InsetsState.traverse(mState, newState, mRemoveGoneSources);
 
         updateDisabledUserAnimationTypes(disabledUserAnimationTypes);
@@ -1662,7 +1671,8 @@
         if (mCompatSysUiVisibilityStaled) {
             mCompatSysUiVisibilityStaled = false;
             mHost.updateCompatSysUiVisibility(
-                    mVisibleTypes, mRequestedVisibleTypes, mControllableTypes);
+                    // Treat non-existing types as controllable types for compatibility.
+                    mVisibleTypes, mRequestedVisibleTypes, mControllableTypes | ~mExistingTypes);
         }
     }
 
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 62fdfae..ddaa71c 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -461,6 +461,7 @@
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
     private String mName;
+    private String mCallsite;
 
      /**
      * Note: do not rename, this field is used by native code.
@@ -774,7 +775,6 @@
             release();
         }
         if (nativeObject != 0) {
-            mCloseGuard.openWithCallSite("release", callsite);
             mFreeNativeResources =
                     sRegistry.registerNativeAllocation(this, nativeObject);
         }
@@ -785,6 +785,8 @@
         } else {
             mReleaseStack = null;
         }
+        setUnreleasedWarningCallSite(callsite);
+        addToRegistry();
     }
 
     /**
@@ -1322,6 +1324,23 @@
             return;
         }
         mCloseGuard.openWithCallSite("release", callsite);
+        mCallsite = callsite;
+    }
+
+    /**
+     * Returns the last provided call site when this SurfaceControl was created.
+     * @hide
+     */
+    @Nullable String getCallsite() {
+        return mCallsite;
+    }
+
+    /**
+     * Returns the name of this SurfaceControl, mainly for debugging purposes.
+     * @hide
+     */
+    @NonNull String getName() {
+        return mName;
     }
 
     /**
@@ -1435,6 +1454,7 @@
             if (mCloseGuard != null) {
                 mCloseGuard.warnIfOpen();
             }
+            removeFromRegistry();
         } finally {
             super.finalize();
         }
@@ -1465,6 +1485,7 @@
                     mChoreographer = null;
                 }
             }
+            removeFromRegistry();
         }
     }
 
@@ -4304,6 +4325,26 @@
         return -1;
     }
 
+    /**
+     * Adds this surface control to the registry for this process if it is created.
+     */
+    private void addToRegistry() {
+        final SurfaceControlRegistry registry = SurfaceControlRegistry.getProcessInstance();
+        if (registry != null) {
+            registry.add(this);
+        }
+    }
+
+    /**
+     * Removes this surface control from the registry for this process.
+     */
+    private void removeFromRegistry() {
+        final SurfaceControlRegistry registry = SurfaceControlRegistry.getProcessInstance();
+        if (registry != null) {
+            registry.remove(this);
+        }
+    }
+
     // Called by native
     private static void invokeReleaseCallback(Consumer<SyncFence> callback, long nativeFencePtr) {
         SyncFence fence = new SyncFence(nativeFencePtr);
diff --git a/core/java/android/view/SurfaceControlRegistry.java b/core/java/android/view/SurfaceControlRegistry.java
new file mode 100644
index 0000000..67ac811
--- /dev/null
+++ b/core/java/android/view/SurfaceControlRegistry.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import static android.Manifest.permission.READ_FRAME_BUFFER;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.content.Context;
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.GcUtils;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * A thread-safe registry used to track surface controls that are active (not yet released) within a
+ * process, to help debug and identify leaks.
+ * @hide
+ */
+public class SurfaceControlRegistry {
+    private static final String TAG = "SurfaceControlRegistry";
+
+    /**
+     * An interface for processing the registered SurfaceControls when the threshold is exceeded.
+     */
+    public interface Reporter {
+        /**
+         * Called when the set of layers exceeds the max threshold.  This can be called on any
+         * thread, and must be handled synchronously.
+         */
+        void onMaxLayersExceeded(WeakHashMap<SurfaceControl, Long> surfaceControls, int limit,
+                PrintWriter pw);
+    }
+
+    /**
+     * The default implementation of the reporter which logs the existing registered surfaces to
+     * logcat.
+     */
+    private static class DefaultReporter implements Reporter {
+        public void onMaxLayersExceeded(WeakHashMap<SurfaceControl, Long> surfaceControls,
+                int limit, PrintWriter pw) {
+            final long now = SystemClock.elapsedRealtime();
+            final ArrayList<Map.Entry<SurfaceControl, Long>> entries = new ArrayList<>();
+            for (Map.Entry<SurfaceControl, Long> entry : surfaceControls.entrySet()) {
+                entries.add(entry);
+            }
+            // Sort entries by time registered when dumping
+            // TODO: Or should it sort by name?
+            entries.sort((o1, o2) -> (int) (o1.getValue() - o2.getValue()));
+            final int size = Math.min(entries.size(), limit);
+
+            pw.println("SurfaceControlRegistry");
+            pw.println("----------------------");
+            pw.println("Listing oldest " + size + " of " + surfaceControls.size());
+            for (int i = 0; i < size; i++) {
+                final Map.Entry<SurfaceControl, Long> entry = entries.get(i);
+                final SurfaceControl sc = entry.getKey();
+                final long timeRegistered = entry.getValue();
+                pw.print("  ");
+                pw.print(sc.getName());
+                pw.print(" (" + sc.getCallsite() + ")");
+                pw.println(" [" + ((now - timeRegistered) / 1000) + "s ago]");
+            }
+        }
+    }
+
+    // The threshold at which to dump information about all the known active SurfaceControls in the
+    // process when the number of layers exceeds a certain count.  This should be significantly
+    // smaller than the MAX_LAYERS (currently 4096) defined in SurfaceFlinger.h
+    private static final int MAX_LAYERS_REPORTING_THRESHOLD = 1024;
+
+    // The threshold at which to reset the dump state.  Needs to be smaller than
+    // MAX_LAYERS_REPORTING_THRESHOLD
+    private static final int RESET_REPORTING_THRESHOLD = 256;
+
+    // Number of surface controls to dump when the max threshold is exceeded
+    private static final int DUMP_LIMIT = 256;
+
+    // Static lock, must be held for all registry operations
+    private static final Object sLock = new Object();
+
+    // The default reporter for printing out the registered surfaces
+    private static final DefaultReporter sDefaultReporter = new DefaultReporter();
+
+    // The registry for a given process
+    private static volatile SurfaceControlRegistry sProcessRegistry;
+
+    // Mapping of the active SurfaceControls to the elapsed time when they were registered
+    @GuardedBy("sLock")
+    private final WeakHashMap<SurfaceControl, Long> mSurfaceControls;
+
+    // The threshold at which we dump information about the current set of registered surfaces.
+    // Once this threshold is reached, we no longer report until the number of layers drops below
+    // mResetReportingThreshold to ensure that we don't spam logcat.
+    private int mMaxLayersReportingThreshold = MAX_LAYERS_REPORTING_THRESHOLD;
+    private int mResetReportingThreshold = RESET_REPORTING_THRESHOLD;
+
+    // Whether the current set of layers has exceeded mMaxLayersReportingThreshold, and we have
+    // already reported the set of registered surfaces.
+    private boolean mHasReportedExceedingMaxThreshold = false;
+
+    // The handler for when the registry exceeds the max threshold
+    private Reporter mReporter = sDefaultReporter;
+
+    private SurfaceControlRegistry() {
+        mSurfaceControls = new WeakHashMap<>(256);
+    }
+
+    /**
+     * Sets the thresholds at which the registry reports errors.
+     * @param maxLayersReportingThreshold The max threshold (inclusive)
+     * @param resetReportingThreshold The reset threshold (inclusive)
+     * @hide
+     */
+    @VisibleForTesting
+    public void setReportingThresholds(int maxLayersReportingThreshold, int resetReportingThreshold,
+            Reporter reporter) {
+        synchronized (sLock) {
+            if (maxLayersReportingThreshold <= 0
+                    || resetReportingThreshold >= maxLayersReportingThreshold) {
+                throw new IllegalArgumentException("Expected maxLayersReportingThreshold ("
+                        + maxLayersReportingThreshold + ") to be > 0 and resetReportingThreshold ("
+                        + resetReportingThreshold + ") to be < maxLayersReportingThreshold");
+            }
+            if (reporter == null) {
+                throw new IllegalArgumentException("Expected non-null reporter");
+            }
+            mMaxLayersReportingThreshold = maxLayersReportingThreshold;
+            mResetReportingThreshold = resetReportingThreshold;
+            mHasReportedExceedingMaxThreshold = false;
+            mReporter = reporter;
+        }
+    }
+
+    /**
+     * Creates and initializes the registry for all SurfaceControls in this process. The caller must
+     * hold the READ_FRAME_BUFFER permission.
+     * @hide
+     */
+    @RequiresPermission(READ_FRAME_BUFFER)
+    @NonNull
+    public static void createProcessInstance(Context context) {
+        if (context.checkSelfPermission(READ_FRAME_BUFFER) != PERMISSION_GRANTED) {
+            throw new SecurityException("Expected caller to hold READ_FRAME_BUFFER");
+        }
+        synchronized (sLock) {
+            if (sProcessRegistry == null) {
+                sProcessRegistry = new SurfaceControlRegistry();
+            }
+        }
+    }
+
+    /**
+     * Destroys the previously created registry this process.
+     * @hide
+     */
+    public static void destroyProcessInstance() {
+        synchronized (sLock) {
+            if (sProcessRegistry == null) {
+                return;
+            }
+            sProcessRegistry = null;
+        }
+    }
+
+    /**
+     * Returns the instance of the registry for this process, only non-null if
+     * createProcessInstance(Context) was previously called from a valid caller.
+     * @hide
+     */
+    @Nullable
+    @VisibleForTesting
+    public static SurfaceControlRegistry getProcessInstance() {
+        synchronized (sLock) {
+            return sProcessRegistry;
+        }
+    }
+
+    /**
+     * Adds a SurfaceControl to the registry.
+     */
+    void add(SurfaceControl sc) {
+        synchronized (sLock) {
+            mSurfaceControls.put(sc, SystemClock.elapsedRealtime());
+            if (!mHasReportedExceedingMaxThreshold
+                    && mSurfaceControls.size() >= mMaxLayersReportingThreshold) {
+                // Dump existing info to logcat for debugging purposes (but don't close the
+                // System.out output stream otherwise we can't print to it after this call)
+                PrintWriter pw = new PrintWriter(System.out, true /* autoFlush */);
+                mReporter.onMaxLayersExceeded(mSurfaceControls, DUMP_LIMIT, pw);
+                mHasReportedExceedingMaxThreshold = true;
+            }
+        }
+    }
+
+    /**
+     * Removes a SurfaceControl from the registry.
+     */
+    void remove(SurfaceControl sc) {
+        synchronized (sLock) {
+            mSurfaceControls.remove(sc);
+            if (mHasReportedExceedingMaxThreshold
+                    && mSurfaceControls.size() <= mResetReportingThreshold) {
+                mHasReportedExceedingMaxThreshold = false;
+            }
+        }
+    }
+
+    /**
+     * Returns a hash of this registry and is a function of all the active surface controls. This
+     * is useful for testing to determine whether the registry has changed between creating and
+     * destroying new SurfaceControls.
+     */
+    @Override
+    public int hashCode() {
+        synchronized (sLock) {
+            // Return a hash of the surface controls
+            return mSurfaceControls.keySet().hashCode();
+        }
+    }
+
+    /**
+     * Forces the gc and finalizers to run, used prior to dumping to ensure we only dump strongly
+     * referenced surface controls.
+     */
+    private static void runGcAndFinalizers() {
+        long t = SystemClock.elapsedRealtime();
+        GcUtils.runGcAndFinalizersSync();
+        Log.i(TAG, "Ran gc and finalizers (" + (SystemClock.elapsedRealtime() - t) + "ms)");
+    }
+
+    /**
+     * Dumps information about the set of SurfaceControls in the registry.
+     *
+     * @param limit the number of layers to report
+     * @param runGc whether to run the GC and finalizers before dumping
+     * @hide
+     */
+    public static void dump(int limit, boolean runGc, PrintWriter pw) {
+        if (runGc) {
+            // This needs to run outside the lock since finalization isn't synchronous
+            runGcAndFinalizers();
+        }
+        synchronized (sLock) {
+            if (sProcessRegistry != null) {
+                sDefaultReporter.onMaxLayersExceeded(sProcessRegistry.mSurfaceControls, limit, pw);
+            }
+        }
+    }
+}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 441636d..f1cde3b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7734,13 +7734,14 @@
         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
 
         boolean handled = false;
-        final ListenerInfo li = mListenerInfo;
+        final OnLongClickListener listener =
+                mListenerInfo == null ? null : mListenerInfo.mOnLongClickListener;
         boolean shouldPerformHapticFeedback = true;
-        if (li != null && li.mOnLongClickListener != null) {
-            handled = li.mOnLongClickListener.onLongClick(View.this);
+        if (listener != null) {
+            handled = listener.onLongClick(View.this);
             if (handled) {
-                shouldPerformHapticFeedback =
-                        li.mOnLongClickListener.onLongClickUseDefaultHapticFeedback(View.this);
+                shouldPerformHapticFeedback = listener.onLongClickUseDefaultHapticFeedback(
+                        View.this);
             }
         }
         if (!handled) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index f662c73..4cbb040 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -6969,10 +6969,10 @@
 
             if (event.getAction() == KeyEvent.ACTION_DOWN
                     && event.getKeyCode() == KeyEvent.KEYCODE_TAB) {
-                if (KeyEvent.metaStateHasModifiers(event.getMetaState(), KeyEvent.META_META_ON)) {
+                if (KeyEvent.metaStateHasModifiers(event.getMetaState(), KeyEvent.META_CTRL_ON)) {
                     groupNavigationDirection = View.FOCUS_FORWARD;
                 } else if (KeyEvent.metaStateHasModifiers(event.getMetaState(),
-                        KeyEvent.META_META_ON | KeyEvent.META_SHIFT_ON)) {
+                        KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON)) {
                     groupNavigationDirection = View.FOCUS_BACKWARD;
                 }
             }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 5b6df1c..e40f8e7 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -555,6 +555,13 @@
     int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT = (1 << 9); // 0x200
 
     /**
+     * Transition flag: The transition is prepared when nothing is visible on screen, e.g. screen
+     * is off. The animation handlers can decide whether to skip animations.
+     * @hide
+     */
+    int TRANSIT_FLAG_INVISIBLE = (1 << 10); // 0x400
+
+    /**
      * @hide
      */
     @IntDef(flag = true, prefix = { "TRANSIT_FLAG_" }, value = {
@@ -567,7 +574,8 @@
             TRANSIT_FLAG_KEYGUARD_LOCKED,
             TRANSIT_FLAG_IS_RECENTS,
             TRANSIT_FLAG_KEYGUARD_GOING_AWAY,
-            TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT
+            TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT,
+            TRANSIT_FLAG_INVISIBLE,
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface TransitionFlags {}
@@ -1185,6 +1193,68 @@
             "android.window.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE";
 
     /**
+     * Application level {@link android.content.pm.PackageManager.Property PackageManager
+     * .Property} for an app to inform the system that the app should be opted-out from the
+     * compatibility override that changes the min aspect ratio.
+     *
+     * <p>When this compat override is enabled the min aspect ratio given in the app's manifest can
+     * be overridden by the device manufacturer using their discretion to improve display
+     * compatibility unless the app's manifest value is higher. This treatment will also apply if
+     * no min aspect ratio value is provided in the manifest. These treatments can apply only in
+     * specific cases (e.g. device is in portrait) or each time the app is displayed on screen.
+     *
+     * <p>Setting this property to {@code false} informs the system that the app must be
+     * opted-out from the compatibility treatment even if the device manufacturer has opted the app
+     * into the treatment.
+     *
+     * <p>Not setting this property at all, or setting this property to {@code true} has no effect.
+     *
+     * <p><b>Syntax:</b>
+     * <pre>
+     * &lt;application&gt;
+     *   &lt;property
+     *     android:name="android.window.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE"
+     *     android:value="true|false"/&gt;
+     * &lt;/application&gt;
+     * </pre>
+     * @hide
+     */
+    // TODO(b/279428317): Make this public API.
+    String PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE =
+            "android.window.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE";
+
+    /**
+     * Application level {@link android.content.pm.PackageManager.Property PackageManager
+     * .Property} for an app to inform the system that the app should be opted-out from the
+     * compatibility overrides that change the resizability of the app.
+     *
+     * <p>When these compat overrides are enabled they force the packages they are applied to to be
+     * resizable / unresizable. If the app is forced to be resizable this won't change whether
+     * the app can be put into multi-windowing mode, but allow the app to resize without going into
+     * size-compat mode when the window container resizes, such as display size change or screen
+     * rotation.
+     *
+     * <p>Setting this property to {@code false} informs the system that the app must be
+     * opted-out from the compatibility treatment even if the device manufacturer has opted the app
+     * into the treatment.
+     *
+     * <p>Not setting this property at all, or setting this property to {@code true} has no effect.
+     *
+     * <p><b>Syntax:</b>
+     * <pre>
+     * &lt;application&gt;
+     *   &lt;property
+     *     android:name="android.window.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES"
+     *     android:value="true|false"/&gt;
+     * &lt;/application&gt;
+     * </pre>
+     * @hide
+     */
+    // TODO(b/280052089): Make this public API.
+    String PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES =
+            "android.window.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES";
+
+    /**
      * @hide
      */
     public static final String PARCEL_KEY_SHORTCUTS_ARRAY = "shortcuts_array";
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 02cd037..99a4f6b 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.res.Configuration;
+import android.graphics.HardwareRenderer;
 import android.os.Build;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -550,6 +551,11 @@
         ThreadedRenderer.trimMemory(level);
     }
 
+    /** @hide */
+    public void trimCaches(@HardwareRenderer.CacheTrimLevel int level) {
+        ThreadedRenderer.trimCaches(level);
+    }
+
     public void dumpGfxInfo(FileDescriptor fd, String[] args) {
         FileOutputStream fout = new FileOutputStream(fd);
         PrintWriter pw = new FastPrintWriter(fout);
diff --git a/core/java/android/view/autofill/AutofillFeatureFlags.java b/core/java/android/view/autofill/AutofillFeatureFlags.java
index b67969e..5ad74c8 100644
--- a/core/java/android/view/autofill/AutofillFeatureFlags.java
+++ b/core/java/android/view/autofill/AutofillFeatureFlags.java
@@ -275,6 +275,14 @@
     public static final boolean DEFAULT_AUTOFILL_PCC_CLASSIFICATION_ENABLED = false;
     // END AUTOFILL PCC CLASSIFICATION FLAGS DEFAULTS
 
+    // AUTOFILL FOR ALL APPS DEFAULTS
+    private static final boolean DEFAULT_AFAA_ON_UNIMPORTANT_VIEW_ENABLED = true;
+    private static final boolean DEFAULT_AFAA_ON_IMPORTANT_VIEW_ENABLED = true;
+    private static final String DEFAULT_AFAA_DENYLIST = "";
+    private static final String DEFAULT_AFAA_ALLOWLIST = "";
+    private static final String DEFAULT_AFAA_NON_AUTOFILLABLE_IME_ACTIONS = "3,4";
+    private static final boolean DEFAULT_AFAA_SHOULD_ENABLE_AUTOFILL_ON_ALL_VIEW_TYPES = true;
+    private static final boolean DEFAULT_AFAA_SHOULD_ENABLE_MULTILINE_FILTER = true;
 
     private AutofillFeatureFlags() {};
 
@@ -330,7 +338,8 @@
     public static boolean isTriggerFillRequestOnUnimportantViewEnabled() {
         return DeviceConfig.getBoolean(
             DeviceConfig.NAMESPACE_AUTOFILL,
-            DEVICE_CONFIG_TRIGGER_FILL_REQUEST_ON_UNIMPORTANT_VIEW, false);
+            DEVICE_CONFIG_TRIGGER_FILL_REQUEST_ON_UNIMPORTANT_VIEW,
+            DEFAULT_AFAA_ON_UNIMPORTANT_VIEW_ENABLED);
     }
 
     /**
@@ -341,7 +350,8 @@
     public static boolean isTriggerFillRequestOnFilteredImportantViewsEnabled() {
         return DeviceConfig.getBoolean(
             DeviceConfig.NAMESPACE_AUTOFILL,
-            DEVICE_CONFIG_TRIGGER_FILL_REQUEST_ON_FILTERED_IMPORTANT_VIEWS, false);
+            DEVICE_CONFIG_TRIGGER_FILL_REQUEST_ON_FILTERED_IMPORTANT_VIEWS,
+            DEFAULT_AFAA_ON_IMPORTANT_VIEW_ENABLED);
     }
 
     /**
@@ -352,7 +362,8 @@
     public static boolean shouldEnableAutofillOnAllViewTypes(){
         return DeviceConfig.getBoolean(
             DeviceConfig.NAMESPACE_AUTOFILL,
-            DEVICE_CONFIG_SHOULD_ENABLE_AUTOFILL_ON_ALL_VIEW_TYPES, false);
+            DEVICE_CONFIG_SHOULD_ENABLE_AUTOFILL_ON_ALL_VIEW_TYPES,
+            DEFAULT_AFAA_SHOULD_ENABLE_AUTOFILL_ON_ALL_VIEW_TYPES);
     }
 
     /**
@@ -363,7 +374,9 @@
      */
     public static Set<String> getNonAutofillableImeActionIdSetFromFlag() {
         final String mNonAutofillableImeActions = DeviceConfig.getString(
-                DeviceConfig.NAMESPACE_AUTOFILL, DEVICE_CONFIG_NON_AUTOFILLABLE_IME_ACTION_IDS, "");
+                DeviceConfig.NAMESPACE_AUTOFILL,
+                DEVICE_CONFIG_NON_AUTOFILLABLE_IME_ACTION_IDS,
+                DEFAULT_AFAA_NON_AUTOFILLABLE_IME_ACTIONS);
         return new ArraySet<>(Arrays.asList(mNonAutofillableImeActions.split(",")));
     }
 
@@ -378,7 +391,8 @@
     public static String getDenylistStringFromFlag() {
         return DeviceConfig.getString(
             DeviceConfig.NAMESPACE_AUTOFILL,
-            DEVICE_CONFIG_PACKAGE_DENYLIST_FOR_UNIMPORTANT_VIEW, "");
+            DEVICE_CONFIG_PACKAGE_DENYLIST_FOR_UNIMPORTANT_VIEW,
+            DEFAULT_AFAA_DENYLIST);
     }
 
     /**
@@ -389,7 +403,8 @@
     public static String getAllowlistStringFromFlag() {
         return DeviceConfig.getString(
             DeviceConfig.NAMESPACE_AUTOFILL,
-            DEVICE_CONFIG_PACKAGE_AND_ACTIVITY_ALLOWLIST_FOR_TRIGGERING_FILL_REQUEST, "");
+            DEVICE_CONFIG_PACKAGE_AND_ACTIVITY_ALLOWLIST_FOR_TRIGGERING_FILL_REQUEST,
+            DEFAULT_AFAA_ALLOWLIST);
     }
     /**
      * Whether include all views that have autofill type not none in assist structure.
@@ -422,7 +437,8 @@
     public static boolean shouldEnableMultilineFilter() {
         return DeviceConfig.getBoolean(
             DeviceConfig.NAMESPACE_AUTOFILL,
-            DEVICE_CONFIG_MULTILINE_FILTER_ENABLED, false);
+            DEVICE_CONFIG_MULTILINE_FILTER_ENABLED,
+            DEFAULT_AFAA_SHOULD_ENABLE_MULTILINE_FILTER);
     }
 
     // START AUTOFILL PCC CLASSIFICATION FUNCTIONS
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 2ef7419..ea75076 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -468,7 +468,8 @@
             COMMIT_REASON_ACTIVITY_FINISHED,
             COMMIT_REASON_VIEW_COMMITTED,
             COMMIT_REASON_VIEW_CLICKED,
-            COMMIT_REASON_VIEW_CHANGED
+            COMMIT_REASON_VIEW_CHANGED,
+            COMMIT_REASON_SESSION_DESTROYED
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface AutofillCommitReason {}
@@ -507,6 +508,12 @@
      * @hide
      */
     public static final int COMMIT_REASON_VIEW_CHANGED = 4;
+    /**
+     * Autofill context was committed because of the session was destroyed.
+     *
+     * @hide
+     */
+    public static final int COMMIT_REASON_SESSION_DESTROYED = 5;
 
     /**
      * Makes an authentication id from a request id and a dataset id.
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 8cff066..efd50e7 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -46,8 +46,6 @@
 import android.os.RemoteException;
 import android.text.Selection;
 import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.Spanned;
 import android.text.TextUtils;
 import android.util.LocalLog;
 import android.util.Log;
@@ -740,7 +738,10 @@
         // Since the same CharSequence instance may be reused in the TextView, we need to make
         // a copy of its content so that its value will not be changed by subsequent updates
         // in the TextView.
-        final CharSequence eventText = stringOrSpannedStringWithoutNoCopySpans(text);
+        CharSequence trimmed = TextUtils.trimToParcelableSize(text);
+        final CharSequence eventText = trimmed != null && trimmed == text
+                ? trimmed.toString()
+                : trimmed;
 
         final int composingStart;
         final int composingEnd;
@@ -761,16 +762,6 @@
                         .setSelectionIndex(startIndex, endIndex)));
     }
 
-    private CharSequence stringOrSpannedStringWithoutNoCopySpans(CharSequence source) {
-        if (source == null) {
-            return null;
-        } else if (source instanceof Spanned) {
-            return new SpannableString(source, /* ignoreNoCopySpan= */ true);
-        } else {
-            return source.toString();
-        }
-    }
-
     /** Public because is also used by ViewRootImpl */
     public void notifyViewInsetsChanged(int sessionId, @NonNull Insets viewInsets) {
         mHandler.post(() -> sendEvent(new ContentCaptureEvent(sessionId, TYPE_VIEW_INSETS_CHANGED)
diff --git a/core/java/android/view/contentcapture/OWNERS b/core/java/android/view/contentcapture/OWNERS
index 1a5cb1e4..d1eda96 100644
--- a/core/java/android/view/contentcapture/OWNERS
+++ b/core/java/android/view/contentcapture/OWNERS
@@ -5,3 +5,5 @@
 markpun@google.com
 lpeter@google.com
 tymtsai@google.com
+hackz@google.com
+volnov@google.com
\ No newline at end of file
diff --git a/core/java/android/view/contentcapture/ViewNode.java b/core/java/android/view/contentcapture/ViewNode.java
index 1762a58..044a31f 100644
--- a/core/java/android/view/contentcapture/ViewNode.java
+++ b/core/java/android/view/contentcapture/ViewNode.java
@@ -1052,14 +1052,21 @@
         }
 
         void writeToParcel(Parcel out, boolean simple) {
-            TextUtils.writeToParcel(mText, out, 0);
+            CharSequence text = TextUtils.trimToParcelableSize(mText);
+            TextUtils.writeToParcel(text, out, 0);
             out.writeFloat(mTextSize);
             out.writeInt(mTextStyle);
             out.writeInt(mTextColor);
             if (!simple) {
+                int selectionStart = text != null
+                        ? Math.min(mTextSelectionStart, text.length())
+                        : mTextSelectionStart;
+                int selectionEnd = text != null
+                        ? Math.min(mTextSelectionEnd, text.length())
+                        : mTextSelectionEnd;
                 out.writeInt(mTextBackgroundColor);
-                out.writeInt(mTextSelectionStart);
-                out.writeInt(mTextSelectionEnd);
+                out.writeInt(selectionStart);
+                out.writeInt(selectionEnd);
                 out.writeIntArray(mLineCharOffsets);
                 out.writeIntArray(mLineBaselines);
                 out.writeString(mHint);
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index c289506..dedbf50 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -726,6 +726,11 @@
                 mActions.get(i).visitUris(visitor);
             }
         }
+        if (mSizedRemoteViews != null) {
+            for (int i = 0; i < mSizedRemoteViews.size(); i++) {
+                mSizedRemoteViews.get(i).visitUris(visitor);
+            }
+        }
         if (mLandscape != null) {
             mLandscape.visitUris(visitor);
         }
@@ -783,7 +788,7 @@
         }
     }
 
-    private class SetEmptyView extends Action {
+    private static class SetEmptyView extends Action {
         int emptyViewId;
 
         SetEmptyView(@IdRes int viewId, @IdRes int emptyViewId) {
@@ -820,7 +825,7 @@
         }
     }
 
-    private class SetPendingIntentTemplate extends Action {
+    private static class SetPendingIntentTemplate extends Action {
         public SetPendingIntentTemplate(@IdRes int id, PendingIntent pendingIntentTemplate) {
             this.viewId = id;
             this.pendingIntentTemplate = pendingIntentTemplate;
@@ -891,7 +896,7 @@
         PendingIntent pendingIntentTemplate;
     }
 
-    private class SetRemoteViewsAdapterList extends Action {
+    private static class SetRemoteViewsAdapterList extends Action {
         public SetRemoteViewsAdapterList(@IdRes int id, ArrayList<RemoteViews> list,
                 int viewTypeCount) {
             this.viewId = id;
@@ -1354,7 +1359,7 @@
     }
 
     @Nullable
-    private MethodHandle getMethod(View view, String methodName, Class<?> paramType,
+    private static MethodHandle getMethod(View view, String methodName, Class<?> paramType,
             boolean async) {
         MethodArgs result;
         Class<? extends View> klass = view.getClass();
@@ -1433,7 +1438,7 @@
      * to {@link ImageView#getDrawable()}.
      * <p>
      */
-    private class SetDrawableTint extends Action {
+    private static class SetDrawableTint extends Action {
         SetDrawableTint(@IdRes int id, boolean targetBackground,
                 @ColorInt int colorFilter, @NonNull PorterDuff.Mode mode) {
             this.viewId = id;
@@ -1697,7 +1702,7 @@
     /**
      * Base class for the reflection actions.
      */
-    private abstract class BaseReflectionAction extends Action {
+    private abstract static class BaseReflectionAction extends Action {
         static final int BOOLEAN = 1;
         static final int BYTE = 2;
         static final int SHORT = 3;
@@ -1860,7 +1865,7 @@
     }
 
     /** Class for the reflection actions. */
-    private final class ReflectionAction extends BaseReflectionAction {
+    private static final class ReflectionAction extends BaseReflectionAction {
         @UnsupportedAppUsage
         Object value;
 
@@ -2006,7 +2011,7 @@
         }
     }
 
-    private final class ResourceReflectionAction extends BaseReflectionAction {
+    private static final class ResourceReflectionAction extends BaseReflectionAction {
 
         static final int DIMEN_RESOURCE = 1;
         static final int COLOR_RESOURCE = 2;
@@ -2093,7 +2098,7 @@
         }
     }
 
-    private final class AttributeReflectionAction extends BaseReflectionAction {
+    private static final class AttributeReflectionAction extends BaseReflectionAction {
 
         static final int DIMEN_RESOURCE = 1;
         static final int COLOR_RESOURCE = 2;
@@ -2187,7 +2192,7 @@
             return ATTRIBUTE_REFLECTION_ACTION_TAG;
         }
     }
-    private final class ComplexUnitDimensionReflectionAction extends BaseReflectionAction {
+    private static final class ComplexUnitDimensionReflectionAction extends BaseReflectionAction {
 
         private final float mValue;
         @ComplexDimensionUnit
@@ -2243,7 +2248,7 @@
         }
     }
 
-    private final class NightModeReflectionAction extends BaseReflectionAction {
+    private static final class NightModeReflectionAction extends BaseReflectionAction {
 
         private final Object mLightValue;
         private final Object mDarkValue;
@@ -2598,12 +2603,17 @@
         public int getActionTag() {
             return VIEW_GROUP_ACTION_ADD_TAG;
         }
+
+        @Override
+        public final void visitUris(@NonNull Consumer<Uri> visitor) {
+            mNestedViews.visitUris(visitor);
+        }
     }
 
     /**
      * ViewGroup methods related to removing child views.
      */
-    private class ViewGroupActionRemove extends Action {
+    private static class ViewGroupActionRemove extends Action {
         /**
          * Id that indicates that all child views of the affected ViewGroup should be removed.
          *
@@ -2725,7 +2735,7 @@
     /**
      * Action to remove a view from its parent.
      */
-    private class RemoveFromParentAction extends Action {
+    private static class RemoveFromParentAction extends Action {
 
         RemoveFromParentAction(@IdRes int viewId) {
             this.viewId = viewId;
@@ -2795,7 +2805,7 @@
      * Helper action to set compound drawables on a TextView. Supports relative
      * (s/t/e/b) or cardinal (l/t/r/b) arrangement.
      */
-    private class TextViewDrawableAction extends Action {
+    private static class TextViewDrawableAction extends Action {
         public TextViewDrawableAction(@IdRes int viewId, boolean isRelative, @DrawableRes int d1,
                 @DrawableRes int d2, @DrawableRes int d3, @DrawableRes int d4) {
             this.viewId = viewId;
@@ -2942,7 +2952,7 @@
     /**
      * Helper action to set text size on a TextView in any supported units.
      */
-    private class TextViewSizeAction extends Action {
+    private static class TextViewSizeAction extends Action {
         TextViewSizeAction(@IdRes int viewId, @ComplexDimensionUnit int units, float size) {
             this.viewId = viewId;
             this.units = units;
@@ -2980,7 +2990,7 @@
     /**
      * Helper action to set padding on a View.
      */
-    private class ViewPaddingAction extends Action {
+    private static class ViewPaddingAction extends Action {
         public ViewPaddingAction(@IdRes int viewId, @Px int left, @Px int top,
                 @Px int right, @Px int bottom) {
             this.viewId = viewId;
@@ -3210,7 +3220,7 @@
     /**
      * Helper action to add a view tag with RemoteInputs.
      */
-    private class SetRemoteInputsAction extends Action {
+    private static class SetRemoteInputsAction extends Action {
 
         public SetRemoteInputsAction(@IdRes int viewId, RemoteInput[] remoteInputs) {
             this.viewId = viewId;
@@ -3246,7 +3256,7 @@
     /**
      * Helper action to override all textViewColors
      */
-    private class OverrideTextColorsAction extends Action {
+    private static class OverrideTextColorsAction extends Action {
 
         private final int textColor;
 
@@ -3289,7 +3299,7 @@
         }
     }
 
-    private class SetIntTagAction extends Action {
+    private static class SetIntTagAction extends Action {
         @IdRes private final int mViewId;
         @IdRes private final int mKey;
         private final int mTag;
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 54d19eb..ee6ac12 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -50,6 +50,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -205,7 +206,7 @@
         INotificationManager service = getService();
         String pkg = mContext.getOpPackageName();
         TN tn = mTN;
-        tn.mNextView = mNextView;
+        tn.mNextView = new WeakReference<>(mNextView);
         final boolean isUiContext = mContext.isUiContext();
         final int displayId = mContext.getDisplayId();
 
@@ -622,7 +623,7 @@
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
         View mView;
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
-        View mNextView;
+        WeakReference<View> mNextView;
         int mDuration;
 
         WindowManager mWM;
@@ -632,7 +633,7 @@
         private final ToastPresenter mPresenter;
 
         @GuardedBy("mCallbacks")
-        private final List<Callback> mCallbacks;
+        private final WeakReference<List<Callback>> mCallbacks;
 
         /**
          * Creates a {@link ITransientNotification} object.
@@ -649,7 +650,7 @@
             mParams = mPresenter.getLayoutParams();
             mPackageName = packageName;
             mToken = token;
-            mCallbacks = callbacks;
+            mCallbacks = new WeakReference<>(callbacks);
 
             mHandler = new Handler(looper, null) {
                 @Override
@@ -685,7 +686,11 @@
 
         private List<Callback> getCallbacks() {
             synchronized (mCallbacks) {
-                return new ArrayList<>(mCallbacks);
+                if (mCallbacks.get() != null) {
+                    return new ArrayList<>(mCallbacks.get());
+                } else {
+                    return new ArrayList<>();
+                }
             }
         }
 
@@ -721,13 +726,15 @@
             if (mHandler.hasMessages(CANCEL) || mHandler.hasMessages(HIDE)) {
                 return;
             }
-            if (mView != mNextView) {
+            if (mNextView != null && mView != mNextView.get()) {
                 // remove the old view if necessary
                 handleHide();
-                mView = mNextView;
-                mPresenter.show(mView, mToken, windowToken, mDuration, mGravity, mX, mY,
-                        mHorizontalMargin, mVerticalMargin,
-                        new CallbackBinder(getCallbacks(), mHandler));
+                mView = mNextView.get();
+                if (mView != null) {
+                    mPresenter.show(mView, mToken, windowToken, mDuration, mGravity, mX, mY,
+                            mHorizontalMargin, mVerticalMargin,
+                            new CallbackBinder(getCallbacks(), mHandler));
+                }
             }
         }
 
diff --git a/core/java/android/widget/ToastPresenter.java b/core/java/android/widget/ToastPresenter.java
index 7467100..7cb61fe 100644
--- a/core/java/android/widget/ToastPresenter.java
+++ b/core/java/android/widget/ToastPresenter.java
@@ -41,6 +41,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 
+import java.lang.ref.WeakReference;
+
 /**
  * Class responsible for toast presentation inside app's process and in system UI.
  *
@@ -87,25 +89,33 @@
         return view;
     }
 
-    private final Context mContext;
     private final Resources mResources;
-    private final WindowManager mWindowManager;
-    private final IAccessibilityManager mAccessibilityManager;
+    private final WeakReference<WindowManager> mWindowManager;
+    private final WeakReference<AccessibilityManager> mAccessibilityManager;
     private final INotificationManager mNotificationManager;
     private final String mPackageName;
+    private final String mContextPackageName;
     private final WindowManager.LayoutParams mParams;
     @Nullable private View mView;
     @Nullable private IBinder mToken;
 
     public ToastPresenter(Context context, IAccessibilityManager accessibilityManager,
             INotificationManager notificationManager, String packageName) {
-        mContext = context;
         mResources = context.getResources();
-        mWindowManager = context.getSystemService(WindowManager.class);
+        mWindowManager = new WeakReference<>(context.getSystemService(WindowManager.class));
         mNotificationManager = notificationManager;
         mPackageName = packageName;
-        mAccessibilityManager = accessibilityManager;
+        mContextPackageName = context.getPackageName();
         mParams = createLayoutParams();
+
+        // We obtain AccessibilityManager manually via its constructor instead of using method
+        // AccessibilityManager.getInstance() for 2 reasons:
+        //   1. We want to be able to inject IAccessibilityManager in tests to verify behavior.
+        //   2. getInstance() caches the instance for the process even if we pass a different
+        //      context to it. This is problematic for multi-user because callers can pass a context
+        //      created via Context.createContextAsUser().
+        mAccessibilityManager = new WeakReference<>(
+                new AccessibilityManager(context, accessibilityManager, context.getUserId()));
     }
 
     public String getPackageName() {
@@ -173,7 +183,7 @@
         params.y = yOffset;
         params.horizontalMargin = horizontalMargin;
         params.verticalMargin = verticalMargin;
-        params.packageName = mContext.getPackageName();
+        params.packageName = mContextPackageName;
         params.hideTimeoutMilliseconds =
                 (duration == Toast.LENGTH_LONG) ? LONG_DURATION_TIMEOUT : SHORT_DURATION_TIMEOUT;
         params.token = windowToken;
@@ -270,8 +280,9 @@
     public void hide(@Nullable ITransientNotificationCallback callback) {
         checkState(mView != null, "No toast to hide.");
 
-        if (mView.getParent() != null) {
-            mWindowManager.removeViewImmediate(mView);
+        final WindowManager windowManager = mWindowManager.get();
+        if (mView.getParent() != null && windowManager != null) {
+            windowManager.removeViewImmediate(mView);
         }
         try {
             mNotificationManager.finishToken(mPackageName, mToken);
@@ -295,14 +306,11 @@
      * enabled.
      */
     public void trySendAccessibilityEvent(View view, String packageName) {
-        // We obtain AccessibilityManager manually via its constructor instead of using method
-        // AccessibilityManager.getInstance() for 2 reasons:
-        //   1. We want to be able to inject IAccessibilityManager in tests to verify behavior.
-        //   2. getInstance() caches the instance for the process even if we pass a different
-        //      context to it. This is problematic for multi-user because callers can pass a context
-        //      created via Context.createContextAsUser().
-        final AccessibilityManager accessibilityManager =
-                new AccessibilityManager(mContext, mAccessibilityManager, mContext.getUserId());
+        final AccessibilityManager accessibilityManager = mAccessibilityManager.get();
+        if (accessibilityManager == null) {
+            return;
+        }
+
         if (!accessibilityManager.isEnabled()) {
             accessibilityManager.removeClient();
             return;
@@ -320,11 +328,15 @@
     }
 
     private void addToastView() {
+        final WindowManager windowManager = mWindowManager.get();
+        if (windowManager == null) {
+            return;
+        }
         if (mView.getParent() != null) {
-            mWindowManager.removeView(mView);
+            windowManager.removeView(mView);
         }
         try {
-            mWindowManager.addView(mView, mParams);
+            windowManager.addView(mView, mParams);
         } catch (WindowManager.BadTokenException e) {
             // Since the notification manager service cancels the token right after it notifies us
             // to cancel the toast there is an inherent race and we may attempt to add a window
diff --git a/core/java/android/window/BackProgressAnimator.java b/core/java/android/window/BackProgressAnimator.java
index 618670a..e58c044 100644
--- a/core/java/android/window/BackProgressAnimator.java
+++ b/core/java/android/window/BackProgressAnimator.java
@@ -43,7 +43,7 @@
     private ProgressCallback mCallback;
     private float mProgress = 0;
     private BackMotionEvent mLastBackEvent;
-    private boolean mStarted = false;
+    private boolean mBackAnimationInProgress = false;
 
     private void setProgress(float progress) {
         mProgress = progress;
@@ -87,7 +87,7 @@
      * @param event the {@link BackMotionEvent} containing the latest target progress.
      */
     public void onBackProgressed(BackMotionEvent event) {
-        if (!mStarted) {
+        if (!mBackAnimationInProgress) {
             return;
         }
         mLastBackEvent = event;
@@ -108,7 +108,7 @@
         reset();
         mLastBackEvent = event;
         mCallback = callback;
-        mStarted = true;
+        mBackAnimationInProgress = true;
     }
 
     /**
@@ -122,7 +122,7 @@
             // Should never happen.
             mSpring.cancel();
         }
-        mStarted = false;
+        mBackAnimationInProgress = false;
         mLastBackEvent = null;
         mCallback = null;
         mProgress = 0;
@@ -149,8 +149,13 @@
         mSpring.animateToFinalPosition(0);
     }
 
+    /** Returns true if the back animation is in progress. */
+    boolean isBackAnimationInProgress() {
+        return mBackAnimationInProgress;
+    }
+
     private void updateProgressValue(float progress) {
-        if (mLastBackEvent == null || mCallback == null || !mStarted) {
+        if (mLastBackEvent == null || mCallback == null || !mBackAnimationInProgress) {
             return;
         }
         mCallback.onProgressUpdate(
diff --git a/core/java/android/window/TaskSnapshot.java b/core/java/android/window/TaskSnapshot.java
index b7bb608..41b6d31 100644
--- a/core/java/android/window/TaskSnapshot.java
+++ b/core/java/android/window/TaskSnapshot.java
@@ -28,6 +28,7 @@
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.SystemClock;
 import android.view.Surface;
 import android.view.WindowInsetsController;
 
@@ -38,6 +39,9 @@
 public class TaskSnapshot implements Parcelable {
     // Identifier of this snapshot
     private final long mId;
+    // The elapsed real time (in nanoseconds) when this snapshot was captured, not intended for use outside the
+    // process in which the snapshot was taken (ie. this is not parceled)
+    private final long mCaptureTime;
     // Top activity in task when snapshot was taken
     private final ComponentName mTopActivityComponent;
     private final HardwareBuffer mSnapshot;
@@ -65,7 +69,7 @@
     // Must be one of the named color spaces, otherwise, always use SRGB color space.
     private final ColorSpace mColorSpace;
 
-    public TaskSnapshot(long id,
+    public TaskSnapshot(long id, long captureTime,
             @NonNull ComponentName topActivityComponent, HardwareBuffer snapshot,
             @NonNull ColorSpace colorSpace, int orientation, int rotation, Point taskSize,
             Rect contentInsets, Rect letterboxInsets, boolean isLowResolution,
@@ -73,6 +77,7 @@
             @WindowInsetsController.Appearance int appearance, boolean isTranslucent,
             boolean hasImeSurface) {
         mId = id;
+        mCaptureTime = captureTime;
         mTopActivityComponent = topActivityComponent;
         mSnapshot = snapshot;
         mColorSpace = colorSpace.getId() < 0
@@ -92,6 +97,7 @@
 
     private TaskSnapshot(Parcel source) {
         mId = source.readLong();
+        mCaptureTime = SystemClock.elapsedRealtimeNanos();
         mTopActivityComponent = ComponentName.readFromParcel(source);
         mSnapshot = source.readTypedObject(HardwareBuffer.CREATOR);
         int colorSpaceId = source.readInt();
@@ -119,6 +125,14 @@
     }
 
     /**
+     * @return The elapsed real time (in nanoseconds) when this snapshot was captured. This time is
+     * only valid in the process where this snapshot was taken.
+     */
+    public long getCaptureTime() {
+        return mCaptureTime;
+    }
+
+    /**
      * @return The top activity component for the task at the point this snapshot was taken.
      */
     public ComponentName getTopActivityComponent() {
@@ -268,6 +282,7 @@
         final int height = mSnapshot != null ? mSnapshot.getHeight() : 0;
         return "TaskSnapshot{"
                 + " mId=" + mId
+                + " mCaptureTime=" + mCaptureTime
                 + " mTopActivityComponent=" + mTopActivityComponent.flattenToShortString()
                 + " mSnapshot=" + mSnapshot + " (" + width + "x" + height + ")"
                 + " mColorSpace=" + mColorSpace.toString()
@@ -296,6 +311,7 @@
     /** Builder for a {@link TaskSnapshot} object */
     public static final class Builder {
         private long mId;
+        private long mCaptureTime;
         private ComponentName mTopActivity;
         private HardwareBuffer mSnapshot;
         private ColorSpace mColorSpace;
@@ -317,6 +333,11 @@
             return this;
         }
 
+        public Builder setCaptureTime(long captureTime) {
+            mCaptureTime = captureTime;
+            return this;
+        }
+
         public Builder setTopActivityComponent(ComponentName name) {
             mTopActivity = name;
             return this;
@@ -400,6 +421,7 @@
         public TaskSnapshot build() {
             return new TaskSnapshot(
                     mId,
+                    mCaptureTime,
                     mTopActivity,
                     mSnapshot,
                     mColorSpace,
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index c0370cc..8c05130 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -493,6 +493,9 @@
         if ((flags & FLAG_FIRST_CUSTOM) != 0) {
             sb.append(sb.length() == 0 ? "" : "|").append("FIRST_CUSTOM");
         }
+        if ((flags & FLAG_MOVED_TO_TOP) != 0) {
+            sb.append(sb.length() == 0 ? "" : "|").append("MOVE_TO_TOP");
+        }
         return sb.toString();
     }
 
diff --git a/core/java/android/window/WindowInfosListenerForTest.java b/core/java/android/window/WindowInfosListenerForTest.java
index 01e577f..cfbeeff 100644
--- a/core/java/android/window/WindowInfosListenerForTest.java
+++ b/core/java/android/window/WindowInfosListenerForTest.java
@@ -68,12 +68,18 @@
          */
         public final boolean isTrustedOverlay;
 
+        /**
+         * True if the window is visible.
+         */
+        public final boolean isVisible;
+
         WindowInfo(@NonNull IBinder windowToken, @NonNull String name, @NonNull Rect bounds,
                 int inputConfig) {
             this.windowToken = windowToken;
             this.name = name;
             this.bounds = bounds;
             this.isTrustedOverlay = (inputConfig & InputConfig.TRUSTED_OVERLAY) != 0;
+            this.isVisible = (inputConfig & InputConfig.NOT_VISIBLE) == 0;
         }
     }
 
@@ -131,9 +137,6 @@
     private static List<WindowInfo> buildWindowInfos(InputWindowHandle[] windowHandles) {
         var windowInfos = new ArrayList<WindowInfo>(windowHandles.length);
         for (var handle : windowHandles) {
-            if ((handle.inputConfig & InputConfig.NOT_VISIBLE) != 0) {
-                continue;
-            }
             var bounds = new Rect(handle.frameLeft, handle.frameTop, handle.frameRight,
                     handle.frameBottom);
             windowInfos.add(new WindowInfo(handle.getWindowToken(), handle.name, bounds,
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 4d0132e..22b2ec0 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -158,6 +158,16 @@
         mAllCallbacks.remove(callback);
         // Re-populate the top callback to WM if the removed callback was previously the top one.
         if (previousTopCallback == callback) {
+            // We should call onBackCancelled() when an active callback is removed from dispatcher.
+            if (mProgressAnimator.isBackAnimationInProgress()
+                    && callback instanceof OnBackAnimationCallback) {
+                // The ProgressAnimator will handle the new topCallback, so we don't want to call
+                // onBackCancelled() on it. We call immediately the callback instead.
+                OnBackAnimationCallback animatedCallback = (OnBackAnimationCallback) callback;
+                animatedCallback.onBackCancelled();
+                Log.d(TAG, "The callback was removed while a back animation was in progress, "
+                        + "an onBackCancelled() was dispatched.");
+            }
             setTopOnBackInvokedCallback(getTopCallback());
         }
     }
diff --git a/core/java/com/android/internal/app/AppLocaleCollector.java b/core/java/com/android/internal/app/AppLocaleCollector.java
index 7cf428a..56f633f 100644
--- a/core/java/com/android/internal/app/AppLocaleCollector.java
+++ b/core/java/com/android/internal/app/AppLocaleCollector.java
@@ -157,13 +157,13 @@
      * Get a list of system locale that removes all extensions except for the numbering system.
      */
     @VisibleForTesting
-    public List<LocaleStore.LocaleInfo> getSystemCurrentLocales() {
-        List<LocaleStore.LocaleInfo> sysLocales = LocaleStore.getSystemCurrentLocales();
+    public Set<LocaleStore.LocaleInfo> getSystemCurrentLocales() {
+        Set<LocaleStore.LocaleInfo> sysLocales = LocaleStore.getSystemCurrentLocales();
         return sysLocales.stream().filter(
                 // For the locale to be added into the suggestion area, its country could not be
                 // empty.
                 info -> info.getLocale().getCountry().length() > 0).collect(
-                Collectors.toList());
+                Collectors.toSet());
     }
 
     @Override
@@ -225,7 +225,10 @@
         // Add current system language into suggestion list
         if (!isForCountryMode) {
             boolean isCurrentLocale, existsInApp, existsInIme;
-            for (LocaleStore.LocaleInfo localeInfo : getSystemCurrentLocales()) {
+            // filter out the system locases that are supported by the application.
+            Set<LocaleStore.LocaleInfo> localeInfoSet =
+                    filterSupportedLocales(getSystemCurrentLocales(), result.mAppSupportedLocales);
+            for (LocaleStore.LocaleInfo localeInfo : localeInfoSet) {
                 isCurrentLocale = mAppCurrentLocale != null
                         && localeInfo.getLocale().equals(mAppCurrentLocale.getLocale());
                 // Add the system suggestion flag if the localeInfo exists in mAllAppActiveLocales
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index ace8451..2b39bb4 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -165,9 +165,11 @@
 import java.util.stream.Collectors;
 
 /**
- * The Chooser Activity handles intent resolution specifically for sharing intents -
- * for example, those generated by @see android.content.Intent#createChooser(Intent, CharSequence).
+ * This is the legacy ChooserActivity and is not expected to be invoked, it's only here because
+ * MediaAppSelectorActivity is still depending on it. The actual chooser used by the system is
+ * at packages/modules/IntentResolver/java/src/com/android/intentresolver/ChooserActivity.java
  *
+ * The migration to the new package will be completed in a later release.
  */
 public class ChooserActivity extends ResolverActivity implements
         ChooserListAdapter.ChooserListCommunicator,
diff --git a/core/java/com/android/internal/app/HarmfulAppWarningActivity.java b/core/java/com/android/internal/app/HarmfulAppWarningActivity.java
index c19196f..35dacb6 100644
--- a/core/java/com/android/internal/app/HarmfulAppWarningActivity.java
+++ b/core/java/com/android/internal/app/HarmfulAppWarningActivity.java
@@ -18,6 +18,7 @@
 
 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 
+import android.app.ActivityOptions;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -108,9 +109,14 @@
                 getPackageManager().setHarmfulAppWarning(mPackageName, null /*warning*/);
 
                 final IntentSender target = getIntent().getParcelableExtra(Intent.EXTRA_INTENT, android.content.IntentSender.class);
+                Bundle activityOptions =
+                        ActivityOptions.makeBasic()
+                                .setPendingIntentBackgroundActivityStartMode(
+                                        ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+                                .toBundle();
                 try {
                     startIntentSenderForResult(target, -1 /*requestCode*/, null /*fillInIntent*/,
-                            0 /*flagsMask*/, 0 /*flagsValue*/, 0 /*extraFlags*/);
+                            0 /*flagsMask*/, 0 /*flagsValue*/, 0 /*extraFlags*/, activityOptions);
                 } catch (IntentSender.SendIntentException e) {
                     Log.e(TAG, "Error while starting intent sender", e);
                 }
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 65394bd..d433cd6 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -219,10 +219,6 @@
     @EnforcePermission("BATTERY_STATS")
     long getAwakeTimePlugged();
 
-    @EnforcePermission("BLUETOOTH_CONNECT")
-    void noteBluetoothOn(int uid, int reason, String packageName);
-    @EnforcePermission("BLUETOOTH_CONNECT")
-    void noteBluetoothOff(int uid, int reason, String packageName);
     @EnforcePermission("UPDATE_DEVICE_STATS")
     void noteBleScanStarted(in WorkSource ws, boolean isUnoptimized);
     @EnforcePermission("UPDATE_DEVICE_STATS")
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 904fb66..7452daa 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -19,7 +19,11 @@
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.app.admin.DevicePolicyResources.Strings.Core.FORWARD_INTENT_TO_PERSONAL;
 import static android.app.admin.DevicePolicyResources.Strings.Core.FORWARD_INTENT_TO_WORK;
+import static android.app.admin.DevicePolicyResources.Strings.Core.MINIRESOLVER_CALL_FROM_WORK;
 import static android.app.admin.DevicePolicyResources.Strings.Core.MINIRESOLVER_OPEN_WORK;
+import static android.app.admin.DevicePolicyResources.Strings.Core.MINIRESOLVER_SWITCH_TO_WORK;
+import static android.app.admin.DevicePolicyResources.Strings.Core.MINIRESOLVER_WORK_TELEPHONY_CALL_BLOCKED_INFORMATION;
+import static android.app.admin.DevicePolicyResources.Strings.Core.MINIRESOLVER_WORK_TELEPHONY_TEXT_BLOCKED_INFORMATION;
 import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 
@@ -29,9 +33,11 @@
 import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.app.Activity;
+import android.app.ActivityOptions;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.admin.DevicePolicyManager;
+import android.app.admin.ManagedSubscriptionsPolicy;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -41,6 +47,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
+import android.graphics.drawable.Drawable;
 import android.metrics.LogMaker;
 import android.os.Build;
 import android.os.Bundle;
@@ -48,6 +55,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.telecom.TelecomManager;
 import android.util.Slog;
 import android.view.View;
 import android.widget.Button;
@@ -203,35 +211,124 @@
 
         findViewById(R.id.title_container).setElevation(0);
 
-        ImageView icon = findViewById(R.id.icon);
         PackageManager packageManagerForTargetUser =
                 createContextAsUser(UserHandle.of(targetUserId), /* flags= */ 0)
                         .getPackageManager();
-        icon.setImageDrawable(target.loadIcon(packageManagerForTargetUser));
+
+        ImageView icon = findViewById(R.id.icon);
+        icon.setImageDrawable(
+                getAppIcon(target, launchIntent, targetUserId, packageManagerForTargetUser));
 
         View buttonContainer = findViewById(R.id.button_bar_container);
         buttonContainer.setPadding(0, 0, 0, buttonContainer.getPaddingBottom());
 
         ((TextView) findViewById(R.id.open_cross_profile)).setText(
-                getOpenInWorkMessage(target.loadLabel(packageManagerForTargetUser)));
+                getOpenInWorkMessage(launchIntent, target.loadLabel(packageManagerForTargetUser)));
 
         // The mini-resolver's negative button is reused in this flow to cancel the intent
         ((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, targetUserId);
+            startActivityAsCaller(
+                    launchIntent,
+                    ActivityOptions.makeCustomAnimation(
+                                    getApplicationContext(),
+                                    R.anim.activity_open_enter,
+                                    R.anim.push_down_out)
+                            .toBundle(),
+                    /* ignoreTargetSecurity= */ false,
+                    targetUserId);
             finish();
         });
+
+
+        View telephonyInfo = findViewById(R.id.miniresolver_info_section);
+        DevicePolicyManager devicePolicyManager =
+                getSystemService(DevicePolicyManager.class);
+        // Additional information section is work telephony specific. Therefore, it is only shown
+        // for telephony related intents, when all sim subscriptions are in the work profile.
+        if ((isDialerIntent(launchIntent) || isTextMessageIntent(launchIntent))
+                && devicePolicyManager.getManagedSubscriptionsPolicy().getPolicyType()
+                    == ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS) {
+            telephonyInfo.setVisibility(View.VISIBLE);
+            ((TextView) findViewById(R.id.miniresolver_info_section_text))
+                    .setText(getWorkTelephonyInfoSectionMessage(launchIntent));
+        } else {
+            telephonyInfo.setVisibility(View.GONE);
+        }
     }
 
-    private String getOpenInWorkMessage(CharSequence targetLabel) {
+    private Drawable getAppIcon(
+            ResolveInfo target,
+            Intent launchIntent,
+            int targetUserId,
+            PackageManager packageManagerForTargetUser) {
+        if (isDialerIntent(launchIntent)) {
+            // The icon for the call intent will be a generic phone icon as the target will be
+            // the telecom call handler. From the user's perspective, they are being directed
+            // to the dialer app, so use the icon from that app instead.
+            TelecomManager telecomManager =
+                    getApplicationContext().getSystemService(TelecomManager.class);
+            String defaultDialerPackageName =
+                    telecomManager.getDefaultDialerPackage(UserHandle.of(targetUserId));
+            try {
+                return packageManagerForTargetUser
+                        .getApplicationInfo(defaultDialerPackageName, /* flags= */ 0)
+                        .loadIcon(packageManagerForTargetUser);
+            } catch (PackageManager.NameNotFoundException e) {
+                // Allow to fall-through to the icon from the target if we can't find the default
+                // dialer icon.
+                Slog.w(TAG, "Cannot load icon for default dialer package");
+            }
+        }
+        return target.loadIcon(packageManagerForTargetUser);
+    }
+
+    private int getOpenInWorkButtonString(Intent launchIntent) {
+        if (isDialerIntent(launchIntent)) {
+            return R.string.miniresolver_call;
+        }
+        if (isTextMessageIntent(launchIntent)) {
+            return R.string.miniresolver_switch;
+        }
+        return R.string.whichViewApplicationLabel;
+    }
+
+    private String getOpenInWorkMessage(Intent launchIntent, CharSequence targetLabel) {
+        if (isDialerIntent(launchIntent)) {
+            return getSystemService(DevicePolicyManager.class).getResources().getString(
+                MINIRESOLVER_CALL_FROM_WORK,
+                () -> getString(R.string.miniresolver_call_in_work));
+        }
+        if (isTextMessageIntent(launchIntent)) {
+            return getSystemService(DevicePolicyManager.class).getResources().getString(
+                    MINIRESOLVER_SWITCH_TO_WORK,
+                    () -> getString(R.string.miniresolver_switch_to_work));
+        }
         return getSystemService(DevicePolicyManager.class).getResources().getString(
                 MINIRESOLVER_OPEN_WORK,
                 () -> getString(R.string.miniresolver_open_work, targetLabel),
                 targetLabel);
     }
 
+    private String getWorkTelephonyInfoSectionMessage(Intent launchIntent) {
+        if (isDialerIntent(launchIntent)) {
+            return getSystemService(DevicePolicyManager.class).getResources().getString(
+                MINIRESOLVER_WORK_TELEPHONY_CALL_BLOCKED_INFORMATION,
+                () -> getString(R.string.miniresolver_call_information));
+        }
+        if (isTextMessageIntent(launchIntent)) {
+            return getSystemService(DevicePolicyManager.class).getResources().getString(
+                MINIRESOLVER_WORK_TELEPHONY_TEXT_BLOCKED_INFORMATION,
+                () -> getString(R.string.miniresolver_sms_information));
+        }
+        return "";
+    }
+
+
+
     private String getForwardToPersonalMessage() {
         return getSystemService(DevicePolicyManager.class).getResources().getString(
                 FORWARD_INTENT_TO_PERSONAL,
diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java
index f4b858f..43d263b 100644
--- a/core/java/com/android/internal/app/LocaleStore.java
+++ b/core/java/com/android/internal/app/LocaleStore.java
@@ -32,7 +32,6 @@
 import java.io.Serializable;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -404,8 +403,8 @@
     /**
      * Returns a list of system locale that removes all extensions except for the numbering system.
      */
-    public static List<LocaleInfo> getSystemCurrentLocales() {
-        List<LocaleInfo> localeList = new ArrayList<>();
+    public static Set<LocaleInfo> getSystemCurrentLocales() {
+        Set<LocaleInfo> localeList = new HashSet<>();
         LocaleList systemLangList = LocaleList.getDefault();
         for(int i = 0; i < systemLangList.size(); i++) {
             Locale sysLocale = getLocaleWithOnlyNumberingSystem(systemLangList.get(i));
diff --git a/core/java/com/android/internal/app/SuspendedAppActivity.java b/core/java/com/android/internal/app/SuspendedAppActivity.java
index 0288137..a5e775a 100644
--- a/core/java/com/android/internal/app/SuspendedAppActivity.java
+++ b/core/java/com/android/internal/app/SuspendedAppActivity.java
@@ -24,6 +24,7 @@
 
 import android.Manifest;
 import android.annotation.Nullable;
+import android.app.ActivityOptions;
 import android.app.AlertDialog;
 import android.app.AppGlobals;
 import android.app.KeyguardManager;
@@ -314,8 +315,15 @@
                         sendBroadcastAsUser(reportUnsuspend, UserHandle.of(mUserId));
 
                         if (mOnUnsuspend != null) {
+                            Bundle activityOptions =
+                                    ActivityOptions.makeBasic()
+                                            .setPendingIntentBackgroundActivityStartMode(
+                                                    ActivityOptions
+                                                            .MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+                                            .toBundle();
                             try {
-                                mOnUnsuspend.sendIntent(this, 0, null, null, null);
+                                mOnUnsuspend.sendIntent(this, 0, null, null, null, null,
+                                        activityOptions);
                             } catch (IntentSender.SendIntentException e) {
                                 Slog.e(TAG, "Error while starting intent " + mOnUnsuspend, e);
                             }
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 7ad2a68..8135f9c 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -549,11 +549,6 @@
             "task_manager_inform_job_scheduler_of_pending_app_stop";
 
     /**
-     * (boolean) Whether to show notification volume control slider separate from ring.
-     */
-    public static final String VOLUME_SEPARATE_NOTIFICATION = "volume_separate_notification";
-
-    /**
      * (boolean) Whether widget provider info would be saved to / loaded from system persistence
      * layer as opposed to individual manifests in respective apps.
      */
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 3633d91..2063542 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -1270,6 +1270,15 @@
             @NonNull ApplicationInfo info,
             @Nullable ProcessInfo processInfo,
             @Nullable IPlatformCompat platformCompat) {
+        String appOverride = SystemProperties.get("persist.arm64.memtag.app." + info.packageName);
+        if ("sync".equals(appOverride)) {
+            return MEMORY_TAG_LEVEL_SYNC;
+        } else if ("async".equals(appOverride)) {
+            return MEMORY_TAG_LEVEL_ASYNC;
+        } else if ("off".equals(appOverride)) {
+            return MEMORY_TAG_LEVEL_NONE;
+        }
+
         // Look at the process attribute first.
         if (processInfo != null && processInfo.memtagMode != ApplicationInfo.MEMTAG_DEFAULT) {
             return memtagModeToZygoteMemtagLevel(processInfo.memtagMode);
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index ae58626..d2564fb 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -157,7 +157,7 @@
     */
     void showAuthenticationDialog(in PromptInfo promptInfo, IBiometricSysuiReceiver sysuiReceiver,
             in int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, int userId,
-            long operationId, String opPackageName, long requestId, int multiSensorConfig);
+            long operationId, String opPackageName, long requestId);
     /**
     * Used to notify the authentication dialog that a biometric has been authenticated.
     */
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 3708859..3977666 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -123,8 +123,7 @@
     // Used to show the authentication dialog (Biometrics, Device Credential)
     void showAuthenticationDialog(in PromptInfo promptInfo, IBiometricSysuiReceiver sysuiReceiver,
             in int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
-            int userId, long operationId, String opPackageName, long requestId,
-            int multiSensorConfig);
+            int userId, long operationId, String opPackageName, long requestId);
 
     // Used to notify the authentication dialog that a biometric has been authenticated
     void onBiometricAuthenticated(int modality);
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index f277635..116c301c 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -367,28 +367,42 @@
      * using a single static object.
      */
     @VisibleForTesting
+    @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
     public void startListeningForLatencyTrackerConfigChanges() {
         final Context context = ActivityThread.currentApplication();
-        if (context != null
-                && context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) == PERMISSION_GRANTED) {
-            // Post initialization to the background in case we're running on the main thread.
-            BackgroundThread.getHandler().post(() -> this.updateProperties(
-                    DeviceConfig.getProperties(NAMESPACE_LATENCY_TRACKER)));
-            DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_LATENCY_TRACKER,
-                    BackgroundThread.getExecutor(), mOnPropertiesChangedListener);
-        } else {
+        if (context == null) {
             if (DEBUG) {
-                if (context == null) {
-                    Log.d(TAG, "No application for " + ActivityThread.currentActivityThread());
-                } else {
-                    synchronized (mLock) {
-                        Log.d(TAG, "Initialized the LatencyTracker."
-                                + " (No READ_DEVICE_CONFIG permission to change configs)"
-                                + " enabled=" + mEnabled + ", package=" + context.getPackageName());
-                    }
+                Log.d(TAG, "No application for package: " + ActivityThread.currentPackageName());
+            }
+            return;
+        }
+        if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) != PERMISSION_GRANTED) {
+            if (DEBUG) {
+                synchronized (mLock) {
+                    Log.d(TAG, "Initialized the LatencyTracker."
+                            + " (No READ_DEVICE_CONFIG permission to change configs)"
+                            + " enabled=" + mEnabled + ", package=" + context.getPackageName());
                 }
             }
+            return;
         }
+
+        // Post initialization to the background in case we're running on the main thread.
+        BackgroundThread.getHandler().post(() -> {
+            try {
+                this.updateProperties(
+                        DeviceConfig.getProperties(NAMESPACE_LATENCY_TRACKER));
+                DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_LATENCY_TRACKER,
+                        BackgroundThread.getExecutor(), mOnPropertiesChangedListener);
+            } catch (SecurityException ex) {
+                // In case of running tests that the main thread passes the check,
+                // but the background thread doesn't have necessary permissions.
+                // Swallow it since it's ok to ignore device config changes in the tests.
+                Log.d(TAG, "Can't get properties: READ_DEVICE_CONFIG granted="
+                        + context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG)
+                        + ", package=" + context.getPackageName());
+            }
+        });
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/ImageFloatingTextView.java b/core/java/com/android/internal/widget/ImageFloatingTextView.java
index 2695b9c..1ac5e1f 100644
--- a/core/java/com/android/internal/widget/ImageFloatingTextView.java
+++ b/core/java/com/android/internal/widget/ImageFloatingTextView.java
@@ -82,7 +82,7 @@
                 .setIncludePad(getIncludeFontPadding())
                 .setUseLineSpacingFromFallbacks(true)
                 .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
-                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
+                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL_FAST);
         int maxLines;
         if (mMaxLinesForHeight > 0) {
             maxLines = mMaxLinesForHeight;
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index a554d0e..92cfa67 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -50,7 +50,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageManager;
-import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
@@ -723,15 +722,13 @@
     }
 
     /**
-     * Whether the auto pin feature logic is available or not.
-     * @return true, if deviceConfig flag is set to true or the flag is not propagated and
-     * defaultValue is true.
+     * Whether the auto pin feature is available or not.
+     * @return true. This method is always returning true due to feature flags not working
+     * properly (b/282246482). Ideally, this should check if deviceConfig flag is set to true
+     * and then return the appropriate value.
      */
     public static boolean isAutoPinConfirmFeatureAvailable() {
-        return DeviceConfig.getBoolean(
-                DeviceConfig.NAMESPACE_AUTO_PIN_CONFIRMATION,
-                FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
-                /* defaultValue= */ true);
+        return true;
     }
 
     /** Returns if the given quality maps to an alphabetic password */
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 21bdf09..e5d5676 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -652,9 +652,7 @@
     char saveResolvedClassesDelayMsOptsBuf[
             sizeof("-Xps-save-resolved-classes-delay-ms:")-1 + PROPERTY_VALUE_MAX];
     char profileMinSavePeriodOptsBuf[sizeof("-Xps-min-save-period-ms:")-1 + PROPERTY_VALUE_MAX];
-    char profileMinFirstSaveOptsBuf[
-            sizeof("-Xps-min-first-save-ms:")-1 + PROPERTY_VALUE_MAX];
-    char madviseRandomOptsBuf[sizeof("-XX:MadviseRandomAccess:")-1 + PROPERTY_VALUE_MAX];
+    char profileMinFirstSaveOptsBuf[sizeof("-Xps-min-first-save-ms:") - 1 + PROPERTY_VALUE_MAX];
     char madviseWillNeedFileSizeVdex[
             sizeof("-XMadviseWillNeedVdexFileSize:")-1 + PROPERTY_VALUE_MAX];
     char madviseWillNeedFileSizeOdex[
@@ -866,13 +864,8 @@
                        jitprithreadweightOptBuf,
                        "-Xjitprithreadweight:");
 
-    parseRuntimeOption("dalvik.vm.jittransitionweight",
-                       jittransitionweightOptBuf,
+    parseRuntimeOption("dalvik.vm.jittransitionweight", jittransitionweightOptBuf,
                        "-Xjittransitionweight:");
-    /*
-     * Madvise related options.
-     */
-    parseRuntimeOption("dalvik.vm.madvise-random", madviseRandomOptsBuf, "-XX:MadviseRandomAccess:");
 
     /*
      * Use default platform configuration as limits for madvising,
diff --git a/core/proto/android/companion/telecom.proto b/core/proto/android/companion/telecom.proto
index b90067d..700baa1 100644
--- a/core/proto/android/companion/telecom.proto
+++ b/core/proto/android/companion/telecom.proto
@@ -42,6 +42,9 @@
       ONGOING = 2;
       ON_HOLD = 3;
       RINGING_SILENCED = 4;
+      AUDIO_PROCESSING = 5;
+      RINGING_SIMULATED = 6;
+      DISCONNECTED = 7;
     }
     Status status = 3;
 
@@ -89,8 +92,6 @@
     END = 6;
     PUT_ON_HOLD = 7;
     TAKE_OFF_HOLD = 8;
-    REJECT_AND_BLOCK = 9;
-    IGNORE = 10;
   }
 
   // The list of active calls.
diff --git a/core/proto/android/os/system_properties.proto b/core/proto/android/os/system_properties.proto
index 84c82e0..10f07ac 100644
--- a/core/proto/android/os/system_properties.proto
+++ b/core/proto/android/os/system_properties.proto
@@ -434,9 +434,8 @@
             optional string vibrator = 37;
             optional string virtual_device = 38;
             optional string vulkan = 39;
-            optional string egl_legacy = 40;
 
-            // Next Tag: 41
+            // Next Tag: 40
         }
         optional Hardware hardware = 27;
 
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index 128de8b..052e2f2 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -471,10 +471,6 @@
         optional SettingProto updatable_driver_prerelease_opt_in_apps = 18;
 
         optional SettingProto angle_egl_features = 19;
-        // ANGLE - List of Apps that ANGLE may have issues with
-        optional SettingProto angle_deferlist = 20;
-        // ANGLE - Integer mode of the logic for applying `angle_deferlist`
-        optional SettingProto angle_deferlist_mode = 21;
     }
     optional Gpu gpu = 59;
 
diff --git a/core/proto/android/service/notification.proto b/core/proto/android/service/notification.proto
index f87d910..17ca7c8 100644
--- a/core/proto/android/service/notification.proto
+++ b/core/proto/android/service/notification.proto
@@ -360,3 +360,11 @@
 
     optional ConversationType allow_conversations_from = 19;
 }
+
+// Enum identifying the type of rule that changed; values set to match ones used in the
+// DNDStateChanged proto.
+enum RuleType {
+    RULE_TYPE_UNKNOWN = 0;
+    RULE_TYPE_MANUAL = 1;
+    RULE_TYPE_AUTOMATIC = 2;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index af08e03..2f9f6ae 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -863,6 +863,7 @@
         android:label="@string/permlab_readContacts"
         android:description="@string/permdesc_readContacts"
         android:protectionLevel="dangerous" />
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
 
     <!-- Allows an application to write the user's contacts data.
          <p>Protection level: dangerous
@@ -6039,6 +6040,7 @@
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CALL_PRIVILEGED"
         android:protectionLevel="signature|privileged" />
+    <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
 
     <!-- @SystemApi Allows an application to perform CDMA OTA provisioning @hide -->
     <permission android:name="android.permission.PERFORM_CDMA_PROVISIONING"
@@ -7690,22 +7692,6 @@
                  android:defaultToDeviceProtectedStorage="true"
                  android:forceQueryable="true"
                  android:directBootAware="true">
-        <activity android:name="com.android.internal.app.ChooserActivity"
-                android:theme="@style/Theme.DeviceDefault.Chooser"
-                android:finishOnCloseSystemDialogs="true"
-                android:excludeFromRecents="true"
-                android:documentLaunchMode="never"
-                android:relinquishTaskIdentity="true"
-                android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
-                android:process=":ui"
-                android:exported="true"
-                android:visibleToInstantApps="true">
-            <intent-filter android:priority="100">
-                <action android:name="android.intent.action.CHOOSER" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.VOICE" />
-            </intent-filter>
-        </activity>
         <activity android:name="com.android.internal.accessibility.dialog.AccessibilityShortcutChooserActivity"
                   android:exported="false"
                   android:theme="@style/Theme.DeviceDefault.Dialog.Alert.DayNight"
@@ -8231,7 +8217,7 @@
         </service>
 
         <service android:name="com.android.server.companion.datatransfer.contextsync.CallMetadataSyncConnectionService"
-                 android:permission="android.permission.BIND_CONNECTION_SERVICE"
+                 android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
                  android:exported="true">
             <intent-filter>
                 <action android:name="android.telecom.ConnectionService"/>
diff --git a/core/res/res/layout/autofill_fill_dialog.xml b/core/res/res/layout/autofill_fill_dialog.xml
index 2e65800..d1a4935 100644
--- a/core/res/res/layout/autofill_fill_dialog.xml
+++ b/core/res/res/layout/autofill_fill_dialog.xml
@@ -35,10 +35,10 @@
 
         <ImageView
             android:id="@+id/autofill_service_icon"
-            android:scaleType="fitStart"
+            android:scaleType="fitCenter"
             android:visibility="gone"
-            android:layout_width="@dimen/autofill_dialog_icon_size"
-            android:layout_height="@dimen/autofill_dialog_icon_size"/>
+            android:layout_height="@dimen/autofill_dialog_icon_max_height"
+            android:layout_width="fill_parent"/>
 
         <LinearLayout
             android:id="@+id/autofill_dialog_header"
diff --git a/core/res/res/layout/autofill_save.xml b/core/res/res/layout/autofill_save.xml
index 3c0b789..85529d6 100644
--- a/core/res/res/layout/autofill_save.xml
+++ b/core/res/res/layout/autofill_save.xml
@@ -40,10 +40,10 @@
 
             <ImageView
                 android:id="@+id/autofill_save_icon"
-                android:scaleType="fitStart"
+                android:scaleType="fitCenter"
                 android:layout_gravity="center"
-                android:layout_width="@dimen/autofill_save_icon_size"
-                android:layout_height="@dimen/autofill_save_icon_size"/>
+                android:layout_height="@dimen/autofill_save_icon_max_height"
+                android:layout_width="fill_parent"/>
 
             <TextView
                 android:id="@+id/autofill_save_title"
@@ -60,7 +60,6 @@
                 android:id="@+id/autofill_save_custom_subtitle"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/autofill_save_scroll_view_top_margin"
                 android:visibility="gone"/>
 
         </LinearLayout>
diff --git a/core/res/res/layout/miniresolver.xml b/core/res/res/layout/miniresolver.xml
index 1ad3acd..db0ea54 100644
--- a/core/res/res/layout/miniresolver.xml
+++ b/core/res/res/layout/miniresolver.xml
@@ -63,6 +63,37 @@
             android:textColor="?android:textColorPrimary"
         />
     </RelativeLayout>
+    <!-- Additional information section, currently only shown when redirecting to Telephony apps -->
+    <LinearLayout
+      android:id="@+id/miniresolver_info_section"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:paddingHorizontal="24dp"
+      android:paddingBottom="48dp"
+      android:visibility="gone"
+      android:background="?attr/colorBackground"
+      android:orientation="horizontal">
+
+      <ImageView
+          android:id="@+id/miniresolver_info_section_icon"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:paddingEnd="8dp"
+          android:src="@drawable/ic_info_outline_24"
+          android:tint="?android:textColorSecondary"
+      />
+
+      <TextView
+          android:id="@+id/miniresolver_info_section_text"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:layout_alignParentEnd="true"
+          android:paddingEnd="8dp"
+          android:textSize="14sp"
+          android:textAllCaps="false"
+          android:textColor="?android:textColorSecondary"
+          />
+    </LinearLayout>
 
     <LinearLayout
         android:id="@+id/button_bar_container"
@@ -83,7 +114,7 @@
             android:orientation="horizontal"
             android:layoutDirection="locale"
             android:measureWithLargestChild="true"
-            android:paddingHorizontal="16dp"
+            android:layout_marginHorizontal="24dp"
             android:paddingBottom="2dp"
             android:elevation="@dimen/resolver_elevation">
 
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 7309fd1..33e7ec9 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Verwyder"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Verhoog volume bo aanbevole vlak?\n\nOm lang tydperke teen hoë volume te luister, kan jou gehoor beskadig."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Waarskuwing:\nJy het in ’n week meer kere na harde klankseine deur oorfone geluister as wat veilig is vir jou gehoor.\n\nAs jy oor hierdie limiet gaan, sal dit jou gehoor vir altyd beskadig."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Waarskuwing:\nJy het in ’n week 5 keer meer na harde klankseine deur oorfone geluister as wat veilig is vir jou gehoor.\n\nVolume is verlaag om jou gehoor te beskerm."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Die vlak waarteen jy na media luister, kan tot gehoorskade lei wanneer dit vir lang tydperke volgehou word.\n\nAs jy aanhou om vir lang tydperke so hard te luister, kan jy jou gehoor beskadig."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Waarskuwing:\nJy luister tans na inhoud wat teen ’n onveilige vlak speel.\n\nAs jy aanhou om so hard te luister, sal dit jou gehoor vir altyd beskadig."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Hou aan om teen hoë volume te luister?\n\nOorfoonvolume was langer as wat aanbeveel word hoog, wat jou gehoor kan beskadig"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Harde klank bespeur\n\nOorfoonvolume was hoër as aanbeveel, wat jou gehoor kan beskadig"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gebruik toeganklikheidkortpad?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Wanneer die kortpad aan is, sal \'n toeganklikheidkenmerk begin word as albei volumeknoppies 3 sekondes lank gedruk word."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Skakel kortpad vir toeganklikheidskenmerke aan?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Hervat"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Geen werkprogramme nie"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Geen persoonlike programme nie"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Maak werk-<xliff:g id="APP">%s</xliff:g> oop?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Maak in persoonlike <xliff:g id="APP">%s</xliff:g> oop?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Maak in werk-<xliff:g id="APP">%s</xliff:g> oop?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Bel van werkapp af?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Skakel oor na werkapp?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Jou organisasie laat jou net toe om oproepe van werkapps af te maak"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Jou organisasie laat jou net toe om boodskappe van werkapps af te stuur"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Gebruik persoonlike blaaier"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Gebruik werkblaaier"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Bel"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Skakel oor"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM se netwerkontsluiting-PIN"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM se netwerksubstelontsluiting-PIN"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM se korporatiewe ontsluiting-PIN"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 2788df7..9013708 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"አስወግድ"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ድምጹ ከሚመከረው መጠን በላይ ከፍ ይበል?\n\nበከፍተኛ ድምፅ ለረጅም ጊዜ ማዳመጥ ጆሮዎን ሊጎዳው ይችላል።"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"ማስጠንቀቂያ፣\nእርስዎ አንድ ሰው በአንድ ሳምንት ውስጥ ደህንነቱ በተጠበቀ ሁኔታ በራስ ላይ ማዳመጫዎች መስማት ከሚችላቸው ጮክ ያሉ የድምፅ ምልክቶች መጠንን አልፈዋል።\n\nከዚህ ገደብ በላይ መሄድ የመስማት ችሎታዎን በቋሚነት ይጎዳል።"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"ማስጠንቀቂያ፣\nእርስዎ አንድ ሰው በአንድ ሳምንት ውስጥ ደህንነቱ በተጠበቀ ሁኔታ በራስ ላይ ማዳመጫዎች መስማት ከሚችላቸው ጮክ ያሉ የድምፅ ምልክቶች መጠን 5 እጥፍ አልፈዋል።\n\nየድምፅ መጠን የመስማት ችሎታዎን ለመጠበቅ ዝቅ ተደርጓል።"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"እርስዎ ሚዲያን እያዳመጡ ያሉበት ደረጃ በዘላቂነት ለረጅም ጊዜ ሲቆይ የመስማት ችሎታ ጉዳትን ያስከትላል።\n\nበዚህ ደረጃ ላይ ለረጅም ጊዜ ማጫወት መቀጠል የመስማት ችሎታዎን ሊጎዳ ይችላል።"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"ማስጠንቀቂያ፣\nበአሁኑ ጊዜ እርስዎ ደህንነቱ ባልተጠበቀ ደረጃ ላይ ጮክ ያለ ይዘት እያዳመጡ ነው።\n\nእንደዚህ ጮክ ብሎ ማዳመጥ መቀጠል የመስማት ችሎታዎን በቋሚነት ይጎዳል።"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"በከፍተኛ የድምፅ መጠን ማዳመጥ ይቀጥሉ?\n\nየራስ ላይ ማዳመጫ የድምፅ መጠን ከሚመከረው ጊዜ በላይ ከፍ ብሎ ቆይቷል፣ ይህም የመስሚያ ችሎታዎን ሊጎዳ ይችላል"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"ጮክ ያለ ድምፅ ተለይቷል\n\nየራስ ላይ ማዳመጫ የድምፅ መጠን ከሚመከረው ጊዜ በላይ ከፍ ብሎ ቆይቷል፣ ይህም የመስሚያ ችሎታዎን ሊጎዳ ይችላል"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"የተደራሽነት አቋራጭ ጥቅም ላይ ይዋል?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"አቋራጩ ሲበራ ሁለቱንም የድምጽ አዝራሮች ለ3 ሰከንዶች ተጭኖ መቆየት የተደራሽነት ባህሪን ያስጀምረዋል።"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"የተደራሽነት ባህሪዎች አቋራጭ ይብራ?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"ከቆመበት ቀጥል"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ምንም የሥራ መተግበሪያዎች የሉም"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ምንም የግል መተግበሪያዎች የሉም"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"የሥራ <xliff:g id="APP">%s</xliff:g> ይከፈት?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"በግል <xliff:g id="APP">%s</xliff:g> ውስጥ ይከፈት?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"በሥራ <xliff:g id="APP">%s</xliff:g> ውስጥ ይከፈት?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"ከሥራ መተግበሪያ ይደወል?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ወደ የሥራ መተግበሪያ ይቀየር?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"ድርጅትዎ ከሥራ መተግበሪያዎች ብቻ ጥሪዎችን እንዲያደርጉ ይፈቅድልዎታል"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"ድርጅትዎ ከሥራ መተግበሪያዎች ብቻ መልዕክቶችን እንዲልኩ ይፈቅድልዎታል"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"የግል አሳሽ ተጠቀም"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"የስራ አሳሽ ተጠቀም"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"ደውል"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"ማብሪያ/ማጥፊያ"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"የሲም አውታረ መረብ መክፈቻ ፒን"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"የሲም አውታረ መረብ ንኡስ ስብስብ መክፈቻ ፒን"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"የሲም ኮርፖሬት መክፈቻ ፒን"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index dc2fc6a..bcfdef2 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -629,11 +629,11 @@
     <string name="biometric_error_generic" msgid="6784371929985434439">"خطأ في المصادقة"</string>
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"استخدام قفل الشاشة"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"أدخِل قفل الشاشة للمتابعة"</string>
-    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"اضغط بقوة على المستشعر"</string>
+    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"اضغط بقوة على أداة الاستشعار"</string>
     <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"يتعذّر التعرّف على بصمة الإصبع. يُرجى إعادة المحاولة."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"يُرجى تنظيف مستشعر بصمات الإصبع ثم إعادة المحاولة."</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"تنظيف المستشعر ثم إعادة المحاولة"</string>
-    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"اضغط بقوة على المستشعر"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"اضغط بقوة على أداة الاستشعار"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"تم تحريك الإصبع ببطء شديد. يُرجى إعادة المحاولة."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"يمكنك تجربة بصمة إصبع أخرى."</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"الصورة ساطعة للغاية."</string>
@@ -681,17 +681,17 @@
     <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"لا يمكن استخدام مستشعر بصمات الإصبع"</string>
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"يُرجى التواصل مع مقدِّم خدمات إصلاح."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"يتعذّر إنشاء نموذج الوجه. يُرجى إعادة المحاولة."</string>
-    <string name="face_acquired_too_bright" msgid="8070756048978079164">"ساطع للغاية. تجربة مستوى سطوع أقلّ."</string>
+    <string name="face_acquired_too_bright" msgid="8070756048978079164">"ساطع للغاية. يُرجى تجربة مستوى سطوع أقلّ"</string>
     <string name="face_acquired_too_dark" msgid="8539853432479385326">"الإضاءة غير كافية"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"يُرجى إبعاد الهاتف عنك."</string>
-    <string name="face_acquired_too_far" msgid="2922278214231064859">"يُرجى تقريب الهاتف منك."</string>
+    <string name="face_acquired_too_far" msgid="2922278214231064859">"يُرجى تقريب الهاتف منك"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"يُرجى رفع الهاتف للأعلى"</string>
     <string name="face_acquired_too_low" msgid="4075391872960840081">"يُرجى خفض الهاتف للأسفل"</string>
-    <string name="face_acquired_too_right" msgid="6245286514593540859">"يُرجى تحريك الهاتف جهة اليسار."</string>
+    <string name="face_acquired_too_right" msgid="6245286514593540859">"يُرجى تحريك الهاتف لجهة اليسار"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"يُرجى تحريك الهاتف لجهة اليمين"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"يُرجى النظر إلى جهازك مباشرة أكثر."</string>
     <string name="face_acquired_not_detected" msgid="1057966913397548150">"ارفع هاتفك إلى مستوى العينَين لأنّه تتعذّر رؤية وجهك"</string>
-    <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"حركة أكثر من اللازم يُرجى حمل بدون حركة."</string>
+    <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"حركة أكثر من اللازم. يُرجى حمل الهاتف بثبات."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"يُرجى إعادة تسجيل وجهك."</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"يتعذّر التعرّف على الوجه. يُرجى إعادة المحاولة."</string>
     <string name="face_acquired_too_similar" msgid="8882920552674125694">"غيِّر موضع رأسك قليلاً."</string>
@@ -1686,10 +1686,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"إزالة"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"هل تريد رفع مستوى الصوت فوق المستوى الموصى به؟\n\nقد يضر سماع صوت عالٍ لفترات طويلة بسمعك."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"تحذير:\nلقد تجاوزت مقدار الإشارات الصوتية العالية التي يمكن للشخص الاستماع إليها بأمان خلال أسبوع باستخدام سماعات الرأس.\n\nتجاوز هذا الحدّ سيضر بسمعك بشكل دائم."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"تحذير:\nلقد تجاوزت بمقدار 5 مرات الإشارات الصوتية العالية التي يمكن للشخص الاستماع إليها بأمان خلال أسبوع باستخدام سماعات الرأس.\n\nتم خفض مستوى الصوت لحماية سمعك."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"يمكن أن يؤدي التعرض لفترات طويلة للمستوى الذي تسمع به الوسائط إلى حدوث ضرر في السمع.\n\nقد يؤدي استمرار التشغيل بهذا المستوى لفترات طويلة إلى حدوث ضرر في السمع."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"تحذير:\nأنت تستمع حاليًا إلى محتوى صاخب يتم تشغيله بمستوى صوت غير آمن.\n\nسيؤدي الاستمرار في الاستماع إلى هذا الصوت الصاخب إلى حدوث ضرر في سمعك بشكل دائم."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"هل تريد مواصلة الاستماع بصوت عالٍ؟\n\nكان مستوى صوت سمّاعة الرأس مرتفعًا لمدة أطول مما يُنصَح به، وقد يضر هذا بسمعك."</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"تم رصد صوت مرتفع.\n\nكان مستوى صوت سمّاعة الرأس مرتفعًا لمدة أطول مما يُنصَح به، وقد يضر هذا بسمعك."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"هل تريد استخدام اختصار \"سهولة الاستخدام\"؟"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"عند تفعيل الاختصار، يؤدي الضغط على زرّي التحكّم في مستوى الصوت معًا لمدة 3 ثوانٍ إلى تفعيل إحدى ميزات إمكانية الوصول."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"هل تريد تفعيل الاختصار لميزات إمكانية الوصول؟"</string>
@@ -2168,14 +2166,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"إلغاء الإيقاف المؤقت"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ما مِن تطبيقات عمل."</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ما مِن تطبيقات شخصية."</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"هل تريد فتح تطبيق \"<xliff:g id="APP">%s</xliff:g>\" في الملف الشخصي للعمل؟"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"هل تريد فتح المحتوى في تطبيق \"<xliff:g id="APP">%s</xliff:g>\" في الملف الشخصي؟"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"هل تريد فتح المحتوى في تطبيق \"<xliff:g id="APP">%s</xliff:g>\" في الملف الشخصي للعمل؟"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"هل تريد الاتصال من تطبيق العمل؟"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"هل تريد الانتقال إلى تطبيق العمل؟"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"تسمح لك مؤسستك بإجراء المكالمات من تطبيقات العمل فقط."</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"تسمح لك مؤسستك بإرسال الرسائل من تطبيقات العمل فقط."</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"استخدام المتصفّح الشخصي"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"استخدام متصفّح العمل"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"الاتصال"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"انتقال"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"‏رقم التعريف الشخصي لإلغاء قفل شبكة شريحة SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"‏رقم التعريف الشخصي لإلغاء قفل المجموعة الفرعية لشبكة شريحة SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"‏رقم التعريف الشخصي لإلغاء قفل شريحة SIM للشركات"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 9ec95ea..f8f390a 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"আঁতৰাওক"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"অনুমোদিত স্তৰতকৈ ওপৰলৈ ভলিউম বঢ়াব নেকি?\n\nদীৰ্ঘ সময়ৰ বাবে উচ্চ ভলিউমত শুনাৰ ফলত শ্ৰৱণ ক্ষমতাৰ ক্ষতি হ\'ব পাৰে।"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"সকীয়নি,\nএগৰাকী ব্যক্তিয়ে এসপ্তাহত হেডফ’নৰ জৰিয়তে সুৰক্ষিতভাৱে শুনিব পৰা ডাঙৰ ধ্বনিৰ ছিগনেলৰ পৰিমাণ আপুনি অতিক্ৰম কৰিছে।\n\nএই সীমা অতিক্ৰম কৰাটোৱে আপোনাৰ শ্ৰৱণ শক্তি স্থায়ীভাৱে নষ্ট কৰিব পাৰে।"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"সকীয়নি,\nএগৰাকী ব্যক্তিয়ে এসপ্তাহত হেডফ’নৰ জৰিয়তে সুৰক্ষিতভাৱে শুনিব পৰা ডাঙৰ ধ্বনিৰ ছিগনেলৰ পৰিমাণৰ ৫ গুণ আপুনি অতিক্ৰম কৰিছে।\n\nআপোনাৰ শ্ৰৱণ শক্তি সুৰক্ষিত কৰিবলৈ ভলিউম কমোৱা হৈছে।"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"আপুনি যিটো স্তৰত মিডিয়া শুনি আছে, দীঘলীয়া সময় ধৰি সেইটো স্তৰত শুনি থাকিলে আপোনাৰ শ্ৰৱণ শক্তি নষ্ট হ’ব পাৰে।\n\nএইটো স্তৰত দীঘলীয়া সময়ৰ বাবে প্লে’ কৰি থাকিলে আপোনাৰ শ্ৰৱণ শক্তি নষ্ট হ’ব পাৰে।"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"সকীয়নি,\nআপুনি বৰ্তমান অসুৰক্ষিত স্তৰ এটাত ডাঙৰ ধ্বনিৰ সমল প্লে’ কৰি শুনি আছে।\n\nএই ডাঙৰ ধ্বনিৰ সমলটো শুনি থাকিলে আপোনাৰ শ্ৰৱণ শক্তি নষ্ট হ’ব পাৰে।"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"উচ্চ ভলিউমত শুনি থাকিব নেকি?\n\nহেডফ’নৰ ভলিউম চুপাৰিছ কৰাতকৈ বেছি সময় ধৰি উচ্চ হৈ আছে, যিয়ে আপোনাৰ শ্ৰৱণ ইন্দ্ৰিয় ক্ষতিগ্ৰস্ত কৰিব পাৰে"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"উচ্চ ধ্বনি চিনাক্ত কৰা হৈছে\n\nহেডফ’নৰ ভলিউম চুপাৰিছ কৰাতকৈ বেছি সময় ধৰি উচ্চ হৈ আছে, যিয়ে আপোনাৰ শ্ৰৱণ ইন্দ্ৰিয় ক্ষতিগ্ৰস্ত কৰিব পাৰে"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"দিব্যাংগসকলৰ সুবিধাৰ শ্বৰ্টকাট ব্যৱহাৰ কৰেনে?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"শ্বৰ্টকাটটো অন হৈ থকাৰ সময়ত দুয়োটা ভলিউম বুটাম ৩ ছেকেণ্ডৰ বাবে হেঁচি ধৰি ৰাখিলে এটা সাধ্য সুবিধা আৰম্ভ হ’ব।"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"সাধ্য সুবিধাসমূহৰ বাবে শ্বৰ্টকাট অন কৰিবনে?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"আনপজ কৰক"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"কোনো কৰ্মস্থানৰ এপ্‌ নাই"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"কোনো ব্যক্তিগত এপ্‌ নাই"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"কৰ্মস্থানৰ <xliff:g id="APP">%s</xliff:g>ত খুলিবনে?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"ব্যক্তিগত <xliff:g id="APP">%s</xliff:g>ত খুলিবনে?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"কৰ্মস্থানৰ <xliff:g id="APP">%s</xliff:g>ত খুলিবনে?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"কাম সম্পৰ্কীয় এপৰ পৰা কল কৰিবনে?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ইয়াৰ সলনি কাম সম্পৰ্কীয় এপ্ ব্যৱহাৰ কৰিবনে?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"আপোনাৰ প্ৰতিষ্ঠানে আপোনাক কেৱল কাম সম্পৰ্কীয় এপ্‌সমূহৰ পৰা কল কৰিবলৈ অনুমতি দিয়ে"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"আপোনাৰ প্ৰতিষ্ঠানে আপোনাক কেৱল কাম সম্পৰ্কীয় এপ্‌সমূহৰ পৰা বাৰ্তা পঠিওৱাৰ অনুমতি দিয়ে"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ব্যক্তিগত ব্ৰাউজাৰ ব্যৱহাৰ কৰক"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"কৰ্মস্থানৰ ব্ৰাউজাৰ ব্যৱহাৰ কৰক"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"কল কৰক"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"সলনি কৰক"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"ছিম নেটৱৰ্ক আনলক কৰা পিন"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"ছিম নেটৱৰ্ক আনলক কৰা পিন"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"ছিম কৰ্পৰে\'ট আনলক কৰা পিন"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index f56f333..6e3a1cc 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" - "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Yığışdır"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Səsin həcmi tövsiyə olunan səviyyədən artıq olsun?\n\nYüksək səsi uzun zaman dinləmək eşitmə qabiliyyətinizə zərər vura bilər."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Xəbərdarlıq,\nQulaqlıqlar vasitəsilə bir həftə ərzində güvənli şəkildə dinləyə biləcəyiniz yüksək səs siqnallarının miqdarını keçmisiniz.\n\nBu həddi aşmaq eşitmə qabiliyyətini həmişəlik zədələyəcək."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Xəbərdarlıq,\nQulaqlıqlar vasitəsilə bir həftə ərzində güvənli şəkildə dinləyə biləcəyiniz yüksək səs siqnallarının miqdarını 5 dəfə keçmisiniz.\n\nEşitmə qabiliyyətinizi qorumaq üçün səs səviyyəsi azaldılıb."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Mediaya qulaq asdığınız səviyyə uzun müddət davam etdikdə eşitmə qabuliyyətinin zədələnməsi ilə nəticələnə bilər.\n\nBu səviyyədə uzun müddət oxutmağa davam etmək eşitmə qabiliyyətinizə zərər verə bilər."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Xəbərdarlıq,\nHazırda təhlükəli səviyyədə oxudulan yüksək səsli məzmunu dinləyirsiniz.\n\nBu yüksək səslə dinləməyə davam etmək eşitmə qabiliyyətinizi həmişəlik zədələyəcək."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Yüksək səsdə davam edilsin?\n\nQulaqlığın səsi tövsiyə ediləndən uzun müddət yüksək olub. Eşitmə zədələnə bilər"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Yüksək səs aşkarlandı\n\nQulaqlığın səsi tövsiyə ediləndən yüksək olub. Eşitmə zədələnə bilər"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Əlçatımlılıq Qısayolu istifadə edilsin?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Qısayol aktiv olduqda, hər iki səs düyməsinə 3 saniyə basıb saxlamaqla əlçatımlılıq funksiyası başladılacaq."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Əlçatımlılıq funksiyaları üçün qısayol aktiv edilsin?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Pauzanı bitirin"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"İş tətbiqi yoxdur"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Şəxsi tətbiq yoxdur"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"<xliff:g id="APP">%s</xliff:g> iş profili açılsın?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"<xliff:g id="APP">%s</xliff:g> şəxsi profilində açılsın?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"<xliff:g id="APP">%s</xliff:g> iş profilində açılsın?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"İş tətbiqindən zəng edilsin?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"İş tətbiqinə dəyişilsin?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Təşkilat yalnız iş tətbiqindən zəng etməyə icazə verir"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Təşkilat yalnız iş tətbiqindən mesaj göndərməyə icazə verir"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Şəxsi brauzerdən istifadə edin"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"İş brauzerindən istifadə edin"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Zəng edin"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Dəyişin"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM şəbəkəsi kilidaçma PİN\'i"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM Şəbəkəsi Alt Dəstinin kilidaçma PIN\'i"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM korporativ kilidaçma PIN\'i"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index ffd3f85..f68eab6 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Ukloni"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Želite da pojačate zvuk iznad preporučenog nivoa?\n\nSlušanje glasne muzike duže vreme može da vam ošteti sluh."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Upozorenje,\npremašili ste broj glasnih zvučnih signala koje je bezbedno slušati preko slušalica tokom nedelju dana.\n\nPrekoračenjem tog ograničenja trajno ćete oštetiti sluh."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Upozorenje,\nPet puta ste premašili broj glasnih zvučnih signala koje je bezbedno slušati preko slušalica tokom nedelju dana.\n\nJačina zvuka treba da se smanji da biste zaštitili sluh."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Nivo na kom slušate medijski sadržaj može da dovede do oštećenja sluha ako to traje tokom dužeg perioda.\n\nAko nastavite da slušate tako glasno tokom dužeg perioda, može da dođe do oštećenja sluha."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Upozorenje,\ntrenutno slušate glasan sadržaj na nebezbednom nivou.\n\nAko nastavite da slušate tako glasno, trajno ćete oštetiti sluh."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Želite da nastavite da slušate glasnu muziku?\n\nJačina zvuka u slušalicama je bila visoka duže nego što se preporučuje, što može da ošteti sluh"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Prepoznat je glasan zvuk\n\nJačina zvuka u slušalicama je bila veća nego što se preporučuje, što može da ošteti sluh"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite li da koristite prečicu za pristupačnost?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kada je prečica uključena, pritisnite oba dugmeta za jačinu zvuka da biste pokrenuli funkciju pristupačnosti."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Želite da uključite prečicu za funkcije pristupačnosti?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Ponovo aktiviraj"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nema poslovnih aplikacija"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nema ličnih aplikacija"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Želite da otvorite poslovnu aplikaciju <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Želite da otvorite u ličnoj aplikaciji <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Želite da otvorite u poslovnoj aplikaciji <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Želite da pozovete iz poslovne aplikacije?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Želite da prebacite na poslovnu aplikaciju?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Vaša organizacija dozvoljava pozivanje samo iz poslovnih aplikacija"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Vaša organizacija dozvoljava slanje poruka samo iz poslovnih aplikacija"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Koristi lični pregledač"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Koristi poslovni pregledač"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Pozovi"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Prebaci"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN za otključavanje SIM mreže"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN za otključavanje podskupa SIM mreže"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN za otključavanje poslovne SIM kartice"</string>
@@ -2334,7 +2335,7 @@
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Uređaj <xliff:g id="DEVICE_NAME">%s</xliff:g> je konfigurisan"</string>
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Raspored tastature je podešen na <xliff:g id="LAYOUT_1">%s</xliff:g>. Dodirnite da biste to promenili."</string>
     <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Raspored tastature je podešen na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Dodirnite da biste to promenili."</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Raspored tastature je podešen na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Dodirnite da biste to promenili."</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Raspored tastature je <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Dodirnite da biste to promenili."</string>
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Raspored tastature je podešen na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Dodirnite da biste promenili."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fizičke tastature su konfigurisane"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Dodirnite da biste videli tastature"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index dd065a5..a47c5b9 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1684,10 +1684,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Выдалiць"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Павялiчыць гук вышэй рэкамендаванага ўзроўню?\n\nДоўгае праслухоўванне музыкi на вялiкай гучнасцi можа пашкодзiць ваш слых."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Папярэджанне.\nВы перавысілі колькасць моцных гукаў, якая лічыцца бяспечнай для слухання праз навушнікі на працягу тыдня.\n\nПеравышэнне гэтага значэння можа незваротна пашкодзіць ваш слых."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Папярэджанне.\nВы ў 5 разоў перавысілі колькасць гукаў, якая лічыцца бяспечнай для слухання праз навушнікі на працягу тыдня.\n\nКаб зберагчы ваш слых, гучнасць паменшана."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Выбраны вамі ўзровень гучнасці можа быць шкодным для слыху пры працяглым слуханні мультымедыя.\n\nДоўгае праслухванне на такім узроўні гучнасці можа пашкодзіць ваш слых."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Папярэджанне.\nЗмесціва, якое вы слухаеце, прайграецца на небяспечным узроўні гучнасці.\n\nПрацяг праслухвання на такой гучнасцi незваротна пашкодзiць ваш слых."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Працягнуць праслухоўваць на вялікай гучнасці?\n\nГучнасць у навушніках была вялікай даўжэй, чым рэкамендавана, гэта можа пашкодзіць ваш слых"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Выяўлены моцны гук\n\nГучнасць у навушніках была большай, чым рэкамендавана, гэта можа пашкодзіць ваш слых"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Выкарыстоўваць камбінацыю хуткага доступу для спецыяльных магчымасцей?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Калі хуткі доступ уключаны, вы можаце націснуць абедзве кнопкі гучнасці і ўтрымліваць іх 3 секунды, каб запусціць функцыю спецыяльных магчымасцей."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Уключыць хуткі доступ да спецыяльных магчымасцей?"</string>
@@ -2166,14 +2164,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Уключыць"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Няма працоўных праграм"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Няма асабістых праграм"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Адкрыць працоўную праграму <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Адкрыць у асабістым профілі <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Адкрыць у працоўным профілі <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Зрабіць выклік з працоўнай праграмы?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Пераключыцца на працоўную праграму?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Ваша арганізацыя дазваляе рабіць выклікі толькі з працоўных праграм"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Ваша арганізацыя дазваляе адпраўляць паведамленні толькі з працоўных праграм"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Скарыстаць асабісты браўзер"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Скарыстаць працоўны браўзер"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Выклікаць"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Пераключальнік"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN-код разблакіроўкі сеткі для SIM-карты"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN-код разблакіроўкі падмноства сеткі для SIM-карты"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN-код разблакіроўкі карпаратыўнай SIM-карты"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 6b5ab20..4ed4a66 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Премахване"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Да се увеличи ли силата на звука над препоръчителното ниво?\n\nПродължителното слушане при висока сила на звука може да увреди слуха ви."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Внимание!\nНадвишихте безопасния брой сигнали със силен звук, които човек може да чуе със слушалки в рамките на една седмица.\n\nТова ще увреди слуха ви за постоянно."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Внимание!\nНадвишихте петкратно безопасния брой сигнали със силен звук, които човек може да чуе със слушалки в рамките на една седмица.\n\nСилата на звука бе намалена с цел предпазване на слуха ви."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Силата на звука, с която се възпроизвежда мултимедийно съдържание, може да доведе до увреждане на слуха, ако слушате продължително.\n\nПродължителното слушане при съответната сила на звука може да увреди слуха ви."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Внимание!\nВ момента слушате съдържание, което се възпроизвежда при опасно висока сила на звука.\n\nАко продължите да слушате с толкова силен звук, ще увредите слуха си за постоянно."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Искате да продължите да слушате при високо ниво на силата на звука?\n\nНивото на силата на звука на слушалките е било високо по-дълго, отколкото е препоръчително, което може да увреди слуха ви"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Установен е висок звук\n\nНивото на силата на звука на слушалките е било по-високо, отколкото е препоръчително, което може да увреди слуха ви"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Искате ли да използвате пряк път към функцията за достъпност?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Когато прекият път е включен, можете да стартирате дадена функция за достъпност, като натиснете двата бутона за силата на звука и ги задържите за 3 секунди."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Искате ли да включите прекия път за функциите за достъпност?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Отмяна на паузата"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Няма подходящи служебни приложения"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Няма подходящи лични приложения"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Да се отвори ли <xliff:g id="APP">%s</xliff:g> в служебния потребителски профил?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Да се отвори ли в(ъв) <xliff:g id="APP">%s</xliff:g> в личния потребителски профил?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Да се отвори ли в(ъв) <xliff:g id="APP">%s</xliff:g> в служебния потребителски профил?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Да се извърши ли обаждане от служебното приложение?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Искате ли да превключите към служебното приложение?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Организацията ви разрешава да извършвате обаждания само от служебни приложения"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Организацията ви разрешава да изпращате съобщения само от служебни приложения"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Използване на личния браузър"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Използване на служебния браузър"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Обаждане"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Превключване"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"ПИН за отключване на мрежата за SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"ПИН за отключване на подмножеството от мрежи за SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"ПИН за отключване на корпоративната SIM карта"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 5575f13..82532fb 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1396,7 +1396,7 @@
     <string name="hardware" msgid="1800597768237606953">"ভার্চুয়াল কীবোর্ড দেখুন"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> কনফিগার করুন"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ফিজিক্যাল কীবোর্ড কনফিগার করুন"</string>
-    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ভাষা এবং লেআউট বেছে নিন আলতো চাপ দিন"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ভাষা ও লেআউট বেছে নিতে ট্যাপ করুন"</string>
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"অন্যান্য অ্যাপের উপরে দেখুন"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"সরান"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"প্রস্তাবিত স্তরের চেয়ে বেশি উঁচুতে ভলিউম বাড়াবেন?\n\nউঁচু ভলিউমে বেশি সময় ধরে কিছু শুনলে আপনার শ্রবনশক্তির ক্ষতি হতে পারে।"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"সতর্কতা,\nহেডফোনের মাধ্যমে এক সপ্তাহে কেউ যতটা জোর আওয়াজের সিগন্যাল শুনতে পারেন আপনি তার সীমা পেরিয়ে গেছেন।\n\nএই সীমা পেরিয়ে গেলে আপনার শ্রবণশক্তি স্থায়ীভাবে ক্ষতিগ্রস্ত হবে।"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"সতর্কতা,\nহেডফোনের মাধ্যমে এক সপ্তাহে কেউ যতটা জোর আওয়াজের সিগন্যাল শুনতে পারেন আপনি তার সীমা ৫ গুণ পেরিয়ে গেছেন।\n\nআপনার শ্রবণশক্তি সুরক্ষিত রাখতে ভলিউম কমানো হয়েছে।"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"যে লেভেলে আপনি মিডিয়া শুনছেন তা দীর্ঘ সময় ধরে চলতে থাকলে আপনার শ্রবণশক্তি ক্ষতিগ্রস্ত হতে পারে।\n\nদীর্ঘ সময় ধরে এই লেভেলে প্লে করলে তা আপনার শ্রবণশক্তির ক্ষতি করতে পারে।"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"সতর্কতা,\nআপনি বর্তমানে অসুরক্ষিত জোর লেভেলে প্লে করা হচ্ছে এমন কন্টেন্ট শুনছেন।\n\nএইভাবে জোরে শোনা চালিয়ে গেলে আপনার শ্রবণশক্তি স্থায়ীভাবে ক্ষতিগ্রস্ত হবে।"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"বেশি ভলিউমে শুনতে থাকবেন?\n\nসাজেস্ট করা সময়ের চেয়ে অতিরিক্ত সময় ধরে হেডফোনের ভলিউম বেশি করা আছে, এর ফলে আপনার কানের ক্ষতি হতে পারে"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"তীব্র শব্দ শনাক্ত করা হয়েছে\n\nসাজেস্ট করা মাত্রার চেয়ে হেডফোনের ভলিউম বেশি করা আছে, এর ফলে আপনার কানের ক্ষতি হতে পারে"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"অ্যাক্সেসযোগ্যতা শর্টকাট ব্যবহার করবেন?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"শর্টকাট চালু করা থাকাকালীন দুটি ভলিউম বোতাম একসাথে ৩ সেকেন্ড টিপে ধরে রাখলে একটি অ্যাকসেসিবিলিটি ফিচার চালু হবে।"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"অ্যাক্সেসিবিলিটি ফিচারের শর্টকাট বন্ধ করতে চান?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"আনপজ করুন"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"এর জন্য কোনও অফিস অ্যাপ নেই"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ব্যক্তিগত অ্যাপে দেখা যাবে না"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"অফিসের <xliff:g id="APP">%s</xliff:g> খুলবেন?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"ব্যক্তিগত <xliff:g id="APP">%s</xliff:g>-এ খুলবেন?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"অফিসের <xliff:g id="APP">%s</xliff:g>-এ খুলবেন?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"অফিসের অ্যাপ থেকে কল করবেন?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"অফিসের অ্যাপে পরিবর্তন করবেন?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"আপনার সংস্থা শুধু অফিসের অ্যাপ থেকেই আপনাকে কল করার অনুমতি দেয়"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"আপনার সংস্থা শুধু অফিসের অ্যাপ থেকেই আপনাকে মেসেজ পাঠানোর অনুমতি দেয়"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ব্যক্তিগত ব্রাউজার ব্যবহার করুন"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"অফিস ব্রাউজার ব্যবহার করুন"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"কল করুন"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"পরিবর্তন করুন"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"সিম নেটওয়ার্ক আনলক পিন"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"সিম নেটওয়ার্ক সাবসেট আনলক পিন"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"কর্পোরেট সিম আনলক পিন"</string>
@@ -2334,7 +2335,7 @@
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"কীবোর্ড লেআউট <xliff:g id="LAYOUT_1">%s</xliff:g>-এ সেট করা আছে। পরিবর্তন করতে ট্যাপ করুন।"</string>
     <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"কীবোর্ড লেআউট <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>-এ সেট করা আছে। পরিবর্তন করতে ট্যাপ করুন।"</string>
     <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"কীবোর্ড লেআউট <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>-এ সেট করা আছে। পরিবর্তন করতে ট্যাপ করুন।"</string>
-    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"কীবোর্ড লেআউট <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>-এ সেট করা আছে… পরিবর্তন করতে ট্যাপ করুন।"</string>
+    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"কীবোর্ড লেআউট <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>-এ সেট করা আছে… পালটাতে ট্যাপ করুন।"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ফিজিক্যাল কীবোর্ড কনফিগার করা হয়েছে"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"কীবোর্ড দেখতে ট্যাপ করুন"</string>
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 97727d3..c625a3a 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -687,7 +687,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"Pomjerite telefon ulijevo"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"Pomjerite telefon udesno"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Gledajte direktno u uređaj."</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Ne vidi se lice. Držite telefon u visini očiju."</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Lice se ne vidi. Držite telefon u visini očiju."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Previše pokreta. Držite telefon mirno."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Ponovo registrirajte lice."</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"Nije moguće prepoznati lice. Pokušajte ponovo."</string>
@@ -703,7 +703,7 @@
     <skip />
     <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Nije moguće kreirati model lica. Pokušajte ponovo."</string>
     <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Otkrivene su tamne naočale. Lice se mora u potpunosti vidjeti."</string>
-    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Otkriveno je pokrivalo preko lica. Lice se mora u potpunosti vidjeti."</string>
+    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Lice je pokriveno. Lice se mora potpuno vidjeti."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="5085202213036026288">"Nije moguće potvrditi lice. Hardver nije dostupan."</string>
@@ -1370,7 +1370,7 @@
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Punjenje povezanog uređaja. Dodirnite za više opcija."</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Otkriven je analogni periferni uređaj"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Priključeni uređaj nije kompatibilan s ovim telefonom. Dodirnite da saznate više."</string>
-    <string name="adb_active_notification_title" msgid="408390247354560331">"Otklanjanje grešaka putem USB-a je uspostavljeno"</string>
+    <string name="adb_active_notification_title" msgid="408390247354560331">"Otklanjanje grešaka putem USB-a je povezano"</string>
     <string name="adb_active_notification_message" msgid="5617264033476778211">"Dodirnite da isključite otklanjanje grešaka putem USB-a"</string>
     <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Odaberite da onemogućite otklanjanje grešaka putem USB-a"</string>
     <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Bežično otklanjanje grešaka je povezano"</string>
@@ -1397,7 +1397,7 @@
     <string name="hardware" msgid="1800597768237606953">"Prikaz virtuelne tastature"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurirajte uređaj <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurirajte fizičke tastature"</string>
-    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dodirnite za odabir jezika i rasporeda"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dodirnite da odaberete jezik i raspored"</string>
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Prikazivanje preko drugih aplikacija"</string>
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Ukloni"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Želite li pojačati zvuk iznad preporučenog nivoa?\n\nDužim slušanjem glasnog zvuka možete oštetiti sluh."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Upozorenje,\nprekoračili ste količinu glasnih zvučnih signala koje je moguće sigurno slušati putem slušalica tokom jedne sedmice.\n\nPrekoračenjem tog ograničenja će vam se trajno oštetiti sluh."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Upozorenje,\nprekoračili ste 5 puta veću količinu glasnih zvučnih signala koje je moguće sigurno slušati putem slušalica tokom jedne sedmice.\n\nJačina zvuka je smanjena radi zaštite vašeg sluha."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Nivo jačine na kojem slušate medijski sadržaj može uzrokovati oštećenje sluha ako se održava duži period.\n\nAko nastavite reproducirati na ovom nivou jačine duži period može doći do oštećenja sluha."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Upozorenje,\nTrenutno slušate glasan sadržaj na nivou jačine koji nije siguran.\n\nAko nastavite slušati ovako glasno, trajno će vam se oštetiti sluh."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Nastaviti slušati pri visokoj jačini zvuka?\n\nJačina zvuka slušalica je bila visoka duže od preporučenog, što može oštetiti sluh"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Otkriven je glasan zvuk\n\nJačina zvuka slušalica je bila viša od preporučenog, što može oštetiti sluh"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite li koristiti Prečicu za pristupačnost?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kada je prečica uključena, pritiskom i držanjem oba dugmeta za jačinu zvuka u trajanju od 3 sekunde pokrenut će se funkcija pristupačnosti."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Uključiti prečicu za funkcije pristupačnosti?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Ponovo pokreni"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nema poslovnih aplikacija"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nema ličnih aplikacija"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Otvoriti poslovnu aplikaciju <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Otvoriti u ličnoj aplikaciji <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Otvoriti u poslovnoj aplikaciji <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Pozvati iz poslovne aplikacije?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Prebaciti na poslovnu aplikaciju?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Vaša organizacija vam dozvoljava da upućujete pozive samo iz poslovnih aplikacija"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Vaša organizacija vam dozvoljava da šaljete poruke samo iz poslovnih aplikacija"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Koristi lični preglednik"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Koristi poslovni preglednik"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Pozovi"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Prebaci"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN za otključavanje mreže na SIM-u"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN za otključavanje mrežne podgrupe na SIM-u"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN za otključavanje korporativnog SIM-a"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 0110fa7..4e22a15 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -703,7 +703,7 @@
     <skip />
     <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"No es pot crear el model facial. Torna-ho a provar."</string>
     <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"S\'han detectat ulleres fosques. La cara ha de ser completament visible."</string>
-    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"S\'ha detectat una mascareta. La cara ha de ser completament visible."</string>
+    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"S\'ha detectat una mascareta. La cara ha de veure\'s sencera."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="5085202213036026288">"No es pot verificar la cara. Maquinari no disponible."</string>
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Elimina"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vols apujar el volum per sobre del nivell recomanat?\n\nSi escoltes música a un volum alt durant períodes llargs, pots danyar-te l\'oïda."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Advertiment:\nHas superat la quantitat de senyals sonors forts que una persona pot escoltar de manera segura amb els auriculars en una setmana.\n\nSi superes aquest límit, danyaràs la teva audició permanentment."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Advertiment:\nHas superat 5 vegades la quantitat de senyals sonors forts que una persona pot escoltar de manera segura amb els auriculars en una setmana.\n\nS\'ha abaixat el volum per protegir la teva audició."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"El nivell al qual estàs escoltant contingut multimèdia pot provocar danys auditius si es manté durant períodes llargs.\n\nSi continues reproduint-lo en aquest nivell durant períodes llargs, podria danyar la teva audició."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Advertiment:\nActualment, estàs escoltant i reproduint contingut a un volum alt i a un nivell no segur.\n\nSi continues escoltant-lo amb aquest volum, causarà danys a la teva audició permanentment."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Vols continuar escoltant a un volum elevat?\n\nEl volum dels auriculars ha estat elevat durant més temps del recomanat, i això pot danyar la teva audició"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"S\'ha detectat un so fort\n\nEl volum dels auriculars ha estat elevat durant més temps del recomanat, i això pot danyar la teva audició"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vols fer servir la drecera d\'accessibilitat?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Si la drecera està activada, prem els dos botons de volum durant 3 segons per iniciar una funció d\'accessibilitat."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Vols desactivar la drecera de les funcions d\'accessibilitat?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Reactiva"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Cap aplicació de treball"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Cap aplicació personal"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Vols obrir l\'aplicació <xliff:g id="APP">%s</xliff:g> de treball?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Vols obrir el contingut a l\'aplicació <xliff:g id="APP">%s</xliff:g> personal?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Vols obrir el contingut a l\'aplicació <xliff:g id="APP">%s</xliff:g> de treball?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Vols trucar des de l\'aplicació de treball?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Vols canviar a l\'aplicació de treball?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"La teva organització només et permet fer trucades des d\'aplicacions de treball"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"La teva organització només et permet enviar missatges des d\'aplicacions de treball"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Utilitza el navegador personal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Utilitza el navegador de treball"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Truca"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Canvia"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN de desbloqueig de la xarxa SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN de desbloqueig de subconjunt de la xarxa SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN de desbloqueig de la SIM corporativa"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 3ffc26b..83589c3 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -270,7 +270,7 @@
     <string name="global_action_settings" msgid="4671878836947494217">"Nastavení"</string>
     <string name="global_action_assist" msgid="2517047220311505805">"Asistence"</string>
     <string name="global_action_voice_assist" msgid="6655788068555086695">"Hlas. asistence"</string>
-    <string name="global_action_lockdown" msgid="2475471405907902963">"Zamknuto"</string>
+    <string name="global_action_lockdown" msgid="2475471405907902963">"Zamknout"</string>
     <string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
     <string name="notification_hidden_text" msgid="2835519769868187223">"Nové oznámení"</string>
     <string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Fyzická klávesnice"</string>
@@ -631,7 +631,7 @@
     <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Otisk prstu se nepodařilo rozpoznat. Zkuste to znovu."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Vyčistěte snímač otisků prstů a zkuste to znovu"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Vyčistěte senzor a zkuste to znovu"</string>
-    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pevně zatlačte na snímač"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pevně přitiskněte na snímač"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Pohyb prstem byl příliš pomalý. Zkuste to znovu."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Zkuste jiný otisk prstu"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Je příliš světlo"</string>
@@ -1684,10 +1684,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Odebrat"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Zvýšit hlasitost nad doporučenou úroveň?\n\nDlouhodobý poslech hlasitého zvuku může poškodit sluch."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Varování:\nPřekročili jste týdenní množství hlasitého zvuku, které lze bezpečně poslouchat přes sluchátka.\n\nPřekračování tohoto limitu trvale poškodí váš sluch."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Varování:\nPřekročili jste 5násobek týdenního množství hlasitého zvuku, které lze bezpečně poslouchat přes sluchátka.\n\nKvůli ochraně vašeho sluchu byla snížena hlasitost."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Hlasitost, se kterou posloucháte média, může při dlouhodobém používání vést k poškození sluchu.\n\nPokud budete v přehrávání touto hlasitostí pokračovat dlouhou dobu, může vám to poškodit sluch."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Varování:\nMomentálně posloucháte obsah nebezpečně hlasitě.\n\nPokud budete v poslechu takto hlasitého zvuku pokračovat, trvale vám to poškodí sluch."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Pokračovat v poslechu s vysokou hlasitostí?\n\nVe sluchátkách je nastavena vysoká hlasitost déle, než je doporučeno, což může poškodit sluch"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Byl zjištěn hlasitý zvuk\n\nVe sluchátkách je nastavena vyšší hlasitost, než je doporučeno, což může poškodit sluch"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Použít zkratku přístupnosti?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Když je tato zkratka zapnutá, můžete funkci přístupnosti spustit tím, že na tři sekundy podržíte obě tlačítka hlasitosti."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Zapnout zkratku funkcí pro usnadnění přístupu?"</string>
@@ -2166,14 +2164,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Zrušit pozastavení"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Žádné pracovní aplikace"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Žádné osobní aplikace"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Otevřít pracovní aplikaci <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Otevřít v osobní aplikaci <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Otevřít v pracovní aplikaci <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Volat z pracovní aplikace?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Přepnout na pracovní aplikaci?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Vaše organizace dovoluje volat jen z pracovních aplikací"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Vaše organizace dovoluje odesílat zprávy jen z pracovních aplikací"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Použít osobní prohlížeč"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Použít pracovní prohlížeč"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Volat"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Přepnout"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Kód PIN odblokování sítě pro SIM kartu"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN pro odblokování podskupiny sítí pro SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Kód PIN odblokování podnikové sítě pro SIM kartu"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 3c3737e..c845e72 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Fjern"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vil du skrue højere op end det anbefalede lydstyrkeniveau?\n\nDu kan skade hørelsen ved at lytte til meget høj musik over længere tid."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Advarsel!\nDu har overskredet den mængde af høje lydsignaler, det er forsvarligt at lytte til over en periode på en uge i dine høretelefoner.\n\nNår du overstiger denne grænse, tager din hørelse permanent skade."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Advarsel!\nDu har 5 gange overskredet den mængde af høje lydsignaler, det er forsvarligt at lytte til over en periode på en uge i dine høretelefoner.\n\nLydstyrken er blevet sænket for at beskytte din hørelse."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Den lydstyrke, du hører medier på, kan medføre høreskader over tid.\n\nHvis du fortsætter med at afspille medier ved så høj lydstyrke over længere tid, kan din hørelse tage skade."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"ADvarsel!\nDu lytter i øjeblikket til indhold, der afspilles ved så høj en lydstyrke, at det kan gå ud over din hørelse.\n\nHvis du fortsætter med at afspille indhold ved så høj lydstyrke, vil din hørelse tage skade."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Vil du fortsætte med at lytte ved høj lydstyrke?\n\nHøretelefonernes lydstyrke har været høj i længere tid end anbefalet, hvilket kan skade din hørelse"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Der er registreret høj lyd\n\nHøretelefonernes lydstyrke har været højere end anbefalet, hvilket kan skade din hørelse"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vil du bruge genvejen til Hjælpefunktioner?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Når genvejen er aktiveret, kan du starte en hjælpefunktion ved at trykke på begge lydstyrkeknapper i tre sekunder."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Vil du aktivere genvejen til hjælpefunktioner?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Genoptag"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Der er ingen arbejdsapps"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Der er ingen personlige apps"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Vil du åbne <xliff:g id="APP">%s</xliff:g> (arbejde)?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Vil du åbne indholdet via <xliff:g id="APP">%s</xliff:g> (personlig)?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Vil du åbne indholdet via <xliff:g id="APP">%s</xliff:g> (arbejde)?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Vil du foretage et opkald via en arbejdsapp?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Vil du skifte til en arbejdsapp?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Din organisation tillader kun, at du foretager opkald via arbejdsapps"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Din organisation tillader kun, at du sender beskeder via arbejdsapps"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Brug personlig browser"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Brug arbejdsbrowser"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Ring op"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Skift"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Pinkode til oplåsning af SIM-netværket"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Pinkode til oplåsning af delmængde for SIM-netværket"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Pinkode til oplåsning af virksomhedens SIM"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 4899ed4..8576cb7 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1370,7 +1370,7 @@
     <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Analoges Audiozubehör erkannt"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Das angeschlossene Gerät ist nicht mit diesem Smartphone kompatibel. Für weitere Informationen tippen."</string>
     <string name="adb_active_notification_title" msgid="408390247354560331">"USB-Debugging aktiviert"</string>
-    <string name="adb_active_notification_message" msgid="5617264033476778211">"Zum Deaktivieren von USB-Debugging tippen"</string>
+    <string name="adb_active_notification_message" msgid="5617264033476778211">"Zum Deaktivieren tippen"</string>
     <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB-Debugging deaktivieren: auswählen"</string>
     <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"\"Debugging über WLAN\" verbunden"</string>
     <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Tippen, um \"Debugging über WLAN\" zu deaktivieren"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Entfernen"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Lautstärke über den Schwellenwert anheben?\n\nWenn du über einen längeren Zeitraum Musik in hoher Lautstärke hörst, kann dies dein Gehör schädigen."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Warnung:\nDu hast den wöchentlichen Schwellenwert für laute Geräusche, die ohne Gesundheitsrisiko über Kopfhörer angehört werden können, überschritten.\n\nDies kann zu dauerhaften Hörschäden führen."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Warnung:\nDu hast den wöchentlichen Schwellenwert für laute Geräusche, die ohne Gesundheitsrisiko über Kopfhörer angehört werden können, 5-fach überschritten.\n\n Die Lautstärke wurde verringert, um Hörschäden zu vermeiden."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Die Lautstärke, mit der du dir Medien anhörst, kann über lange Zeiträume hinweg Hörschäden verursachen.\n\nWenn du dir weiterhin Medien bei dieser Lautstärke über lange Zeiträume hinweg anhörst, kann dies zu dauerhaften Hörschäden führen."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Warnung:\nDu überschreitest momentan den Schwellenwert für laute Geräusche, die ohne Gesundheitsrisiko über Kopfhörer angehört werden können.\n\nWenn du dir weiterhin Medien bei dieser Lautstärke anhörst, kann dies zu dauerhaften Hörschäden führen."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Weiter mit hoher Lautstärke hören?\n\nDu hast deine Kopfhörer länger als empfohlen mit einer hohen Lautstärke betrieben. Das kann deinem Hörvermögen schaden"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Lautes Geräusch erkannt\n\nDu hast deine Kopfhörer lauter als empfohlen eingestellt. Das kann deinem Hörvermögen schaden"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Verknüpfung für Bedienungshilfen verwenden?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Wenn die Verknüpfung aktiviert ist, kannst du die beiden Lautstärketasten drei Sekunden lang gedrückt halten, um eine Bedienungshilfe zu starten."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Verknüpfung für Bedienungshilfen aktivieren?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Nicht mehr pausieren"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Keine geschäftlichen Apps"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Keine privaten Apps"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Geschäftliche <xliff:g id="APP">%s</xliff:g>-Instanz öffnen?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"In der privaten <xliff:g id="APP">%s</xliff:g>-Instanz öffnen?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"In der geschäftlichen <xliff:g id="APP">%s</xliff:g>-Instanz öffnen?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Über geschäftliche App anrufen?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Zu geschäftlicher App wechseln?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Deine Organisation lässt das Telefonieren nur über geschäftliche Apps zu"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Deine Organisation lässt das Senden von Nachrichten nur über geschäftliche Apps zu"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Privaten Browser verwenden"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Arbeitsbrowser verwenden"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Anrufen"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Wechseln"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Entsperr-PIN für netzgebundenes Gerät"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Entsperr-PIN für subnetzgebundenes Gerät"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Entsperr-PIN für unternehmensgebundenes Gerät"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 6986b8a..a39e988 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Κατάργηση"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Αυξάνετε την ένταση ήχου πάνω από το επίπεδο ασφαλείας;\n\nΑν ακούτε μουσική σε υψηλή ένταση για μεγάλο χρονικό διάστημα ενδέχεται να προκληθεί βλάβη στην ακοή σας."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Προειδοποίηση,\nΈχετε υπερβεί τον μέγιστο αριθμό ηχητικών σημάτων σε υψηλή ένταση που ένα άτομο μπορεί να ακούσει με ασφάλεια σε μία εβδομάδα με ακουστικά.\n\nΑν υπερβείτε αυτό το όριο, θα προκαλέσετε μόνιμη βλάβη στην ακοή σας."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Προειδοποίηση,\nΈχετε υπερβεί κατά 5 φορές τον μέγιστο αριθμό δυνατών ηχητικών σημάτων που ένα άτομο μπορεί να ακούσει με ασφάλεια σε μία εβδομάδα με ακουστικά.\n\nΗ ένταση χαμηλώθηκε για την προστασία της ακοής σας."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Η ένταση ήχου που επιλέγετε για την ακρόαση πολυμέσων μπορεί να προκαλέσει βλάβη στην ακοή σας όταν παρατείνεται για μεγάλα χρονικά διαστήματα.\n\nΑν συνεχίσετε την αναπαραγωγή σε αυτήν την ένταση, μπορεί να προκληθεί βλάβη στην ακοή σας."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Προειδοποίηση,\nΑκούτε περιεχόμενο σε υψηλή, μη ασφαλή ένταση.\n\nΑν συνεχίσετε με αυτήν την υψηλή ένταση, μπορεί να προκληθεί βλάβη στην ακοή σας."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Θέλετε να συνεχίσετε να ακούτε σε υψηλή ένταση ήχου;\n\nΗ ένταση ήχου των ακουστικών ήταν σε υψηλό επίπεδο για μεγαλύτερο διάστημα από αυτό που συνιστάται, κάτι που μπορεί να προκαλέσει ζημιά στην ακοή σας"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Ανιχνεύτηκε δυνατός ήχος\n\nΗ ένταση ήχου των ακουστικών ήταν σε υψηλό επίπεδο για μεγαλύτερο διάστημα από αυτό που συνιστάται, κάτι που μπορεί να προκαλέσει ζημιά στην ακοή σας"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Να χρησιμοποιείται η συντόμευση προσβασιμότητας;"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Όταν η συντόμευση είναι ενεργοποιημένη, το πάτημα και των δύο κουμπιών έντασης ήχου για 3 δευτερόλεπτα θα ξεκινήσει μια λειτουργία προσβασιμότητας."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Ενεργοποίηση συντόμευσης για λειτουργίες προσβασιμότητας;"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Αναίρεση παύσης"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Δεν υπάρχουν εφαρμογές εργασιών"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Δεν υπάρχουν προσωπικές εφαρμογές"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Άνοιγμα <xliff:g id="APP">%s</xliff:g> εργασίας;"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Άνοιγμα στο προσωπικό <xliff:g id="APP">%s</xliff:g>;"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Άνοιγμα στο <xliff:g id="APP">%s</xliff:g> εργασίας;"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Κλήση από εφαρμογή εργασιών;"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Εναλλαγή σε εφαρμογή εργασιών;"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Ο οργανισμός σας επιτρέπει την πραγματοποίηση κλήσεων μόνο από εφαρμογές εργασιών"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Ο οργανισμός σας επιτρέπει την αποστολή μηνυμάτων μόνο από εφαρμογές εργασιών"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Χρήση προσωπικού προγράμματος περιήγησης"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Χρήση προγράμματος περιήγησης εργασίας"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Κλήση"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Εναλλαγή"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN ξεκλειδώματος δικτύου κάρτας SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN ξεκλειδώματος υποσυνόλου δικτύου κάρτας SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN ξεκλειδώματος εταιρικής SIM"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index b055818..b43dfb9 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Remove"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Warning,\nYou have exceeded the amount of loud sound signals one can safely listen to in a week over headphones.\n\nGoing over this limit will permanently damage your hearing."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Warning,\nYou have exceeded five times the amount of loud sound signals one can safely listen to in a week over headphones.\n\nVolume has been lowered to protect your hearing."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"The level at which you are listening to media can result in hearing damage when sustained over long periods of time.\n\nContinuing to play at this level for long periods of time could damage your hearing."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Warning,\nYou are currently listening to loud content played at an unsafe level.\n\nContinuing to listen this loud will permanently damage your hearing."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Keep listening at a high volume?\n\nHeadphone volume has been high for longer than recommended, which can damage your hearing"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Loud sound detected\n\nHeadphone volume has been higher than recommended, which can damage your hearing"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"When the shortcut is on, pressing both volume buttons for three seconds will start an accessibility feature."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Turn on shortcut for accessibility features?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Unpause"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"No work apps"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"No personal apps"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Open work <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Open in personal <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Open in work <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Call from work app?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Switch to work app?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Your organisation only allows you to make calls from work apps"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Your organisation only allows you to send messages from work apps"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Use personal browser"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Use work browser"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Call"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Switch"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM network unlock PIN"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM network subset unlock PIN"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM corporate unlock PIN"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index b12e3ec..13b1c93 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Remove"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Warning,\nYou have exceeded the amount of loud sound signals one can safely listen to in a week over headphones.\n\nGoing over this limit will permanently damage your hearing."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Warning,\nYou have exceeded 5 times the amount of loud sound signals one can safely listen to in a week over headphones.\n\nVolume has been lowered to protect your hearing."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"The level at which you are listening to media can result in hearing damage when sustained over long periods of time.\n\nContinuing to play at this level for long periods of time could damage your hearing."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Warning,\nYou are currently listening to loud content played at an unsafe level.\n\nContinuing to listen this loud will permanently damage your hearing."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Keep listening at a high volume?\n\nHeadphone volume has been high for longer than recommended, which can damage your hearing"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Loud sound detected\n\nHeadphone volume has been higher than recommended, which can damage your hearing"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Turn on shortcut for accessibility features?"</string>
@@ -2167,8 +2165,14 @@
     <string name="miniresolver_open_work" msgid="6286176185835401931">"Open work <xliff:g id="APP">%s</xliff:g>?"</string>
     <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Open in personal <xliff:g id="APP">%s</xliff:g>?"</string>
     <string name="miniresolver_open_in_work" msgid="941341494673509916">"Open in work <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Call from work app?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Switch to work app?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Your organization only allows you to make calls from work apps"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Your organization only allows you to send messages from work apps"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Use personal browser"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Use work browser"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Call"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Switch"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM network unlock PIN"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM network subset unlock PIN"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM corporate unlock PIN"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index aacc433..623f829 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Remove"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Warning,\nYou have exceeded the amount of loud sound signals one can safely listen to in a week over headphones.\n\nGoing over this limit will permanently damage your hearing."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Warning,\nYou have exceeded five times the amount of loud sound signals one can safely listen to in a week over headphones.\n\nVolume has been lowered to protect your hearing."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"The level at which you are listening to media can result in hearing damage when sustained over long periods of time.\n\nContinuing to play at this level for long periods of time could damage your hearing."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Warning,\nYou are currently listening to loud content played at an unsafe level.\n\nContinuing to listen this loud will permanently damage your hearing."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Keep listening at a high volume?\n\nHeadphone volume has been high for longer than recommended, which can damage your hearing"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Loud sound detected\n\nHeadphone volume has been higher than recommended, which can damage your hearing"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"When the shortcut is on, pressing both volume buttons for three seconds will start an accessibility feature."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Turn on shortcut for accessibility features?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Unpause"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"No work apps"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"No personal apps"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Open work <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Open in personal <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Open in work <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Call from work app?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Switch to work app?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Your organisation only allows you to make calls from work apps"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Your organisation only allows you to send messages from work apps"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Use personal browser"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Use work browser"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Call"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Switch"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM network unlock PIN"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM network subset unlock PIN"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM corporate unlock PIN"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 2b1d575..e79afd5 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Remove"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Raise volume above recommended level?\n\nListening at high volume for long periods may damage your hearing."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Warning,\nYou have exceeded the amount of loud sound signals one can safely listen to in a week over headphones.\n\nGoing over this limit will permanently damage your hearing."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Warning,\nYou have exceeded five times the amount of loud sound signals one can safely listen to in a week over headphones.\n\nVolume has been lowered to protect your hearing."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"The level at which you are listening to media can result in hearing damage when sustained over long periods of time.\n\nContinuing to play at this level for long periods of time could damage your hearing."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Warning,\nYou are currently listening to loud content played at an unsafe level.\n\nContinuing to listen this loud will permanently damage your hearing."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Keep listening at a high volume?\n\nHeadphone volume has been high for longer than recommended, which can damage your hearing"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Loud sound detected\n\nHeadphone volume has been higher than recommended, which can damage your hearing"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Use Accessibility Shortcut?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"When the shortcut is on, pressing both volume buttons for three seconds will start an accessibility feature."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Turn on shortcut for accessibility features?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Unpause"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"No work apps"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"No personal apps"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Open work <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Open in personal <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Open in work <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Call from work app?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Switch to work app?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Your organisation only allows you to make calls from work apps"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Your organisation only allows you to send messages from work apps"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Use personal browser"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Use work browser"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Call"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Switch"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM network unlock PIN"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM network subset unlock PIN"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM corporate unlock PIN"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 6ceb03b..a908198 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‎‎‏‎‎ — ‎‏‎‎‏‎ "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‎Remove‎‏‎‎‏‎"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎Raise volume above recommended level?‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Listening at high volume for long periods may damage your hearing.‎‏‎‎‏‎"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‎‏‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‎‎‎Warning,‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎You have exceeded the amount of loud sound signals one can safely listen to in a week over headphones.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Going over this limit will permanently damage your hearing.‎‏‎‎‏‎"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‎‎‎‏‎‎‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‏‏‎‏‏‏‏‏‎‎‏‎Warning,‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎You have exceeded 5 times the amount of loud sound signals one can safely listen to in a week over headphones.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Volume has been lowered to protect your hearing.‎‏‎‎‏‎"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎The level at which you are listening to media can result in hearing damage when sustained over long periods of time.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Continuing to play at this level for long periods of time could damage your hearing.‎‏‎‎‏‎"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‎‎Warning,‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎You are currently listening to loud content played at an unsafe level.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Continuing to listen this loud will permanently damage your hearing.‎‏‎‎‏‎"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎Keep listening at a high volume?‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Headphone volume has been high for longer than recommended, which can damage your hearing‎‏‎‎‏‎"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‎Loud sound detected‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Headphone volume has been higher than recommended, which can damage your hearing‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‎‏‎Use Accessibility Shortcut?‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎‏‎‎‎‎When the shortcut is on, pressing both volume buttons for 3 seconds will start an accessibility feature.‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎Turn on shortcut for accessibility features?‎‏‎‎‏‎"</string>
@@ -2167,8 +2165,14 @@
     <string name="miniresolver_open_work" msgid="6286176185835401931">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎Open work ‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
     <string name="miniresolver_open_in_personal" msgid="807427577794490375">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‏‎‏‏‎‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎Open in personal ‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
     <string name="miniresolver_open_in_work" msgid="941341494673509916">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‎‏‎‎‏‎‏‏‎‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‎‎‎Open in work ‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‏‏‏‎Call from work app?‎‏‎‎‏‎"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎Switch to work app?‎‏‎‎‏‎"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎‏‎‎‎‏‎‎‏‏‎Your organization only allows you to make calls from work apps‎‏‎‎‏‎"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎Your organization only allows you to send messages from work apps‎‏‎‎‏‎"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‎‎‎Use personal browser‎‏‎‎‏‎"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‎‎Use work browser‎‏‎‎‏‎"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‏‎‏‎Call‎‏‎‎‏‎"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎Switch‎‏‎‎‏‎"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‏‎‏‏‎‏‎‎‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‎‏‏‎SIM network unlock PIN‎‏‎‎‏‎"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎‎‎‎‎‎‎‏‎‏‏‎‎SIM network subset unlock PIN‎‏‎‎‏‎"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‏‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎‎SIM corporate unlock PIN‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index e0eb7cc..433ba38 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -636,7 +636,7 @@
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Demasiada luz"</string>
     <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Se detectó una presión del botón de encendido"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Prueba ajustarla"</string>
-    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia un poco la posición del dedo cada vez"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia ligeramente la posición del dedo cada vez"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_error_not_match" msgid="4599441812893438961">"No se reconoció la huella dactilar"</string>
@@ -703,7 +703,7 @@
     <skip />
     <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"No se puede crear modelo de rostro. Vuelve a intentarlo."</string>
     <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Se detectaron lentes oscuros. Tu rostro debe verse completamente."</string>
-    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Llevas mascarilla. Tu rostro debe verse completamente."</string>
+    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Llevas mascarilla. Se debe ver todo tu rostro."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="5085202213036026288">"No se verificó el rostro. Hardware no disponible."</string>
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Eliminar"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"¿Quieres subir el volumen por encima del nivel recomendado?\n\nEscuchar a un alto volumen durante largos períodos puede dañar tu audición."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Advertencia:\nSuperaste la cantidad de señales sonoras fuertes que se pueden escuchar con auriculares de forma segura a lo largo de una semana.\n\nExceder ese límite dañará tu audición de forma permanente."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Advertencia:\nSuperaste 5 veces la cantidad de señales sonoras fuertes que se pueden escuchar con auriculares de forma segura a lo largo de una semana.\n\nSe bajó el volumen para proteger tu audición."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"El volumen al que estás escuchando contenido multimedia puede provocar daños auditivos si se mantiene durante períodos prolongados.\n\nSeguir reproduciendo audio a este volumen durante largos períodos podría dañar tu audición."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Advertencia:\nEstás escuchando contenido a un volumen peligrosamente alto.\n\nSeguir reproduciendo audio a este volumen dañará tu audición de forma permanente."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"¿Quieres seguir escuchando a un volumen alto?\n\nEl volumen de los auriculares se mantuvo elevado por más tiempo del recomendado, lo que te podría dañar la audición"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Se detectaron sonidos fuertes\n\nEl volumen de los auriculares se mantuvo más alto de lo recomendado, lo que te podría dañar la audición"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"¿Usar acceso directo de accesibilidad?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Cuando la combinación de teclas está activada, puedes presionar los botones de volumen durante 3 segundos para iniciar una función de accesibilidad."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"¿Quieres activar la combinación de teclas para las funciones de accesibilidad?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Reanudar"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"El contenido no es compatible con apps de trabajo"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"El contenido no es compatible con apps personales"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"¿Quieres abrir <xliff:g id="APP">%s</xliff:g> de trabajo?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"¿Quieres abrir <xliff:g id="APP">%s</xliff:g> en tu perfil personal?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"¿Quieres abrir <xliff:g id="APP">%s</xliff:g> en tu perfil de trabajo?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"¿Quieres llamar desde la app de trabajo?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"¿Quieres cambiar a una app de trabajo?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Tu organización solo te permite realizar llamadas desde apps de trabajo"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Tu organización solo te permite enviar mensajes desde apps de trabajo"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usar un navegador personal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usar un navegador de trabajo"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Llamar"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Cambiar"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN de desbloqueo del dispositivo para la red de tarjeta SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN de desbloqueo del dispositivo para el subconjunto de redes de tarjeta SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN de desbloqueo corporativo del dispositivo para tarjeta SIM"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 924be83..03a12a0 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -702,8 +702,8 @@
     <!-- no translation found for face_acquired_mouth_covering_detected (8219428572168642593) -->
     <skip />
     <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"No se puede crear tu modelo. Inténtalo de nuevo."</string>
-    <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Gafas oscuras detectadas. Tu cara se debe poder ver por completo."</string>
-    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Mascarilla detectada. Tu cara se debe poder ver por completo."</string>
+    <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Gafas oscuras detectadas. Tu cara se debe poder ver entera."</string>
+    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Mascarilla detectada. Tu cara se debe poder ver entera."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="5085202213036026288">"No se puede verificar. Hardware no disponible."</string>
@@ -1371,7 +1371,7 @@
     <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Se ha detectado un accesorio de audio analógico"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"El dispositivo adjunto no es compatible con este teléfono. Toca para obtener más información."</string>
     <string name="adb_active_notification_title" msgid="408390247354560331">"Depuración por USB activa"</string>
-    <string name="adb_active_notification_message" msgid="5617264033476778211">"Toca para desactivar la depuración por USB"</string>
+    <string name="adb_active_notification_message" msgid="5617264033476778211">"Tocar para desactivar depuración USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Seleccionar para inhabilitar la depuración por USB"</string>
     <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Depuración inalámbrica conectada"</string>
     <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Toca para desactivar la depuración inalámbrica"</string>
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Quitar"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"¿Quieres subir el volumen por encima del nivel recomendado?\n\nEscuchar sonidos fuertes durante mucho tiempo puede dañar los oídos."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Atención:\nHas superado la cantidad de señales acústicas elevadas que se considera seguro escuchar en una semana a través de auriculares.\n\nSuperar este límite dañará tu audición de forma permanente."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Atención:\nHas superado cinco veces la cantidad de señales acústicas elevadas que se considera seguro escuchar en una semana a través de auriculares.\n\nSe ha bajado el volumen para proteger tu audición."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"El volumen al que estás escuchando contenido multimedia puede provocar daños de audición si se mantiene durante un periodo prolongado.\n\nSi sigues reproduciendo audio a este volumen durante largos periodos, puede que perjudique tu audición."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Atención:\nEstás escuchando contenido a un volumen no seguro.\n\nSi sigues escuchando audio tan alto, tu audición se dañará de forma permanente."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"¿Seguir escuchando a un volumen alto?\n\nEl volumen de los auriculares ha estado alto durante más tiempo del recomendado, lo que puede dañar tu audición"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Sonido alto detectado\n\nEl volumen de los auriculares está más alto de lo recomendado, lo que puede dañar tu audición"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"¿Utilizar acceso directo de accesibilidad?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Si el acceso directo está activado, pulsa los dos botones de volumen durante 3 segundos para iniciar una función de accesibilidad."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"¿Quieres activar el acceso directo a las funciones de accesibilidad?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Reactivar"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Ninguna aplicación de trabajo"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Ninguna aplicación personal"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"¿Abrir <xliff:g id="APP">%s</xliff:g> de trabajo?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"¿Abrir en <xliff:g id="APP">%s</xliff:g> personal?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"¿Abrir en <xliff:g id="APP">%s</xliff:g> de trabajo?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"¿Llamar desde una aplicación de trabajo?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"¿Cambiar a una aplicación de trabajo?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Tu organización solo te permite hacer llamadas desde aplicaciones de trabajo"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Tu organización solo te permite enviar mensajes desde aplicaciones de trabajo"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usar navegador personal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usar navegador de trabajo"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Llamar"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Cambiar"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN de desbloqueo de red de tarjeta SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN de desbloqueo de subconjunto de red SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN de desbloqueo corporativo de SIM"</string>
@@ -2331,7 +2332,7 @@
     <string name="concurrent_display_notification_power_save_content" msgid="2198116070583851493">"Dual Screen no está disponible porque la función Ahorro de batería está activada. Puedes desactivarla en Ajustes."</string>
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"Ir a Ajustes"</string>
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desactivar"</string>
-    <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Se ha configurado <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+    <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> configurado"</string>
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Diseño del teclado definido como <xliff:g id="LAYOUT_1">%s</xliff:g>. Toca para cambiarlo."</string>
     <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Diseño del teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g> y <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Toca para cambiarlo."</string>
     <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Diseño del teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> y <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Toca para cambiarlo."</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index a5ab4f2..0328a05 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Eemalda"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Kas suurendada helitugevuse taset üle soovitatud taseme?\n\nPikaajaline valju helitugevusega kuulamine võib kuulmist kahjustada."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Hoiatus!\nOlete ületanud valjude helisignaalide hulga, mida inimene tohib nädala jooksul kõrvaklappidega kuulata.\n\nSeda limiiti ületades kahjustate püsivalt oma kuulmist."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Hoiatus!\nOlete viiekordselt ületanud valjude helisignaalide hulka, mida inimene tohib nädala jooksul kõrvaklappidega kuulata.\n\nHelitugevust on vähendatud, et teie kuulmist kaitsta."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Helitugevuse tase, millega meediat kuulate, võib kahjustada teie kuulmist, kui sellisel tasemel pikema aja vältel kuulate.\n\nSellisel tasemel pikema aja vältel kuulamise jätkamisel võite kahjustada oma kuulmist."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Hoiatus!\nKuulate praegu valjut sisu ohtlikul tasemel.\n\nNii valjusti kuulamise jätkamisel kahjustate jäädavalt oma kuulmist."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Kas jätkata suure helitugevusega kuulamist?\n\nKõrvaklappide helitugevus on olnud suur soovitatavast ajast kauem ja see võib kahjustada teie kuulmist."</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Tuvastatud on vali heli\n\nKõrvaklappide helitugevus on olnud soovitatavast suurem ja see võib kahjustada teie kuulmist."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Kas kasutada juurdepääsetavuse otseteed?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kui otsetee on sisse lülitatud, käivitab mõlema helitugevuse nupu kolm sekundit all hoidmine juurdepääsetavuse funktsiooni."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Kas lülitada juurdepääsufunktsioonide otsetee sisse?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Jätka"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Töörakendusi pole"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Isiklikke rakendusi pole"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Kas avada töörakendus <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Kas avada isiklikus rakenduses <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Kas avada töörakenduses <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Kas helistada töörakendusest?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Kas lülituda töörakendusele?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Teie organisatsioon lubab helistada ainult töörakendustest"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Teie organisatsioon lubab sõnumeid saata ainult töörakendustest."</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Kasuta isiklikku brauserit"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Kasuta tööbrauserit"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Helistage"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Lülitu"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM-kaardi võrgu avamise PIN-kood"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM-kaardi võrgu alamhulga avamise PIN-kood"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM-kaardi ettevõtte avamise PIN-kood"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 1a5dd50..1fd274f 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -459,7 +459,7 @@
     <string name="permdesc_readCallLog" msgid="8964770895425873433">"Aplikazioak deien historia irakur dezake."</string>
     <string name="permlab_writeCallLog" msgid="670292975137658895">"idatzi deien erregistroan"</string>
     <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Tabletaren deien erregistroa aldatzeko baimena ematen die aplikazioei, sarrerako eta irteerako deiei buruzko datuak barne. Asmo txarreko aplikazioek deien erregistroa ezabatzeko edo aldatzeko erabil dezakete."</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Android TV gailuko deien erregistroa aldatzeko baimena ematen die aplikazioei, jasotako eta egindako deiei buruzko datuak barne. Baliteke asmo txarreko aplikazioek deien erregistroa ezabatzea edo aldatzea."</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Android TV gailuko deien erregistroa aldatzeko baimena ematen die aplikazioei, sarrerako eta irteerako deiei buruzko datuak barne. Baliteke asmo txarreko aplikazioek deien erregistroa ezabatzea edo aldatzea."</string>
     <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Telefonoaren deien erregistroa aldatzeko baimena ematen die aplikazioei, sarrerako eta irteerako deiei buruzko datuak barne. Asmo txarreko aplikazioek deien erregistroa ezabatzeko edo aldatzeko erabil dezakete."</string>
     <string name="permlab_bodySensors" msgid="662918578601619569">"Atzitu gorputz-sentsoreen datuak (esaterako, bihotz-maiztasuna) aplikazioa erabili bitartean"</string>
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Aplikazioak erabiltzen diren bitartean, gorputz-sentsoreen datuak (besteak beste, bihotz-maiztasuna, tenperatura eta odolean dagoen oxigenoaren ehunekoa) erabiltzeko baimena ematen die aplikazio horiei."</string>
@@ -979,7 +979,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5823469004536805423">"Gehitu SIM bat."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="4403843937236648032">"SIMa falta da, edo ezin da irakurri. Gehitu SIM bat."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="1925200607820809677">"Ezin da erabili SIMa."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="6902979937802238429">"Betiko desaktibatu da SIMa.\n Jarri harremanetan operadorearekin beste SIM bat eskuratzeko."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="6902979937802238429">"Betiko desaktibatu da SIMa.\n Jarri operadorearekin harremanetan beste SIM bat eskuratzeko."</string>
     <string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"Aurreko pista"</string>
     <string name="lockscreen_transport_next_description" msgid="2931509904881099919">"Hurrengo pista"</string>
     <string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"Pausatu"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Kendu"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Bolumena gomendatutako mailatik gora igo nahi duzu?\n\nMusika bolumen handian eta denbora luzez entzuteak entzumena kalte diezazuke."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Abisua:\nEntzungailuen bidez astebetean segurtasun osoz entzun daitekeen soinu ozenen kopurua gainditu duzu.\n\nSoinu ozen gehiago entzuten jarraituz gero, entzumena kaltetuko duzu."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Abisua:\nEntzungailuen bidez astebetean segurtasun osoz entzun daitekeen soinu ozenen kopurua bost aldiz gainditu duzu.\n\nEntzumena babesteko, bolumena jaitsi da."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Multimedia-edukia entzuteko bolumena denbora luzez erabiliz gero, baliteke entzumena kaltetzea.\n\nMultimedia-edukia denbora luzez bolumen horretan entzuten jarraitzen baduzu, baliteke entzumena kaltetzea."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Abisua:\nSegurua ez den maila batean entzuten ari zara eduki ozena.\n\nEdukia bolumen horretan entzuten jarraitzen baduzu, baliteke entzumena kaltetzea."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Bolumen altuan entzuten jarraitu nahi duzu?\n\nEntzungailuen bolumena gomendatutako denboran baino gehiagoan eduki da ozen, eta baliteke horrek entzumena kaltetzea"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Soinu ozen bat hauteman da\n\nEntzungailuen bolumena gomendatutakoa baino ozenago eduki da, eta baliteke horrek entzumena kaltetzea"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Erabilerraztasun-lasterbidea erabili nahi duzu?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Lasterbidea aktibatuta dagoenean, bi bolumen-botoiak hiru segundoz sakatuta abiaraziko da erabilerraztasun-eginbidea."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Erabilerraztasun-eginbideetarako lasterbidea aktibatu nahi duzu?"</string>
@@ -1928,9 +1926,9 @@
     <string name="call_notification_answer_video_action" msgid="2086030940195382249">"Bideoa"</string>
     <string name="call_notification_decline_action" msgid="3700345945214000726">"Baztertu"</string>
     <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Amaitu deia"</string>
-    <string name="call_notification_incoming_text" msgid="6143109825406638201">"Jasotako deia"</string>
+    <string name="call_notification_incoming_text" msgid="6143109825406638201">"Sarrerako deia"</string>
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Deia abian da"</string>
-    <string name="call_notification_screening_text" msgid="8396931408268940208">"Jasotako dei bat bistaratzen"</string>
+    <string name="call_notification_screening_text" msgid="8396931408268940208">"Sarrerako dei bat bistaratzen"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Kategoriarik gabea"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Zuk ezarri duzu jakinarazpen hauen garrantzia."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Garrantzitsua da eragiten dien pertsonengatik."</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Berraktibatu"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Ez dago laneko aplikaziorik"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Ez dago aplikazio pertsonalik"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Laneko <xliff:g id="APP">%s</xliff:g> aplikazioan ireki nahi duzu?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"<xliff:g id="APP">%s</xliff:g> pertsonalean ireki nahi duzu?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Laneko <xliff:g id="APP">%s</xliff:g> aplikazioan ireki nahi duzu?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Laneko aplikaziotik deitu nahi duzu?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Laneko aplikaziora aldatu nahi duzu?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Laneko aplikazioetatik soilik deitzeko baimena ematen du zure erakundeak"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Mezuak laneko aplikazioetatik soilik bidaltzeko baimena ematen du zure erakundeak"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Erabili arakatzaile pertsonala"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Erabili laneko arakatzailea"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Deitu"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Aldatu"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIMaren sarearen bidez desblokeatzeko PINa"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIMaren sareko azpimultzoaren bidez desblokeatzeko PINa"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Enpresaren SIMaren bidez desblokeatzeko PINa"</string>
@@ -2331,9 +2332,9 @@
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"Joan Ezarpenak atalera"</string>
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desaktibatu"</string>
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Konfiguratu da <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
-    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Ezarri da <xliff:g id="LAYOUT_1">%s</xliff:g> gisa teklatuaren diseinua. Diseinu hori aldatzeko, sakatu hau."</string>
-    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Ezarri da <xliff:g id="LAYOUT_1">%1$s</xliff:g> eta <xliff:g id="LAYOUT_2">%2$s</xliff:g> gisa teklatuaren diseinua. Diseinu hori aldatzeko, sakatu hau."</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Ezarri da <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> eta <xliff:g id="LAYOUT_3">%3$s</xliff:g> gisa teklatuaren diseinua. Diseinu hori aldatzeko, sakatu hau."</string>
+    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Ezarri da <xliff:g id="LAYOUT_1">%s</xliff:g>. Diseinu hori aldatzeko, sakatu hau."</string>
+    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Ezarri dira <xliff:g id="LAYOUT_1">%1$s</xliff:g> eta <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Diseinu horiek aldatzeko, sakatu hau."</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Ezarri dira <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> eta <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Diseinu horiek aldatzeko, sakatu hau."</string>
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Ezarri da <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> eta <xliff:g id="LAYOUT_3">%3$s</xliff:g> gisa teklatuaren diseinua… Diseinu hori aldatzeko, sakatu hau."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Konfiguratu dira teklatu fisikoak"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Sakatu hau teklatuak ikusteko"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index c6b15a0..415dce5 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"حذف"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"میزان صدا را به بالاتر از حد توصیه شده افزایش می‌دهید؟\n\nگوش دادن به صداهای بلند برای مدت طولانی می‌تواند به شنوایی‌تان آسیب وارد کند."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"هشدار،\nشما از میزان صدای بلندی که انسان می‌تواند به‌طور ایمن در یک هفته ازطریق هدفون گوش دهد فراتر رفته‌اید.\n\nعبور از این حد به شنوایی شما آسیب می‌رساند."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"هشدار،\nشما از میزان صدای بلندی که انسان می‌تواند به‌طور ایمن در یک هفته ازطریق هدفون گوش دهد ۵ بار فراتر رفته‌اید.\n\nبرای محافظت از شنوایی شما، صدا کاهش یافته است."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"میزان صدایی که با آن به رسانه گوش می‌کنید درصورت ادامه در درازمدت می‌تواند منجر به آسیب به شنوایی شود.\n\nادامه پخش با این صدا برای مدت طولانی می‌تواند به شنوایی شما آسیب برساند."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"هشدار،\nمیزان صدای بلندِ محتوایی که الآن می‌شنوید خطرناک است.\n\nاگر با همین بلندی صدا ادامه دهید شنوایی‌تان برای همیشه آسیب خواهد دید."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"همچنان می‌خواهید با صدای بلند گوش کنید؟\n\nصدای هدفون برای مدتی طولانی‌تر از حد توصیه‌شده بلند بوده است. این موضوع می‌تواند به شنوایی شما آسیب بزند."</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"صدای بلند شناسایی شد\n\nصدای هدفون برای مدتی طولانی‌تر از حد توصیه‌شده بلند بوده است. این موضوع می‌تواند به شنوایی شما آسیب بزند."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"از میان‌بر دسترس‌پذیری استفاده شود؟"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"وقتی میان‌بر روشن باشد، با فشار دادن هردو دکمه صدا به‌مدت ۳ ثانیه ویژگی دسترس‌پذیری فعال می‌شود."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"میان‌بر برای ویژگی‌های دسترس‌پذیری روشن شود؟"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"لغو مکث"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"برنامه کاری‌ای وجود ندارد"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"برنامه شخصی‌ای وجود ندارد"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"<xliff:g id="APP">%s</xliff:g> کاری باز شود؟"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"در <xliff:g id="APP">%s</xliff:g> شخصی باز شود؟"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"در <xliff:g id="APP">%s</xliff:g> کاری باز شود؟"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"تماس ازطریق برنامه کاری برقرار شود؟"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"به برنامه کاری جابه‌جا شوید؟"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"سازمانتان به شما اجازه می‌دهد فقط ازطریق برنامه‌های کاری تماس بگیرید"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"سازمانتان به شما اجازه می‌دهد فقط ازطریق برنامه‌های کاری پیام ارسال کنید"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"استفاده از مرورگر شخصی"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"استفاده از مرورگر کاری"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"تماس گرفتن"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"عوض کردن"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"پین باز کردن قفل شبکه سیم‌کارت"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"پین باز کردن قفل زیرمجموعه شبکه سیم‌کارت"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"پین باز کردن قفل شرکت سیم‌کارت"</string>
@@ -2330,7 +2331,7 @@
     <string name="concurrent_display_notification_power_save_content" msgid="2198116070583851493">"‏Dual Screen دردسترس نیست چون «بهینه‌سازی باتری» روشن است. می‌توانید این ویژگی را در «تنظیمات» خاموش کنید."</string>
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"رفتن به تنظیمات"</string>
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"خاموش کردن"</string>
-    <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> پیکربندی شد"</string>
+    <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"‫<xliff:g id="DEVICE_NAME">%s</xliff:g> پیکربندی شد"</string>
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"طرح‌بندی صفحه‌کلید روی <xliff:g id="LAYOUT_1">%s</xliff:g> تنظیم شد. برای تغییر دادن، ضربه بزنید."</string>
     <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"طرح‌بندی صفحه‌کلید روی <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g> تنظیم شد. برای تغییر دادن، ضربه بزنید."</string>
     <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"طرح‌بندی صفحه‌کلید روی <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g> تنظیم شد. برای تغییر دادن، ضربه بزنید."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index c8316b7..ccca9df 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Poista"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Nostetaanko äänenvoimakkuus suositellun tason yläpuolelle?\n\nPitkäkestoinen kova äänenvoimakkuus saattaa heikentää kuuloa."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Varoitus,\nolet kuunnellut tällä viikolla enemmän äänekkäitä signaaleja kuin kuulokkeilla on turvallista.\n\nRajan ylittäminen vahingoittaa kuuloasi pysyvästi."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Varoitus,\nolet kuunnellut tällä viikolla viisi kertaa enemmän äänekkäitä signaaleja kuin kuulokkeilla on turvallista.\n\nÄänenvoimakkuutta on laskettu kuulosi suojaamiseksi."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Äänenvoimakkuus, jolla kuuntelet mediaa, voi ajan mittaan johtaa kuulovaurioihin.\n\nJos jatkat tällä äänenvoimakkuudella pitkään, kuulosi voi vaurioitua."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Varoitus,\nkuuntelet sisältöä äänenvoimakkuudella, joka ei ole turvallinen.\n\nTällä äänenvoimakkuudella jatkaminen voi vaurioittaa kuuloasi pysyvästi."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Haluatko jatkaa suurella äänenvoimakkuudella kuuntelua?\n\nKuulokkeiden äänenvoimakkuus on ollut suuri suositeltua pidemmän ajan, mikä voi vaurioittaa kuuloa"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Kova ääni havaittu\n\nKuulokkeiden äänenvoimakkuus on ollut suositeltua suurempi, mikä voi vaurioittaa kuuloa"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Käytetäänkö esteettömyyden pikanäppäintä?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kun pikanäppäin on käytössä, voit käynnistää esteettömyystoiminnon pitämällä molempia äänenvoimakkuuspainikkeita painettuna kolmen sekunnin ajan."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Laitetaanko esteettömyysominaisuuksien pikavalinta päälle?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Jatka"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Ei työsovelluksia"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Ei henkilökohtaisia sovelluksia"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Avataanko sisältö työprofiilissa (<xliff:g id="APP">%s</xliff:g>)?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Avataanko sisältö henkilökohtaisessa profiilissa (<xliff:g id="APP">%s</xliff:g>)?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Avataanko sisältö työprofiilissa (<xliff:g id="APP">%s</xliff:g>)?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Soitetaanko työsovelluksesta?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Vaihdetaanko työsovellukseen?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Organisaatio sallii soittamisen vain työsovelluksilla"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Organisaatio sallii viestien lähettämisen vain työsovelluksilla"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Käytä henkilökohtaista selainta"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Käytä työselainta"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Soita"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Vaihda"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM-kortin verkkoversion lukituksen avaamisen PIN-koodi"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM-kortin verkkoversion alijoukon lukituksen avaamisen PIN-koodi"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM-kortin yritysversion lukituksen avaamisen PIN-koodi"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 7423ba1..97bbfb4 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -319,7 +319,7 @@
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"enregistrer des fichiers audio"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Activité physique"</string>
     <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"accéder à vos activités physiques"</string>
-    <string name="permgrouplab_camera" msgid="9090413408963547706">"Appareil photo"</string>
+    <string name="permgrouplab_camera" msgid="9090413408963547706">"appareil photo"</string>
     <string name="permgroupdesc_camera" msgid="7585150538459320326">"prendre des photos et filmer des vidéos"</string>
     <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Appareils à proximité"</string>
     <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"découvrir les appareils à proximité et s\'y connecter"</string>
@@ -506,8 +506,7 @@
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Permet à l\'application de gérer le vibreur de l\'appareil."</string>
     <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permet à l\'application d\'accéder au mode vibration."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"appeler directement des numéros de téléphone"</string>
-    <!-- no translation found for permdesc_callPhone (7892422187827695656) -->
-    <skip />
+    <string name="permdesc_callPhone" msgid="7892422187827695656">"Autorisez l\'application à appeler des numéros de téléphone sans votre intervention. Cela peut entraîner des frais ou des appels imprévus. Notez aussi que cela ne permet pas à l\'application d\'appeler des numéros d\'urgence. Des applications malveillantes peuvent engendrer des frais en passant des appels sans votre confirmation ou en composant des codes de fournisseurs de service qui transfèrent automatiquement des appels entrants vers un autre numéro."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"accéder au service d\'appel IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permet à l\'application d\'utiliser le service IMS pour faire des appels sans votre intervention."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"voir l\'état et l\'identité du téléphone"</string>
@@ -1665,7 +1664,7 @@
     <string name="kg_login_instructions" msgid="3619844310339066827">"Pour déverrouiller l\'appareil, connectez-vous avec votre compte Google."</string>
     <string name="kg_login_username_hint" msgid="1765453775467133251">"Nom d\'utilisateur (courriel)"</string>
     <string name="kg_login_password_hint" msgid="3330530727273164402">"Mot de passe"</string>
-    <string name="kg_login_submit_button" msgid="893611277617096870">"Connexion"</string>
+    <string name="kg_login_submit_button" msgid="893611277617096870">"Se connecter"</string>
     <string name="kg_login_invalid_input" msgid="8292367491901220210">"Nom d\'utilisateur ou mot de passe non valide."</string>
     <string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Vous avez oublié votre nom d\'utilisateur ou votre mot de passe?\nRendez-vous sur la page "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="4676010303243317253">"Vérification du compte en cours…"</string>
@@ -1684,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Supprimer"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Augmenter le volume au-dessus du niveau recommandé?\n\nL\'écoute prolongée à un volume élevé peut endommager vos facultés auditives."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Avertissement,\nVous avez dépassé la quantité de signaux sonores forts hebdomadaire à laquelle vous pouvez être exposé sans danger avec des écouteurs.\n\nLe dépassement de cette limite endommagera votre audition de façon permanente."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Avertissement,\nVous avez dépassé de cinq fois la quantité de signaux sonores forts hebdomadaire à laquelle vous pouvez être exposé sans danger avec des écouteurs.\n\nLe volume a été baissé pour protéger votre audition."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Le niveau auquel vous écoutez le contenu multimédia peut entraîner des dommages auditifs s\'il est maintenu sur une durée prolongée.\n\nVous risquez d\'endommager votre audition si vous continuez l\'écoute à ce niveau sur une durée prolongée."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Avertissement,\nVous écoutez actuellement un contenu dont le niveau sonore élevé est dangereux.\n\nSi vous continuez à écouter à ce niveau, vous endommagerez votre audition de façon permanente."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Continuer à écouter à un volume élevé?\n\nLe niveau du volume des écouteurs est resté élevé au-delà de la durée recommandée, ce qui peut endommager votre audition"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Son fort détecté\n\nLe niveau du volume des écouteurs est plus élevé que celui recommandé, ce qui peut endommager votre audition"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Utiliser le raccourci d\'accessibilité?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Quand le raccourci est activé, appuyez sur les deux boutons de volume pendant trois secondes pour lancer une fonctionnalité d\'accessibilité."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Activer le raccourci pour les fonctionnalités d\'accessibilité?"</string>
@@ -2162,20 +2159,21 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Impossible d\'ouvrir ce contenu avec des applications professionnelles"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Impossible de partager ce contenu avec des applications personnelles"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Impossible d\'ouvrir ce contenu avec des applications personnelles"</string>
-    <!-- no translation found for resolver_turn_on_work_apps (1535946298236678122) -->
-    <skip />
-    <!-- no translation found for resolver_switch_on_work (4527096360772311894) -->
-    <skip />
+    <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Les applications professionnelles sont interrompues"</string>
+    <string name="resolver_switch_on_work" msgid="4527096360772311894">"Réactiver"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Aucune application professionnelle"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Aucune application personnelle"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Ouvrir le profil professionnel de <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Ouvrir <xliff:g id="APP">%s</xliff:g> dans le profil personnel?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Ouvrir <xliff:g id="APP">%s</xliff:g> dans le profil professionnel?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Appeler à partir de l\'application professionnelle?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Passer à l\'application professionnelle?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Votre organisation vous autorise à passer des appels uniquement à partir d\'applications professionnelles"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Votre organisation vous autorise à envoyer des messages uniquement à partir d\'applications professionnelles"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Utiliser le navigateur du profil personnel"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Utiliser le navigateur du profil professionnel"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Appeler"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Changer"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"NIP de déverrouillage du réseau associé au module SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"NIP de déverrouillage du sous-ensemble du réseau associé au module SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"NIP de déverrouillage du module SIM professionnel"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index d1c7c98..6e2e1f0 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -626,11 +626,11 @@
     <string name="biometric_error_generic" msgid="6784371929985434439">"Erreur d\'authentification"</string>
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Utiliser verrouillage écran"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Utilisez le verrouillage de l\'écran pour continuer"</string>
-    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Appuyez bien sur le lecteur"</string>
+    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Appuyez fermement sur le lecteur"</string>
     <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Impossible de reconnaître l\'empreinte digitale. Réessayez."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Nettoyez le lecteur d\'empreinte digitale et réessayez"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Nettoyez le lecteur et réessayez"</string>
-    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Appuyez bien sur le lecteur"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Appuyez fermement sur le lecteur"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Vous avez déplacé votre doigt trop lentement. Veuillez réessayer."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Essayez une autre empreinte"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Trop de lumière"</string>
@@ -1397,7 +1397,7 @@
     <string name="hardware" msgid="1800597768237606953">"Afficher le clavier virtuel"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configurer <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configurez les claviers physiques"</string>
-    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Appuyer pour sélectionner la langue et la disposition"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Appuyez pour sélectionner la langue et la disposition"</string>
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Afficher par-dessus les autres applications"</string>
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Supprimer"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Augmenter le volume au dessus du niveau recommandé ?\n\nL\'écoute prolongée à un volume élevé peut endommager vos facultés auditives."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Attention,\nVous avez dépassé la dose hebdomadaire de bruit élevé que vous pouvez écouter sans danger via un casque.\n\nDépasser cette limite endommagera définitivement votre audition."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Attention,\nVous avez dépassé 5 fois la dose hebdomadaire de bruit élevé que vous pouvez écouter sans danger via un casque.\n\nLe volume a été réduit pour protéger votre audition."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Le volume auquel vous écoutez du contenu multimédia peut endommager votre audition s\'il est maintenu pendant une longue période.\n\nSi vous continuez d\'écouter du contenu à ce volume pendant de longues périodes, vous risquez d\'endommager votre audition."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Attention,\nVous écoutez actuellement du contenu à un volume sonore dangereux.\n\nPoursuivre l\'écoute à un volume si élevé endommagera définitivement votre audition."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Continuer d\'écouter à un volume élevé ?\n\nLe volume du casque est élevé depuis plus longtemps que recommandé, ce qui peut endommager votre audition"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Bruit fort détecté\n\nLe volume du casque est élevé depuis plus longtemps que recommandé, ce qui peut endommager votre audition"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Utiliser le raccourci d\'accessibilité ?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Quand le raccourci est activé, appuyez sur les deux boutons de volume pendant trois secondes pour démarrer une fonctionnalité d\'accessibilité."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Activer le raccourci pour accéder aux fonctionnalités d\'accessibilité ?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Réactiver"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Aucune appli professionnelle"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Aucune appli personnelle"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Ouvrir <xliff:g id="APP">%s</xliff:g> (professionnel) ?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Ouvrir dans <xliff:g id="APP">%s</xliff:g> (personnel) ?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Ouvrir dans <xliff:g id="APP">%s</xliff:g> (professionnel) ?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Appeler depuis une appli professionnelle ?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Passer à une appli professionnelle ?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Votre organisation ne vous autorise à passer des appels que depuis des applis professionnelles"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Votre organisation ne vous autorise à envoyer des messages que depuis des applis professionnelles"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Utiliser le navigateur personnel"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Utiliser le navigateur professionnel"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Appeler"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Changer"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Code PIN de déblocage du réseau SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Code PIN de déblocage du sous-ensemble du réseau SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Code PIN de déblocage de la carte SIM d\'entreprise"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 90bd60f..9da299c 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -312,7 +312,7 @@
     <string name="permgroupdesc_storage" msgid="5378659041354582769">"acceder a ficheiros no teu dispositivo"</string>
     <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Música e audio"</string>
     <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"acceder a música e audio do dispositivo"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotos e vídeos"</string>
+    <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"fotos e vídeos"</string>
     <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"acceder a fotos e vídeos do dispositivo"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Micrófono"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"gravar audio"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Quitar"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Queres subir o volume máis do nivel recomendado?\n\nA reprodución de son a un volume elevado durante moito tempo pode provocar danos nos oídos."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Advertencia:\nSuperaches a cantidade de sinais acústicos elevados que podes escoitar de forma segura con auriculares nunha semana.\n\nSe superas este límite, os teus oídos quedarán danados permanentemente."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Advertencia:\nSuperaches 5 veces a cantidade de sinais acústicos elevados que podes escoitar de forma segura con auriculares nunha semana.\n\nBaixouse o volume para protexer os teus oídos."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"O nivel ao que escoitas o contido multimedia pode causar danos auditivos se o mantés durante longos períodos de tempo.\n\nSe segues reproducindo audio a este nivel de volume durante moito tempo, poderían danárseche os oídos."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Advertencia:\nEstás escoitando contido a un nivel de volume perigoso.\n\nSe segues escoitando audio a este nivel de volume, os teus oídos quedarán danados permanentemente."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Queres seguir escoitando contido cun volume alto?\n\nUsaches os auriculares cun volume alto durante máis tempo do recomendado, o que podería provocarche danos auditivos"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Detectouse son alto\n\nUsaches os auriculares cun volume máis alto do recomendado, o que podería provocarche danos auditivos"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Queres utilizar o atallo de accesibilidade?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Cando o atallo está activado, podes premer os dous botóns de volume durante 3 segundos para iniciar unha función de accesibilidade."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Queres activar as funcións de accesibilidade?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Reactivar"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Non hai ningunha aplicación do traballo compatible"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Non hai ningunha aplicación persoal compatible"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Queres abrir a aplicación <xliff:g id="APP">%s</xliff:g> do traballo?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Queres abrir o contido na aplicación <xliff:g id="APP">%s</xliff:g> persoal?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Queres abrir o contido na aplicación <xliff:g id="APP">%s</xliff:g> do traballo?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Queres chamar desde a aplicación do traballo?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Queres cambiar á aplicación do traballo?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"A túa organización só che permite chamar desde aplicacións do traballo"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"A túa organización só che permite enviar mensaxes desde aplicacións do traballo"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Utilizar navegador persoal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Utilizar navegador de traballo"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Chamar"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Cambiar"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN de desbloqueo da rede SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN de desbloqueo do subconxunto da rede SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN de desbloqueo corporativo da SIM"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 23b8cac..1c7d986 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"કાઢી નાખો"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ભલામણ કરેલ સ્તરની ઉપર વૉલ્યૂમ વધાર્યો?\n\nલાંબા સમય સુધી ઊંચા અવાજે સાંભળવું તમારી શ્રવણક્ષમતાને નુકસાન પહોંચાડી શકે છે."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"ચેતવણી,\nએક અઠવાડિયામાં કોઈ વ્યક્તિ હૅડફોન પર સુરક્ષિત રીતે મોટા અવાજે સાંભળી શકે તેટલા સાઉન્ડ સિગ્નલની મર્યાદા તમે વટાવી ચૂક્યા છો.\n\nઆ મર્યાદા વટાવવાથી તમારી સાંભળવાની ક્ષમતાને કાયમી રીતે નુક્સાન થઈ શકે છે."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"ચેતવણી,\nએક અઠવાડિયામાં કોઈ વ્યક્તિ હૅડફોન પર સુરક્ષિત રીતે મોટા અવાજે સાંભળી શકે તેટલા સાઉન્ડ સિગ્નલના 5 ગણાથી વધુ મર્યાદા તમે વટાવી ચૂક્યા છો.\n\nતમારી સાંભળવાની ક્ષમતાને સુરક્ષિત રાખવા માટે વૉલ્યૂમ ઘટાડવામાં આવ્યું છે."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"તમે જે લેવલ પર મીડિયા સાંભળી રહ્યાં છો, તે લાંબા સમય સુધી ચાલુ રહેશે તો તેના પરિણામે તમારી સાંભળવાની ક્ષમતાને નુક્સાન થઈ શકે છે.\n\nઆ લેવલ પર લાંબા સમય સુધી વગાડવાનું ચાલુ રાખવાથી, તમારી સાંભળવાની ક્ષમતાને નુક્સાન થઈ શકે છે."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"ચેતવણી,\nતમે હાલમાં અસુરક્ષિત લેવલ પર મોટેથી વગાડવામાં આવતું કન્ટેન્ટ સાંભળી રહ્યાં છો.\n\nઆટલું મોટેથી વાગતું કન્ટેન્ટ સાંભળવાનું ચાલુ રાખવાથી તમારી સાંભળવાની ક્ષમતાને કાયમી રીતે નુક્સાન થશે."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"ઊંચા વૉલ્યૂમ પર સાંભળવાનું ચાલુ રાખીએ?\n\nહૅડફોનનું વૉલ્યૂમ સુઝાવ આપેલા સમય કરતાં વધારે સમય સુધી ઊંચા વૉલ્યૂમ પર રહ્યું છે, જે તમારી શ્રવણશક્તિને નુકસાન પહોંચાડી શકે છે"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"મોટા અવાજની ભાળ મળી\n\nહૅડફોનનું વૉલ્યૂમ સુઝાવ આપેલા કરતાં વધુ ઊંચા વૉલ્યૂમ પર રહ્યું છે, જે તમારી શ્રવણશક્તિને નુકસાન પહોંચાડી શકે છે"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ઍક્સેસિબિલિટી શૉર્ટકટનો ઉપયોગ કરીએ?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"જ્યારે શૉર્ટકટ ચાલુ હોય, ત્યારે બન્ને વૉલ્યૂમ બટનને 3 સેકન્ડ સુધી દબાવી રાખવાથી ઍક્સેસિબિલિટી સુવિધા શરૂ થઈ જશે."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"ઍક્સેસિબિલિટી સુવિધાઓ માટે શૉર્ટકટ ચાલુ કરીએ?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"ફરી ચાલુ કરો"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"કોઈ ઑફિસ માટેની ઍપ સપોર્ટ કરતી નથી"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"કોઈ વ્યક્તિગત ઍપ સપોર્ટ કરતી નથી"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"ઑફિસની પ્રોફાઇલવાળી <xliff:g id="APP">%s</xliff:g> ખોલીએ?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"વ્યક્તિગત પ્રોફાઇલવાળી <xliff:g id="APP">%s</xliff:g>માં ખોલીએ?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"ઑફિસની પ્રોફાઇલવાળી <xliff:g id="APP">%s</xliff:g>માં ખોલીએ?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"શું ઑફિસ માટેની ઍપમાંથી કૉલ કરીએ?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"શું ઑફિસ માટેની ઍપ પર સ્વિચ કરીએ?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"તમારી સંસ્થા તમને માત્ર ઑફિસ માટેની ઍપ પરથી કૉલ કરવાની મંજૂરી આપે છે"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"તમારી સંસ્થા તમને માત્ર ઑફિસ માટેની ઍપ પરથી મેસેજ મોકલવાની મંજૂરી આપે છે"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"વ્યક્તિગત બ્રાઉઝરનો ઉપયોગ કરો"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ઑફિસના બ્રાઉઝરના ઉપયોગ કરો"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"કૉલ કરો"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"સ્વિચ કરો"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"સિમ નેટવર્કને અનલૉક કરવાનો પિન"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"સિમ નેટવર્ક સબસેટને અનલૉક કરવાનો પિન"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"સિમ કૉર્પોરેટ કાર્ડના લૉકને અનલૉક કરવાનો પિન"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index bdb65b9..c750d50 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -308,7 +308,7 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"अपने कैलेंडर को ऐक्सेस करें"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"मैसेज (एसएमएस)"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"मैसेज (एसएमएस) भेजें और देखें"</string>
-    <string name="permgrouplab_storage" msgid="17339216290379241">"फ़ाइलें"</string>
+    <string name="permgrouplab_storage" msgid="17339216290379241">"फ़ाइल"</string>
     <string name="permgroupdesc_storage" msgid="5378659041354582769">"अपने डिवाइस में मौजूद फ़ाइलों का ऐक्सेस दें"</string>
     <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"संगीत और ऑडियो"</string>
     <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"आपके डिवाइस पर संगीत और ऑडियो को ऐक्सेस करने की अनुमति"</string>
@@ -629,7 +629,7 @@
     <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"फ़िंगरप्रिंट की पहचान नहीं की जा सकी. फिर से कोशिश करें."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"फ़िंगरप्रिंट सेंसर को साफ़ करके फिर से कोशिश करें"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"फ़िंगरप्रिंट सेंसर को साफ़ करके फिर से कोशिश करें"</string>
-    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"सेंसर को उंगली से दबाएं"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"सेंसर को उंगली से दबाकर रखें"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"उंगली बहुत धीरे चलाई गई. कृपया फिर से कोशिश करें."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"किसी दूसरे फ़िंगरप्रिंट से कोशिश करें"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"बहुत रोशनी है"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"हटाएं"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"वॉल्यूम को सुझाए गए स्तर से ऊपर बढ़ाएं?\n\nअत्यधिक वॉल्यूम पर ज़्यादा समय तक सुनने से आपकी सुनने की क्षमता को नुकसान हो सकता है."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"चेतावनी,\nआपने हेडफ़ोन पर एक हफ़्ते में, सुरक्षित तरीके से तेज़ साउंड सिग्नल सुनने की सीमा को पार कर लिया है.\n\nइस सीमा को पार करने पर, आपकी सुनने की क्षमता को हमेशा के लिए नुकसान पहुंच सकता है."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"चेतावनी,\nआपने हेडफ़ोन पर एक हफ़्ते में, सुरक्षित तरीके से तेज़ साउंड सिग्नल सुनने की सीमा से पांच गुना ज़्यादा बार तेज़ साउंड सिग्नल सुन लिए हैं.\n\nआपकी सुनने की क्षमता की सुरक्षा के लिए, आवाज़ को धीमा कर दिया गया है."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"मौजूदा लेवल पर ज़्यादा समय तक मीडिया को सुनने से, आपकी सुनने की क्षमता को नुकसान पहुंच सकता है.\n\nबहुत देर तक इस लेवल पर मीडिया चलाना जारी रखने से, आपकी सुनने की क्षमता को नुकसान पहुंच सकता है."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"चेतावनी,\nतेज़ आवाज़ वाले कॉन्टेंट को, आवाज़ के असुरक्षित लेवल पर सुना जा रहा है.\n\nबहुत देर तक इतनी तेज़ आवाज़ को सुनने पर, आपकी सुनने की क्षमता को हमेशा के लिए नुकसान पहुंच सकता है."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"क्या तेज़ आवाज़ में गाने सुनना जारी रखना है?\n\nहेडफ़ोन की आवाज़ सुझाए गए समय के बाद भी ज़्यादा रही. इससे आपकी सुनने की क्षमता को नुकसान पहुंच सकता है"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"तेज़ आवाज़ का पता चला है\n\nहेडफ़ोन की आवाज़ सुझाए गए लेवल से ज़्यादा है. इससे आपकी सुनने की क्षमता को नुकसान पहुंच सकता है"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"सुलभता शॉर्टकट का इस्तेमाल करना चाहते हैं?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"शॉर्टकट के चालू होने पर, दाेनाें वॉल्यूम बटन (आवाज़ कम या ज़्यादा करने वाले बटन) को तीन सेकंड तक दबाने से, सुलभता सुविधा शुरू हाे जाएगी."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"क्या आप सुलभता सुविधाओं के लिए शॉर्टकट चालू करना चाहते हैं?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"चालू करें"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"यह कॉन्टेंट, ऑफ़िस के काम से जुड़े आपके किसी भी ऐप्लिकेशन पर खोला नहीं जा सकता"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"यह कॉन्टेंट आपके किसी भी निजी ऐप्लिकेशन पर खोला नहीं जा सकता"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"वर्क प्रोफ़ाइल वाला <xliff:g id="APP">%s</xliff:g> ऐप्लिकेशन खोलें?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"निजी प्रोफ़ाइल वाले <xliff:g id="APP">%s</xliff:g> ऐप्लिकेशन में जाकर खोलें?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"वर्क प्रोफ़ाइल वाले <xliff:g id="APP">%s</xliff:g> ऐप्लिकेशन में जाकर खोलें?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"क्या आपको वर्क ऐप्लिकेशन से कॉल करना है?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"क्या आपको वर्क ऐप्लिकेशन में स्विच करना है?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"आपके संगठन ने, सिर्फ़ वर्क ऐप्लिकेशन से कॉल करने की अनुमति दी है"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"आपके संगठन ने, सिर्फ़ वर्क ऐप्लिकेशन से मैसेज भेजने की अनुमति दी है"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"निजी ब्राउज़र का इस्तेमाल करें"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ऑफ़िस के काम से जुड़े ब्राउज़र का इस्तेमाल करें"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"कॉल करें"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"स्विच करें"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"सिम नेटवर्क को अनलॉक करने का पिन"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"सिम नेटवर्क के सबसेट को अनलॉक करने का पिन"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"कारोबार के लिए इस्तेमाल होने वाले सिम को अनलॉक करने का पिन"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 1a3ab3a..38d3f01 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Ukloni"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Želite li pojačati zvuk iznad preporučene razine?\n\nDugotrajno slušanje glasne glazbe može vam oštetiti sluh."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Upozorenje,\npremašili ste količinu glasnih zvučnih signala koja se može sigurno slušati putem slušalica u tjedan dana.\n\nPrekoračenjem tog ograničenja trajno ćete oštetiti svoj sluh."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Upozorenje,\npeterostruko ste premašili količinu glasnih zvučnih signala koja se može sigurno slušati putem slušalica u tjedan dana.\n\nGlasnoća je utišana radi zaštite vašeg sluha."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Glasnoća kojom slušate medijske sadržaje može rezultirati oštećenjem sluha ako potraje dulje.\n\nAko nastavite slušati tako glasno dulje vrijeme, mogao bi vam se oštetiti sluh."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Upozorenje,\ntrenutačno slušate glasan sadržaj nesigurnom glasnoćom.\n\nAko nastavite slušati tako glasno, trajno ćete oštetiti sluh."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Želite li nastaviti slušati vrlo glasno?\n\nPojačana je glasnoća u slušalicama dulje nego što se preporučuje, a to vam može oštetiti sluh"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Detektiran je glasan zvuk\n\nGlasnoća u slušalicama jača je od preporučene, a to vam može oštetiti sluh"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite li upotrebljavati prečac za pristupačnost?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kad je taj prečac uključen, pritiskom na obje tipke za glasnoću na tri sekunde pokrenut će se značajka pristupačnosti."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Želite li uključiti prečac za značajke pristupačnosti?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Ponovno pokreni"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Poslovne aplikacije nisu dostupne"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Osobne aplikacije nisu dostupne"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Otvoriti aplikaciju <xliff:g id="APP">%s</xliff:g> za poslovni profil?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Otvoriti u aplikaciji <xliff:g id="APP">%s</xliff:g> za osobni profil?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Otvoriti u aplikaciji <xliff:g id="APP">%s</xliff:g> za poslovni profil?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Želite li nazvati putem poslovne aplikacije?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Želite li prebaciti na poslovnu aplikaciju?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Vaša organizacija dopušta upućivanje poziva samo iz poslovnih aplikacija"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Vaša organizacija dopušta slanje poruka samo iz poslovnih aplikacija"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Koristi osobni preglednik"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Koristi poslovni preglednik"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Nazovi"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Prebaci"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN za otključavanje SIM mreže."</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN za otključavanje podskupa SIM mreže"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN za otključavanje poslovnog SIM-a"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 21934cf..0525338 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Eltávolítás"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Az ajánlott szint fölé szeretné emelni a hangerőt?\n\nHa hosszú időn át teszi ki magát nagy hangerőnek, azzal károsíthatja a hallását."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Figyelem!\nTúllépte azt az időt, ameddig egy ember fejlhallgatóval biztonságosan hallgathat hangos hangokat egy hét alatt.\n\nEnnek a határértéknek a túllépése maradandóan károsítani fogja a hallását."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Figyelem!\nÖtszörösen túllépte azt az időt, ameddig egy ember fejlhallgatóval biztonságosan hallgathat hangos hangokat egy hét alatt.\n\nA rendszer csökkentette a hangerőt a hallása védelme érdekében."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Az a hangerő, amelyen jelenleg médiatartalmat hallgat, hosszabb idejű hallgatás esetén halláskárosodást okozhat.\n\nHa továbbra is ezen a hangerőn folytatja a lejátszást hosszabb ideig, károsíthatja a hallását."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Figyelem!\nJelenleg nem biztonságos szinten hallgat hangos médiatartalmat.\n\nHa továbbra is ezen a hangerőn folytatja a lejátszást, maradandóan károsodni fog a hallása."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Maradjon a magas hangerő?\n\nA fejhallgató hangereje az ajánlottnál hosszabb ideig volt magasra állítva, ami károsíthatja a hallását."</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Nagy hangerő észlelhető\n\nA fejhallgató hangereje magasabb az ajánlottnál, ami károsíthatja a hallását."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Szeretné használni a Kisegítő lehetőségek billentyűparancsot?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Ha a gyorsparancs aktív, akkor a két hangerőgomb három másodpercig tartó együttes lenyomásával kisegítő funkciót indíthat el."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Bekapcsol gyorsparancsot a kisegítő lehetőségekhez?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Szüneteltetés feloldása"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nincs munkahelyi alkalmazás"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nincs személyes alkalmazás"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Megnyitja a munkahelyi <xliff:g id="APP">%s</xliff:g> alkalmazást?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"A személyes <xliff:g id="APP">%s</xliff:g> alkalmazásban szeretné megnyitni?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"A munkahelyi <xliff:g id="APP">%s</xliff:g> alkalmazásban szeretné megnyitni?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Hívás a munkahelyi alkalmazásból?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Átvált a munkahelyi alkalmazásra?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Szervezete csak munkahelyi alkalmazásokból engedélyezi a hívásindítást"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Szervezete csak munkahelyi alkalmazásokból engedélyezi az üzenetküldést"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Személyes böngésző használata"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Munkahelyi böngésző használata"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Hívás"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Váltás"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Hálózati SIM feloldó PIN-kódja"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Hálózati SIM alkészletének feloldó PIN-kódja"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Vállalati SIM feloldó PIN-kódja"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 4abf401..db5acb9 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -683,8 +683,8 @@
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Մոտեցրեք հեռախոսը"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Բարձրացրեք հեռախոսը"</string>
     <string name="face_acquired_too_low" msgid="4075391872960840081">"Իջեցրեք հեռախոսը"</string>
-    <string name="face_acquired_too_right" msgid="6245286514593540859">"Տեղափոխեք հեռախոսը ձախ"</string>
-    <string name="face_acquired_too_left" msgid="9201762240918405486">"Տեղափոխեք հեռախոսը աջ"</string>
+    <string name="face_acquired_too_right" msgid="6245286514593540859">"Հեռախոսը շարժեք դեպի ձախ"</string>
+    <string name="face_acquired_too_left" msgid="9201762240918405486">"Հեռախոսը շարժեք դեպի աջ"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Նայեք ուղիղ էկրանին։"</string>
     <string name="face_acquired_not_detected" msgid="1057966913397548150">"Դեմքը չի երևում։ Հեռախոսը պահեք աչքերի մա­­կարդակում։"</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Շատ եք շարժում։ Հեռախոսն անշարժ պահեք։"</string>
@@ -1370,7 +1370,7 @@
     <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Հայտնաբերված է անալոգային աուդիո լրասարք"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Կցված սարքը համատեղելի չէ այս հեռախոսի հետ: Հպեք` ավելին իմանալու համար:"</string>
     <string name="adb_active_notification_title" msgid="408390247354560331">"USB-ով վրիպազերծումը միացված է"</string>
-    <string name="adb_active_notification_message" msgid="5617264033476778211">"Հպեք՝ USB-ով վրիպազերծումն անջատելու համար"</string>
+    <string name="adb_active_notification_message" msgid="5617264033476778211">"Հպեք՝ անջատելու համար"</string>
     <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Սեղմեք՝ USB-ով վրիպազերծումն անջատելու համար:"</string>
     <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Անլար վրիպազերծումը միացված է"</string>
     <string name="adbwifi_active_notification_message" msgid="930987922852867972">"Հպեք՝ անլար վրիպազերծումն անջատելու համար"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Հեռացնել"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ձայնը բարձրացնե՞լ խորհուրդ տրվող մակարդակից ավել:\n\nԵրկարատև բարձրաձայն լսելը կարող է վնասել ձեր լսողությունը:"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Ուշադրություն.\nդուք գերազանցել եք բարձր ձայնային ազդանշանների քանակը, որն անվտանգ է համարվում մեկ շաբաթվա ընթացքում ականջակալներով լսելու համար։\n\nԱյս սահմանաչափն անցնելու դեպքում ձեր լսողությանն անդառնալի վնաս կհասցվի։"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Ուշադրություն.\nդուք 5 անգամ գերազանցել եք բարձր ձայնային ազդանշանների քանակը, որն անվտանգ է համարվում մեկ շաբաթվա ընթացքում ականջակալներով լսելու համար։\n\nՁայնն իջեցվել է՝ ձեր լսողությունը պաշտպանելու համար։"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Երկար ժամանակ ձայնի ուժգնության այս մակարդակով մեդիա բովանդակություն լսելը կարող է վնասել ձեր լսողությունը։\n\nԵթե ձայնը չիջեցնեք, ձեր լսողությունը ժամանակի ընթացքում կարող է վատանալ։"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Ուշադրություն․\nդուք չափազանց բարձր ձայնով եք մեդիա բովանդակություն լսում, ինչը կարող է վտանագավոր լինել։\n\nԵթե չիջեցնեք ձայնը, ձեր լսողությանն անդառնալի վնաս կհասցվի։"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Պահե՞լ ձայնը բարձրացրած\n\nԱկանջակալների ձայնի ուժգնությունը տևական ժամանակ ավելի բարձր է եղել առաջարկվող մակարդակից, ինչը կարող է վնասել ձեր լսողությունը"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Հայտնաբերվել է ձայնի բարձր ուժգնություն\n\nԱկանջակալների ձայնի ուժգնությունը բարձր է առաջարկվող մակարդակից, ինչը կարող է վնասել ձեր լսողությունը"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Օգտագործե՞լ Մատչելիության դյուրանցումը։"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Հատուկ գործառույթն օգտագործելու համար սեղմեք և 3 վայրկյան սեղմած պահեք ձայնի ուժգնության երկու կոճակները, երբ գործառույթը միացված է:"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Միացնե՞լ հատուկ գործառույթների դյուրանցումը"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Վերսկսել"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Աշխատանքային հավելվածներ չկան"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Անձնական հավելվածներ չկան"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Բացե՞լ աշխատանքային <xliff:g id="APP">%s</xliff:g> հավելվածը"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Բացե՞լ անձնական <xliff:g id="APP">%s</xliff:g> հավելվածում"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Բացե՞լ աշխատանքային <xliff:g id="APP">%s</xliff:g> հավելվածում"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Զանգե՞լ աշխատանքային հավելվածից"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Անցնե՞լ աշխատանքային հավելվածի"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Ձեր կազմակերպությունը թույլատրում է ձեզ զանգեր կատարել միայն աշխատանքային հավելվածներից"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Ձեր կազմակերպությունը թույլատրում է ձեզ հաղորդագրություններ ուղարկել միայն աշխատանքային հավելվածներից"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Օգտագործել անձնական դիտարկիչը"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Օգտագործել աշխատանքային դիտարկիչը"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Զանգել"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Անցնել"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM Network քարտի ապակողպման PIN"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM Network Subset քարտի ապակողպման PIN"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM Corporate քարտի ապակողպման PIN"</string>
@@ -2330,7 +2331,7 @@
     <string name="concurrent_display_notification_power_save_content" msgid="2198116070583851493">"Dual Screen-ն անհասանելի է, քանի որ Մարտկոցի տնտեսումը միացված է։ Դուք կարող եք անջատել այս գործառույթը Կարգավորումներում։"</string>
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"Անցնել Կարգավորումներ"</string>
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Անջատել"</string>
-    <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> սարքը կարգավորված է"</string>
+    <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> – կարգավորված է"</string>
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Ստեղնաշարի համար կարգավորված է <xliff:g id="LAYOUT_1">%s</xliff:g> դասավորությունը։ Հպեք փոփոխելու համար։"</string>
     <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Ստեղնաշարի համար կարգավորված են <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> դասավորությունները։ Հպեք փոփոխելու համար։"</string>
     <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Ստեղնաշարի համար կարգավորված են <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> դասավորությունները։ Հպեք փոփոխելու համար։"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index b536d84..4609fdf 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -701,7 +701,7 @@
     <!-- no translation found for face_acquired_mouth_covering_detected (8219428572168642593) -->
     <skip />
     <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Tidak dapat membuat model wajah Anda. Coba lagi."</string>
-    <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Kacamata hitam terdeteksi. Wajah Anda harus terlihat sepenuhnya."</string>
+    <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Kacamata hitam terdeteksi. Wajah harus terlihat sepenuhnya."</string>
     <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Penutup wajah terdeteksi. Wajah harus terlihat sepenuhnya."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Hapus"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Mengeraskan volume di atas tingkat yang disarankan?\n\nMendengarkan dengan volume keras dalam waktu yang lama dapat merusak pendengaran Anda."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Peringatan,\nAnda telah melampaui jumlah sinyal suara keras yang dapat didengarkan dengan aman dalam seminggu melalui headphone.\n\nMelebihi batas ini akan merusak pendengaran Anda secara permanen."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Peringatan,\nAnda telah melampaui 5 kali jumlah sinyal suara keras yang dapat didengarkan dengan aman dalam seminggu melalui headphone.\n\nVolume telah diturunkan untuk melindungi pendengaran Anda."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Level Anda mendengarkan media dapat menyebabkan kerusakan pendengaran jika dilakukan dalam waktu yang lama.\n\nTerus memutar media pada level ini untuk waktu yang lama dapat merusak pendengaran Anda."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Peringatan,\nAnda sedang mendengarkan konten dengan suara keras yang diputar pada level yang tidak aman.\n\nTerus mendengarkan suara sekeras ini akan merusak pendengaran Anda secara permanen."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Tetap mendengarkan dengan volume tinggi?\n\nVolume headphone tinggi selama lebih lama dari yang direkomendasikan, yang dapat merusak pendengaran Anda"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Suara keras terdeteksi\n\nVolume headphone tinggi selama lebih lama dari yang direkomendasikan, yang dapat merusak pendengaran Anda"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gunakan Pintasan Aksesibilitas?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Saat pintasan aktif, menekan kedua tombol volume selama 3 detik akan memulai fitur aksesibilitas."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Aktifkan pintasan untuk fitur aksesibilitas?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Batalkan jeda"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Tidak ada aplikasi kerja"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Tidak ada aplikasi pribadi"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Buka <xliff:g id="APP">%s</xliff:g> kerja?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Buka di <xliff:g id="APP">%s</xliff:g> pribadi?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Buka di <xliff:g id="APP">%s</xliff:g> kerja?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Telepon dari aplikasi kerja?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Beralih ke aplikasi kerja?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Organisasi Anda hanya mengizinkan menelepon dari aplikasi kerja"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Organisasi Anda hanya mengizinkan pengiriman pesan dari aplikasi kerja"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Gunakan browser pribadi"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Gunakan browser kerja"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Telepon"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Beralih"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN pembuka kunci SIM network"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN pembuka kunci SIM network subset"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN pembuka kunci SIM corporate"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 484f628..30f0bd9 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Fjarlægja"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Hækka hljóðstyrk umfram ráðlagðan styrk?\n\nEf hlustað er á háum hljóðstyrk í langan tíma kann það að skaða heyrnina."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Viðvörun,\nÞú hefur náð hámarksfjölda háværra hljóðmerkja sem öruggt er að hlusta á innan viku í heyrnartólum.\n\nEf farið er yfir þessi mörk veldur það varanlegum heyrnarskaða."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Viðvörun,\nÞú hefur náð fimmföldum hámarksfjölda háværra hljóðmerkja sem öruggt er að hlusta á innan viku í heyrnartólum.\n\nBúið er að lækka hljóðstyrkinn til að vernda heyrnina hjá þér."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Hljóðstyrkurinn sem þú notar til að hlusta á efni getur valdið heyrnarskaða við langvarandi notkun.\n\nLangvarandi spilun á þessum hljóðstyrk getur valdið heyrnarskaða."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Viðvörun,\nÞú ert að hlusta á hávært efni með of háum hljóðstyrk.\n\nEf þú heldur áfram að hlusta á þessum hljóðstyrk veldur það varanlegum heyrnarskaða."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Halda áfram að hlusta með háum hljóðstyrk?\n\nHljóðstyrkur í heyrnartólum hefur verið hár í lengri tíma en mælt er með sem gæti valdið heyrnarskaða"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Hátt hljóð greindist\n\nHljóðstyrkur í heyrnartólum hefur verið hærri en mælt er með sem gæti valdið heyrnarskaða"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Viltu nota aðgengisflýtileið?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Þegar flýtileiðin er virk er kveikt á aðgengiseiginleikanum með því að halda báðum hljóðstyrkshnöppunum inni í þrjár sekúndur."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Kveikja á flýtileið fyrir aðgangseiginleika?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Ljúka hléi"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Engin vinnuforrit"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Engin forrit til einkanota"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Opna <xliff:g id="APP">%s</xliff:g> með vinnuprófíl?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Opna í <xliff:g id="APP">%s</xliff:g> til einkanota?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Opna í <xliff:g id="APP">%s</xliff:g> með vinnuprófíl?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Hringja úr vinnuforriti?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Skipta yfir í vinnuforrit?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Fyrirtækið heimilar þér aðeins að hringja úr vinnuforritum"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Fyrirtækið heimilar þér aðeins að senda skilaboð úr vinnuforritum"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Nota einkavafra"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Nota vinnuvafra"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Hringja"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Skipta"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN-númer fyrir opnun á SIM-korti netkerfis"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN-númer fyrir opnun á SIM-korti netkerfishlutmengis"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN-númer fyrir opnun á SIM-korti fyrirtækis"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 6281e2c..f5c1c33 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -687,7 +687,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"Sposta il telefono verso sinistra"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"Sposta il telefono verso destra"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Guarda più direttamente verso il dispositivo."</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Impossibile vedere il volto. Tieni il telefono all\'altezza degli occhi."</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Volto non visible. Tieni lo smartphone all\'altezza degli occhi."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Troppo movimento. Tieni fermo il telefono."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Ripeti l\'acquisizione del volto."</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"Impossibile riconoscere il volto. Riprova."</string>
@@ -695,7 +695,7 @@
     <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Guarda dritto nel telefono"</string>
     <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Guarda dritto nel telefono"</string>
     <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Guarda dritto nel telefono"</string>
-    <string name="face_acquired_obscured" msgid="4917643294953326639">"Rimuovi tutto ciò che ti nasconde il viso."</string>
+    <string name="face_acquired_obscured" msgid="4917643294953326639">"Rimuovi tutto ciò che ti nasconde il viso"</string>
     <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Pulisci la parte superiore dello schermo, inclusa la barra nera"</string>
     <!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
     <skip />
@@ -703,7 +703,7 @@
     <skip />
     <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Impossibile creare il modello del volto. Riprova."</string>
     <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Sono stati rilevati occhiali scuri. Il tuo volto deve essere visibile per intero."</string>
-    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Rilevata mascherina. Il volto deve essere visibile per intero."</string>
+    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Il tuo volto è coperto. Deve essere visibile per intero."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="5085202213036026288">"Imposs. verificare volto. Hardware non disponibile."</string>
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Rimuovi"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vuoi aumentare il volume oltre il livello consigliato?\n\nL\'ascolto ad alto volume per lunghi periodi di tempo potrebbe danneggiare l\'udito."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Avviso,\nHai superato il limite di segnali audio a forte volume che è possibile ascoltare in sicurezza in una settimana tramite le cuffie.\n\nIl superamento di questo limite causerà danni permanenti al tuo udito."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Avviso,\nHai superato di 5 volte il limite di segnali audio a forte volume che è possibile ascoltare in sicurezza in una settimana tramite le cuffie.\n\nIl volume è stato abbassato per proteggere il tuo udito."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Il livello a cui stai ascoltando contenuti multimediali può causare danni all\'udito se viene usato per periodi di tempo prolungati.\n\nSe continui l\'ascolto a questo livello per lunghi periodi di tempo, il tuo udito potrebbe subire danni."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Avviso,\nStai ascoltando contenuti ad alto volume a un livello non sicuro.\n\nSe continui l\'ascolto a questo volume, il tuo udito subirà danni permanenti."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Vuoi continuare ad ascoltare a un volume alto?\n\nIl volume delle cuffie è rimasto alto per un periodo superiore a quello raccomandato, con il rischio di danneggiare l\'udito"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Rilevato un suono forte\n\nIl volume delle cuffie è più alto di quello raccomandato, con il rischio di danneggiare l\'udito"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Usare la scorciatoia Accessibilità?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Quando la scorciatoia è attiva, puoi premere entrambi i pulsanti del volume per tre secondi per avviare una funzione di accessibilità."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Vuoi attivare la scorciatoia per le funzioni di accessibilità?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Riattiva"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nessuna app di lavoro"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nessuna app personale"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Aprire l\'app <xliff:g id="APP">%s</xliff:g> di lavoro?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Aprire nell\'app <xliff:g id="APP">%s</xliff:g> personale?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Aprire nell\'app <xliff:g id="APP">%s</xliff:g> di lavoro?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Chiamare dall\'app di lavoro?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Vuoi passare all\'app di lavoro?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"La tua organizzazione consente di fare chiamate solo dalle app di lavoro"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"La tua organizzazione consente di inviare messaggi solo dalle app di lavoro"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usa il browser personale"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usa il browser di lavoro"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Chiama"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Passa"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN di sblocco rete SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN di sblocco sottoinsieme rete SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN sblocco aziendale SIM"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 8439391..4b0a874 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1371,7 +1371,7 @@
     <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"המכשיר זיהה התקן אודיו אנלוגי"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ההתקן שחיברת לא תואם לטלפון הזה. יש להקיש לקבלת מידע נוסף."</string>
     <string name="adb_active_notification_title" msgid="408390247354560331">"‏ניפוי באגים ב-USB מחובר"</string>
-    <string name="adb_active_notification_message" msgid="5617264033476778211">"‏יש להקיש כדי לכבות את ניפוי הבאגים ב-USB"</string>
+    <string name="adb_active_notification_message" msgid="5617264033476778211">"‏לכיבוי של ניפוי הבאגים ב-USB, יש להקיש"</string>
     <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"‏יש ללחוץ על ההתראה כדי להשבית ניפוי באגים ב-USB."</string>
     <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ניפוי הבאגים האלחוטי מחובר"</string>
     <string name="adbwifi_active_notification_message" msgid="930987922852867972">"יש להקיש כדי להשבית ניפוי באגים אלחוטי"</string>
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"הסרה"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"להגביר את עוצמת הקול מעל לרמה המומלצת?\n\nהאזנה בעוצמת קול גבוהה למשכי זמן ממושכים עלולה לפגוע בשמיעה."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"אזהרה,\nחרגת מגובה עוצמת הקול שאפשר להאזין לה בבטחה באמצעות אוזניות בפרק זמן של שבוע.\n\nחריגה מהמגבלה הזו תגרום נזק לצמיתות לשמיעה שלך."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"אזהרה,\nחרגת פי חמש מגובה עוצמת הקול שאפשר להאזין לה בבטחה באמצעות אוזניות בפרק זמן של שבוע.\n\nעוצמת הקול הוחלשה כדי להגן על השמיעה שלך."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"גובה עוצמת הקול שבה האזנת למדיה עלול לגרום לנזק לשמיעה כאשר הוא נמשך לפרקי זמן ארוכים.\n\nהמשך השמעה בעוצמת הקול הזו לפרקי זמן ארוכים עלול להזיק לשמיעה שלך."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"אזהרה,\nמתבצעת כעת האזנה לתוכן רועש המושמע בעוצמת קול לא בטוחה.\n\nהמשך האזנה בעוצמת הקול הזו יגרום נזק לצמיתות לשמיעה שלך."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"להמשיך להאזין בעוצמת קול גבוהה?\n\nעוצמת הקול של האוזניות הייתה גבוהה במשך יותר זמן מהמומלץ, מה שעלול להזיק לשמיעה"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"זוהה צליל חזק\n\nעוצמת הקול של האוזניות הייתה גבוהה מהמומלץ, מה שעלול להזיק לשמיעה"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"להשתמש בקיצור הדרך לתכונת הנגישות?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"כשקיצור הדרך מופעל, לחיצה על שני לחצני עוצמת הקול למשך שלוש שניות מפעילה את תכונת הנגישות."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"האם להפעיל את מקש הקיצור לתכונות הנגישות?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"ביטול ההשהיה"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"אין אפליקציות לעבודה"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"אין אפליקציות לשימוש אישי"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"לפתוח את <xliff:g id="APP">%s</xliff:g> בפרופיל העבודה?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"לפתוח את <xliff:g id="APP">%s</xliff:g> בפרופיל האישי?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"לפתוח את <xliff:g id="APP">%s</xliff:g> בפרופיל העבודה?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"להתקשר מהאפליקציה לעבודה?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"לעבור לאפליקציה לעבודה?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"בארגון שלך מאפשרים לבצע שיחות רק מאפליקציות לעבודה"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"בארגון שלך מאפשרים לשלוח הודעות רק מאפליקציות לעבודה"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"בדפדפן האישי"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"בדפדפן של העבודה"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"שיחה"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"מעבר"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"‏קוד אימות לביטול הנעילה של רשת SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"‏קוד אימות לביטול הנעילה של תת-קבוצה ברשת SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"‏קוד אימות לביטול הנעילה של כרטיס SIM עסקי"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index a0f8d8e3..43925cc 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -329,7 +329,7 @@
     <string name="permgrouplab_sensors" msgid="9134046949784064495">"ボディセンサー"</string>
     <string name="permgroupdesc_sensors" msgid="2610631290633747752">"バイタルサインに関するセンサーデータへのアクセス"</string>
     <string name="permgrouplab_notifications" msgid="5472972361980668884">"通知"</string>
-    <string name="permgroupdesc_notifications" msgid="4608679556801506580">"通知の表示"</string>
+    <string name="permgroupdesc_notifications" msgid="4608679556801506580">"通知を表示"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"ウィンドウコンテンツの取得"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"ユーザーがアクセスしているウィンドウのコンテンツを検査します。"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"タッチガイドの有効化"</string>
@@ -479,7 +479,7 @@
     <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"このアプリは、使用中に、位置情報サービスからデバイスの正確な位置情報を取得できます。アプリが位置情報を取得するには、デバイスで位置情報サービスが ON になっている必要があります。この場合、バッテリー使用量が増えることがあります。"</string>
     <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"フォアグラウンドでのみおおよその位置情報にアクセス"</string>
     <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"このアプリは、使用中に、位置情報サービスからデバイスのおおよその位置情報を取得できます。アプリが位置情報を取得するには、デバイスで位置情報サービスがオンになっている必要があります。"</string>
-    <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"バックグラウンドでの位置情報へのアクセス"</string>
+    <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"バックグラウンドで位置情報にアクセスする"</string>
     <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"このアプリは、使用中でない場合でも、常に位置情報にアクセスできます。"</string>
     <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"音声設定の変更"</string>
     <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"音声全般の設定(音量、出力に使用するスピーカーなど)の変更をアプリに許可します。"</string>
@@ -594,7 +594,7 @@
     <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"キーロックとキーロックに関連付けられたパスワードのセキュリティを無効にすることをアプリに許可します。たとえば、かかってきた電話を受ける際にキーロックを無効にし、通話が終了したらキーロックを再度有効にする場合などに使用します。"</string>
     <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"画面ロックの複雑さのリクエスト"</string>
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"このアプリに画面ロックの複雑さレベル(高、中、低、なし)を認識することを許可します。複雑さレベルは、画面ロックの文字数の範囲やタイプを示すものです。アプリから一定レベルまで画面ロックを更新するよう推奨されることもありますが、ユーザーは無視したり別の操作を行ったりできます。画面ロックは平文で保存されないため、アプリが正確なパスワードを知ることはありません。"</string>
-    <string name="permlab_postNotification" msgid="4875401198597803658">"通知の表示"</string>
+    <string name="permlab_postNotification" msgid="4875401198597803658">"通知を表示"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"通知の表示をアプリに許可"</string>
     <string name="permlab_turnScreenOn" msgid="219344053664171492">"画面をオンにする"</string>
     <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"画面をオンにすることをアプリに許可します。"</string>
@@ -648,8 +648,8 @@
     <string name="fingerprint_error_timeout" msgid="7361192266621252164">"指紋の設定がタイムアウトしました。もう一度お試しください。"</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"指紋の操作をキャンセルしました。"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"指紋の操作がユーザーによりキャンセルされました。"</string>
-    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"試行回数が上限を超えました。代わりに画面ロックを使用してください。"</string>
-    <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"試行回数が上限を超えました。代わりに画面ロックを使用してください。"</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"試行回数が上限を超えました。代わりに PIN を入力してください。"</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"試行回数が上限を超えました。代わりに PIN を入力してください。"</string>
     <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"指紋を処理できません。もう一度お試しください。"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"指紋が登録されていません。"</string>
     <string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"このデバイスには指紋認証センサーがありません。"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" - "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"削除"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"推奨レベルを超えるまで音量を上げますか?\n\n大音量で長時間聞き続けると、聴力を損なう恐れがあります。"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"警告\nこの 1 週間のヘッドフォンの音量は、聴覚に影響を及ぼす可能性のある大きさを超えていました。\n\nこの限度を超えると聴力を損ない、元に戻らなくなるおそれがあります。"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"警告\nこの 1 週間のヘッドフォンの音量は、聴覚に影響を及ぼす可能性のある大きさを超えることが 5 回ありました。\n\n聴力を守るために音量を下げました。"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"メディアを長期間聴く際の音量によっては、聴覚の障害を招くことがあります。\n\nこのような音量で長期間再生していると、聴覚に影響を及ぼすおそれがあります。"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"警告\n現在、安全なレベルを超えた大音量でコンテンツを再生しています。\n\nこの音量で聴き続けると聴力を損ない、元に戻らなくなるおそれがあります。"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"このまま大音量で聴き続けますか?\n\nおすすめの時間よりも長い時間にわたってヘッドフォンの音量が大きいため、聴力を損なうおそれがあります"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"大きな音が検知されました\n\nヘッドフォンの音量がおすすめの音量よりも大きいため、聴力を損なうおそれがあります"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ユーザー補助機能のショートカットの使用"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ショートカットが ON の場合、両方の音量ボタンを 3 秒ほど長押しするとユーザー補助機能が起動します。"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"ユーザー補助機能のショートカットを ON にしますか?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"停止解除"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"仕事用アプリはありません"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"個人用アプリはありません"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"仕事用の <xliff:g id="APP">%s</xliff:g> を開きますか?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"個人用の <xliff:g id="APP">%s</xliff:g> で開きますか?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"仕事用の <xliff:g id="APP">%s</xliff:g> で開きますか?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"仕事用アプリからの通話ですか?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"仕事用アプリに切り替えますか?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"組織では、仕事用アプリからの通話のみ許可されています"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"組織では、仕事用アプリからのメッセージ送信のみ許可されています"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"個人用ブラウザを使用"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"仕事用ブラウザを使用"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"通話"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"切り替える"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM のネットワーク ロック解除 PIN"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM のネットワーク サブネットのロック解除 PIN"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM の企業ロック解除 PIN"</string>
@@ -2331,10 +2332,10 @@
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"設定に移動"</string>
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"OFF にする"</string>
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g>の設定完了"</string>
-    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%s</xliff:g>に設定されています。タップすると変更できます。"</string>
-    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>に設定されています。タップすると変更できます。"</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>に設定されています。タップすると変更できます。"</string>
-    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>に設定されています。タップすると変更できます。"</string>
+    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%s</xliff:g>に設定されています。タップで変更できます。"</string>
+    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>に設定されています。タップで変更できます。"</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>に設定されています。タップで変更できます。"</string>
+    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>に設定されています。タップで変更できます。"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"物理キーボードの設定完了"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"タップするとキーボードを表示できます"</string>
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 9499ffa..f22942d 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -635,7 +635,7 @@
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ზედმეტად ნათელია"</string>
     <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"აღმოჩენილია Ძლიერი დაჭერა"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ცადეთ დარეგულირება"</string>
-    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ოდნავ შეცვალეთ თითის დაჭერის ადგილი ყოველ ჯერზე"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ოდნავ შეცვალეთ დაჭერის ადგილი ყოველ ჯერზე"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_error_not_match" msgid="4599441812893438961">"თითის ანაბეჭდის ამოცნობა ვერ მოხერხდა"</string>
@@ -686,7 +686,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"გაწიეთ ტელეფონი თქვენგან მარცხნივ"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"გაწიეთ ტელეფონი თქვენგან მარჯვნივ"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"გთხოვთ, უფრო პირდაპირ შეხედოთ თქვენს მოწყობილობას."</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"თქვენი სახე არ ჩანს. დაიჭირეთ ტელეფონი თვალის დონეზე."</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"სახე არ ჩანს. დაიჭირეთ ტელ. თვალის დონეზე."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"მეტისმეტად მოძრაობთ. მყარად დაიჭირეთ ტელეფონი."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"გთხოვთ, ხელახლა დაარეგისტრიროთ თქვენი სახე."</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"სახის ამოცნობა ვერ ხერხდება. ცადეთ ხელახლა."</string>
@@ -702,7 +702,7 @@
     <skip />
     <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"თქვენი სახის მოდელი ვერ იქმნება. ცადეთ ხელახლა."</string>
     <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"აღმოჩენილია მუქი სათვალე. თქვენი სახე მთლიანად უნდა ჩანდეს."</string>
-    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"აღმოჩენილია სახის დაფარვა. თქვენი სახე მთლიანად უნდა ჩანდეს."</string>
+    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"სახე დაფარულია. ის მთლიანად უნდა ჩანდეს."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="5085202213036026288">"სახე ვერ დასტურდება. აპარატი მიუწვდომელია."</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"ამოშლა"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"გსურთ ხმის რეკომენდებულ დონეზე მაღლა აწევა?\n\nხანგრძლივად ხმამაღლა მოსმენით შესაძლოა სმენადობა დაიზიანოთ."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"გაფრთხილება,\nთქვენ გადააჭარბეთ ყურსასმენებით ერთ კვირაში ხმამაღალი სიგნალების უსაფრთხოდ მოსმენის დასაშვებ რაოდენობას.\n\nმოცემულ ზღვარს თუ გადააჭარბებთ, ეს სამუდამოდ დაგიზიანებთ სმენას."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"გაფრთხილება,\nთქვენ 5-ჯერ გადააჭარბეთ ყურსასმენებით ერთ კვირაში ხმამაღალი სიგნალების უსაფრთხოდ მოსმენის დასაშვებ რაოდენობას.\n\nხმა დაწეულია თქვენი სმენის დასაცავად."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"ხმის დონეს, რომელზეც მედიას უსმენთ, შეიძლება შედეგად მოყვეს სმენის დაზიანება თუ ამას ხანგრძლივად გააგრძელებთ.\n\nთუ გააგრძელებთ ხანგრძლივად დაკვრას ხმის მოცემულ დონეზე, ამან შეიძლება დააზიანოს თქვენი სმენა."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"გაფრთხილება,\nამჟამად უსმენთ ხმამაღალ კონტენტს, რომლის დაკვრის ხმის დონე არ არის უსაფრთხო.\n\nასეთი ხმამაღალი კონტენტის დაკვრა სამუდამოდ დაგიზიანებთ სმენას."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"განაგრძობთ მაღალ ხმაზე მოსმენას?\n\nყურსასმენების ხმა მაღალი იყო რეკომენდებულზე დიდხანს, რამაც შესაძლოა თქვენი სმენა დააზიანოს"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"მაღალი ხმაა ამოცნობილი\n\nყურსასმენების ხმა რეკომენდებულზე მაღალი იყო, რამაც შესაძლოა თქვენი სმენა დააზიანოს"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"გსურთ მარტივი წვდომის მალსახმობის გამოყენება?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"თუ მალსახმობი ჩართულია, ხმის ორივე ღილაკზე 3 წამის განმავლობაში დაჭერით მარტივი წვდომის ფუნქცია ჩაირთვება."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"ჩაირთოს მარტივი წვდომის ფუნქციების მალსახმობი?"</string>
@@ -1952,8 +1950,8 @@
     <string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> ამჟამად მიუწვდომელია. ის იმართება <xliff:g id="APP_NAME_1">%2$s</xliff:g>-ის მიერ."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"შეიტყვეთ მეტი"</string>
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"აპის დაპაუზების გაუქმება"</string>
-    <string name="work_mode_off_title" msgid="6367463960165135829">"გაუქმდეს სამსახურის აპების დაპაუზება?"</string>
-    <string name="work_mode_turn_on" msgid="5316648862401307800">"პაუზის გაუქმება"</string>
+    <string name="work_mode_off_title" msgid="6367463960165135829">"კვლავ გააქტიურდეს სამსახურის აპები?"</string>
+    <string name="work_mode_turn_on" msgid="5316648862401307800">"გააქტიურება"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"საგანგებო სიტუაცია"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"აპი მიუწვდომელია"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ამჟამად მიუწვდომელია."</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"პაუზის გაუქმება"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"სამსახურის აპები არ არის"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"პირადი აპები არ არის"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"გსურთ, სამსახურის <xliff:g id="APP">%s</xliff:g>-ის გახსნა?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"გსურთ, პირად <xliff:g id="APP">%s</xliff:g>-ში გახსნა?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"გსურთ, სამსახურის <xliff:g id="APP">%s</xliff:g>-ში გახსნა?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"სამსახურის აპიდან დარეკავთ?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"გადაერთვებით სამუშაო აპზე?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"თქვენი ორგანიზაცია ნებას გრთავთ, რომ დარეკოთ მხოლოდ სამსახურის აპებიდან"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"თქვენი ორგანიზაცია ნებას გრთავთ, მხოლოდ სამსახურის აპებიდან გაგზავნოთ შეტყობინებები"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"პირადი ბრაუზერის გამოყენება"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"სამსახურის ბრაუზერის გამოყენება"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"ზარი"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"გადართვა"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM ქსელის განბლოკვის PIN-კოდი"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM ქსელის ქვედანაყოფის განბლოკვის PIN-კოდი"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM-ის კორპორატიული განბლოკვის PIN-კოდი"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index b074b49..e972e8c 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -702,7 +702,7 @@
     <skip />
     <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Бет үлгісі жасалмады. Қайталап көріңіз."</string>
     <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Қою түсті көзілдірік анықталды. Бетіңіз толық көрініп тұруы керек."</string>
-    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Бетперде анықталды. Бетіңіз толық көрініп тұруы керек."</string>
+    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Бетперде тағып алғансыз. Бетіңіз толық көрініп тұруы керек."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="5085202213036026288">"Бетті тану мүмкін емес. Жабдық қолжетімді емес."</string>
@@ -1396,7 +1396,7 @@
     <string name="hardware" msgid="1800597768237606953">"Виртуалдық пернетақтаны көрсету"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> конфигурациялау"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Физикалық пернетақталарды конфигурациялау"</string>
-    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Тіл мен пернетақта схемасын таңдау үшін түртіңіз"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Тіл мен пернетақта схемасын таңдау үшін түртіңіз."</string>
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Басқа қолданбалардың үстінен көрсету"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Жою"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Дыбыс деңгейін ұсынылған деңгейден көтеру керек пе?\n\nЖоғары дыбыс деңгейінде ұзақ кезеңдер бойы тыңдау есту қабілетіңізге зиян тигізуі мүмкін."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Ескерту!\nҚұлақаспап арқылы бір аптада қауіпсіз тыңдауға болатын қатты дыбыстық сигналдар санын асырып жібердіңіз.\n\nБұл лимиттен асыру есту мүшесінің біржола зақымдалуына себеп болады."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Ескерту!\nҚұлақаспап арқылы бір аптада қауіпсіз тыңдауға болатын қатты дыбыстық сигналдар санын 5 рет асырып жібердіңіз.\n\nЕсту мүшесін қорғау үшін дыбыс деңгейі төмендетілді."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Сіз медиафайлды тыңдап жатқан дауыс деңгейі ұзақ уақыт ойнату жағдайында есту мүшесін зақымдауы мүмкін.\n\nҰзақ уақыт бойы осы дыбыс деңгейімен ойнату есту мүшесін зақымдауы ықтимал."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Ескерту!\nҚазір дауысы тым қатты контентті тыңдап жатырсыз, оның деңгейі қауіпті.\n\nОсылай тым қатты тыңдауды жалғастыру есту мүшесін біржола зақымдайды."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Жоғары дыбыс деңгейінде тыңдай бересіз бе?\n\nҚұлақаспаптың жоғары дыбыс деңгейі ұсынылған уақыттан ұзақ қосылып тұрды. Есту мүшеңізге зияны тиюі мүмкін."</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Қатты дыбыс анықталды\n\nҚұлақаспаптың жоғары дыбыс деңгейі ұсынылған уақыттан ұзақ қосылып тұрды. Есту мүшеңізге зияны тиюі мүмкін."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Арнайы мүмкіндік төте жолын пайдалану керек пе?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Түймелер тіркесімі қосулы кезде, екі дыбыс түймесін 3 секунд басып тұрсаңыз, \"Арнайы мүмкіндіктер\" функциясы іске қосылады."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Арнайы мүмкіндіктердің жылдам пәрмені іске қосылсын ба?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Қайта қосу"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Жұмыс қолданбалары жоқ."</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Жеке қолданбалар жоқ."</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"<xliff:g id="APP">%s</xliff:g> қолданбасы жұмыс профилімен ашылсын ба?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"<xliff:g id="APP">%s</xliff:g> қолданбасындағы жеке профильден ашылсын ба?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"<xliff:g id="APP">%s</xliff:g> қолданбасындағы жұмыс профилінен ашылсын ба?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Жұмыс қолданбасынан қоңырау шалу керек пе?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Жұмыс қолданбасына ауысу керек пе?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Ұйымыңыз тек жұмыс қолданбаларынан қоңырау шалуға рұқсат етеді."</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Ұйымыңыз тек жұмыс қолданбаларынан хабар жіберуге рұқсат етеді."</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Жеке браузерді пайдалану"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Жұмыс браузерін пайдалану"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Қоңырау шалу"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Ауысу"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM желісінің құлпын ашатын PIN коды"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM желісі ішкі жиынтығының құлпын ашатын PIN коды"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Корпоративтік SIM картасының құлпын ашатын PIN коды"</string>
@@ -2331,10 +2332,10 @@
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"Параметрлерге өту"</string>
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Өшіру"</string>
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> конфигурацияланды"</string>
-    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Пернетақта форматы <xliff:g id="LAYOUT_1">%s</xliff:g> деп орнатылды. Өзгерту үшін түртіңіз."</string>
-    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Пернетақта форматы <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> деп орнатылды. Өзгерту үшін түртіңіз."</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Пернетақта форматы <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> деп орнатылды. Өзгерту үшін түртіңіз."</string>
-    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Пернетақта форматы <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> деп орнатылды… Өзгерту үшін түртіңіз."</string>
+    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Пернетақта схемасы \"<xliff:g id="LAYOUT_1">%s</xliff:g>\" деп орнатылды. Өзгерту үшін түртіңіз."</string>
+    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Пернетақта схемасы \"<xliff:g id="LAYOUT_1">%1$s</xliff:g>\", \"<xliff:g id="LAYOUT_2">%2$s</xliff:g>\" деп орнатылды. Өзгерту үшін түртіңіз."</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Пернетақта схемасы \"<xliff:g id="LAYOUT_1">%1$s</xliff:g>\", \"<xliff:g id="LAYOUT_2">%2$s</xliff:g>\", \"<xliff:g id="LAYOUT_3">%3$s</xliff:g>\" деп орнатылды. Өзгерту үшін түртіңіз."</string>
+    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Пернетақта схемасы \"<xliff:g id="LAYOUT_1">%1$s</xliff:g>\", \"<xliff:g id="LAYOUT_2">%2$s</xliff:g>\", \"<xliff:g id="LAYOUT_3">%3$s</xliff:g>\" деп орнатылды… Өзгерту үшін түртіңіз."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физикалық пернетақталар конфигурацияланды"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Пернетақталарды көру үшін түртіңіз."</string>
 </resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 8dbe390..9dc2d97 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -625,11 +625,11 @@
     <string name="biometric_error_generic" msgid="6784371929985434439">"មានបញ្ហាក្នុង​ការផ្ទៀងផ្ទាត់"</string>
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"ប្រើ​ការ​ចាក់​សោ​អេក្រង់"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"បញ្ចូលការចាក់សោអេក្រង់របស់អ្នក ដើម្បីបន្ត"</string>
-    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"សង្កត់លើ​ឧបករណ៍​ចាប់សញ្ញា​ឱ្យណែន"</string>
+    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"សង្កត់លើ​សេនស័រឱ្យណែន"</string>
     <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"មិនអាចសម្គាល់​ស្នាមម្រាមដៃបានទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"សម្អាត​ឧបករណ៍​ចាប់ស្នាមម្រាមដៃ រួចព្យាយាម​ម្ដងទៀត"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"សម្អាត​ឧបករណ៍​ចាប់សញ្ញា រួចព្យាយាម​ម្ដងទៀត"</string>
-    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"សង្កត់លើ​ឧបករណ៍​ចាប់សញ្ញា​ឱ្យណែន"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"សង្កត់លើ​សេនស័រឱ្យណែន"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"ចលនាម្រាមដៃយឺតពេកហើយ។ សូមព្យាយាមម្តងទៀត។"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"សាកល្បងប្រើ​ស្នាមម្រាមដៃផ្សេងទៀត"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ភ្លឺពេក"</string>
@@ -656,7 +656,7 @@
     <string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"បានបិទ​ឧបករណ៍​ចាប់សញ្ញាជា​បណ្តោះអាសន្ន។"</string>
     <string name="fingerprint_error_bad_calibration" msgid="4385512597740168120">"មិនអាចប្រើ​ឧបករណ៍ចាប់ស្នាមម្រាមដៃ​បានទេ។ សូមទាក់ទង​ក្រុមហ៊ុនផ្ដល់​ការជួសជុល"</string>
     <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"បាន​ចុច​ប៊ូតុង​ថាមពល"</string>
-    <string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃ <xliff:g id="FINGERID">%d</xliff:g>"</string>
+    <string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃទី <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"ប្រើស្នាមម្រាមដៃ"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"ប្រើស្នាមម្រាមដៃ ឬ​ការចាក់សោអេក្រង់"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ប្រើ​ស្នាមម្រាមដៃ​របស់អ្នក ដើម្បីបន្ត"</string>
@@ -665,15 +665,15 @@
   </string-array>
     <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"មានអ្វីមួយខុសប្រក្រតី។ សូមព្យាយាមម្ដងទៀត។"</string>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"រូបស្នាមម្រាមដៃ"</string>
-    <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ដោះ​សោ​តាម​​ទម្រង់​មុខ"</string>
+    <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"ការដោះ​សោ​ដោយស្កេន​មុខ"</string>
     <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"មានបញ្ហា​ពាក់ព័ន្ធនឹង​មុខងារ​ដោះសោ​តាមទម្រង់មុខ"</string>
     <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"ចុចដើម្បីលុប​គំរូមុខ​របស់អ្នក រួចបញ្ចូល​មុខរបស់អ្នក​ម្ដងទៀត"</string>
-    <string name="face_setup_notification_title" msgid="8843461561970741790">"រៀបចំ​ការដោះសោ​តាមទម្រង់មុខ"</string>
+    <string name="face_setup_notification_title" msgid="8843461561970741790">"រៀបចំ​ការដោះសោ​ដោយស្កេនមុខ"</string>
     <string name="face_setup_notification_content" msgid="5463999831057751676">"ដោះសោទូរសព្ទ​របស់អ្នកដោយសម្លឹងមើលវា"</string>
     <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"ដើម្បីប្រើមុខងារដោះសោតាមទម្រង់មុខ សូមបើក"<b>"ការចូលប្រើកាមេរ៉ា"</b>"នៅក្នុងការកំណត់ &gt; ឯកជនភាព"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"រៀបចំ​វិធីច្រើនទៀត​ដើម្បី​ដោះសោ"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"ចុច​ដើម្បីបញ្ចូល​ស្នាមម្រាមដៃ"</string>
-    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ការដោះសោ​ដោយប្រើ​ស្នាមម្រាមដៃ"</string>
+    <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"ការដោះសោ​ដោយស្កេន​ស្នាមម្រាមដៃ"</string>
     <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"មិនអាចប្រើ​ឧបករណ៍ចាប់ស្នាមម្រាមដៃ​បានទេ"</string>
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"ទាក់ទងក្រុមហ៊ុន​ផ្ដល់ការជួសជុល។"</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"មិនអាចបង្កើតគំរូមុខរបស់អ្នកបានទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"លុប​ចេញ"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"បង្កើន​កម្រិត​សំឡេង​លើស​ពី​កម្រិត​បាន​ផ្ដល់​យោបល់?\n\nការ​ស្ដាប់​នៅ​កម្រិត​សំឡេង​ខ្លាំង​យូរ​អាច​ធ្វើឲ្យ​ខូច​ត្រចៀក។"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"សូមប្រុងប្រយ័ត្ន\nអ្នកបានលើសបរិមាណ​រលកសញ្ញាសំឡេងឮខ្លាំងដែលមនុស្សអាចស្ដាប់តាមកាស​បានដោយសុវត្ថិភាពក្នុងរយៈពេលមួយសប្ដាហ៍។\n\nការស្ដាប់លើសដែនកំណត់នេះ​នឹងបណ្ដាលឱ្យខូចត្រចៀករបស់អ្នក​ជាអចិន្ត្រៃយ៍។"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"សូមប្រុងប្រយ័ត្ន\nអ្នកបានលើសបរិមាណរលក​សញ្ញាសំឡេងឮខ្លាំងចំនួន 5 ដង ដែលមនុស្សអាចស្ដាប់តាមកាស​បានដោយសុវត្ថិភាពក្នុងរយៈពេលមួយសប្ដាហ៍។\n\nកម្រិតសំឡេងត្រូវបានបន្ថយ ដើម្បីការពារត្រចៀករបស់អ្នក។"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"កម្រិតដែលអ្នក​កំពុងស្ដាប់មេឌៀអាច​បណ្ដាលឱ្យខូច​ត្រចៀក នៅពលស្ដាប់ក្នុង​រយៈពេលយូរ។\n\nការបន្តចាក់នៅកម្រិតនេះ​ក្នុងរយៈពេលយូរ​អាចធ្វើឱ្យត្រចៀករបស់អ្នកខូច។"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"សូមប្រុងប្រយ័ត្ន\nបច្ចុប្បន្ន អ្នកកំពុងស្ដាប់ខ្លឹមសារឮខ្លាំង​ដែលបានចាក់នៅកម្រិត​គ្មានសុវត្ថិភាព។\n\nការបន្តស្ដាប់ឮខ្លាំងបែបនេះ​នឹងធ្វើឱ្យត្រចៀករបស់អ្នក​ខូចជាអចិន្ត្រៃយ៍។"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"បន្តស្ដាប់ក្នុងកម្រិតសំឡេងខ្ពស់ឬ?\n\nកម្រិតសំឡេងកាសមានកម្រិតខ្ពស់យូរជាងរយៈពេលដែលបានណែនាំ ដែលអាចបណ្ដាលឱ្យខូចត្រចៀករបស់អ្នក"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"បានចាប់ដឹងថាសំឡេងឮខ្លាំង\n\nកម្រិតសំឡេងកាសខ្ពស់ជាងកម្រិតដែលបានណែនាំ ដែលអាចបណ្ដាលឱ្យខូចត្រចៀករបស់អ្នក"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ប្រើប្រាស់​ផ្លូវកាត់​ភាព​ងាយស្រួល?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"នៅពេលបើក​ផ្លូវកាត់ ការចុច​ប៊ូតុង​កម្រិតសំឡេង​ទាំងពីរ​រយៈពេល 3 វិនាទី​នឹង​ចាប់ផ្តើម​មុខងារ​ភាពងាយប្រើ។"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"បើក​ផ្លូវកាត់​សម្រាប់មុខងារ​ភាពងាយស្រួលឬ?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"ឈប់ផ្អាក"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"គ្មាន​កម្មវិធី​ការងារ​ទេ"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"គ្មាន​កម្មវិធី​ផ្ទាល់ខ្លួន​ទេ"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"បើក <xliff:g id="APP">%s</xliff:g> ការងារឬ?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"បើកនៅក្នុង <xliff:g id="APP">%s</xliff:g> ផ្ទាល់ខ្លួនឬ?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"បើកនៅក្នុង <xliff:g id="APP">%s</xliff:g> ការងារឬ?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"ហៅទូរសព្ទពី​កម្មវិធីការងារឬ?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ប្ដូរទៅកម្មវិធីការងារឬ?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"ស្ថាប័ន​របស់អ្នក​អនុញ្ញាត​ឱ្យអ្នកធ្វើការហៅទូរសព្ទ​ពីកម្មវិធីការងារ​តែប៉ុណ្ណោះ"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"ស្ថាប័ន​របស់អ្នក​អនុញ្ញាត​ឱ្យអ្នក​ផ្ញើសារ​ពី​កម្មវិធី​ការងារតែប៉ុណ្ណោះ"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ប្រើ​កម្មវិធីរុករក​តាមអ៊ីនធឺណិត​ផ្ទាល់ខ្លួន"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ប្រើ​កម្មវិធីរុករក​តាមអ៊ីនធឺណិត​សម្រាប់​ការងារ"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"ហៅទូរសព្ទ"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"ប្ដូរ"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"កូដ PIN ដោះ​សោ​បណ្ដាញ​ស៊ីម"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"កូដ PIN ដោះសោ​សំណុំរង​នៃ​បណ្ដាញស៊ីម"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"កូដ PIN ដោះសោ​ក្រុមហ៊ុនស៊ីម"</string>
@@ -2331,9 +2332,9 @@
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"ចូលទៅកាន់ \"ការកំណត់\""</string>
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"បិទ"</string>
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"បានកំណត់​រចនាសម្ព័ន្ធ <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
-    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"បានកំណត់ប្លង់ក្ដារចុចទៅ <xliff:g id="LAYOUT_1">%s</xliff:g>។ សូមចុចដើម្បីប្ដូរ។"</string>
-    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"បានកំណត់ប្លង់ក្ដារចុចទៅ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>។ សូមចុចដើម្បីប្ដូរ។"</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"បានកំណត់ប្លង់ក្ដារចុចទៅ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>។ សូមចុចដើម្បីប្ដូរ។"</string>
+    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"បានកំណត់ប្លង់ក្ដារចុចទៅ <xliff:g id="LAYOUT_1">%s</xliff:g>។ ចុចដើម្បីប្ដូរ។"</string>
+    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"បានកំណត់ប្លង់ក្ដារចុចទៅ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>។ ចុចដើម្បីប្ដូរ។"</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"បានកំណត់ប្លង់ក្ដារចុចទៅ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>។ ចុចដើម្បីប្ដូរ។"</string>
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"បានកំណត់ប្លង់ក្ដារចុចទៅ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… សូមចុចដើម្បីប្ដូរ។"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"បានកំណត់រចនាសម្ព័ន្ធ​ក្ដារចុចរូបវន្ត"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ចុចដើម្បីមើលក្ដារចុច"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 181e10a..c6d6aff 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -270,7 +270,7 @@
     <string name="global_action_voice_assist" msgid="6655788068555086695">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
     <string name="global_action_lockdown" msgid="2475471405907902963">"ಲಾಕ್‌ಡೌನ್‌"</string>
     <string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
-    <string name="notification_hidden_text" msgid="2835519769868187223">"ಹೊಸ ಅಧಿಸೂಚನೆ"</string>
+    <string name="notification_hidden_text" msgid="2835519769868187223">"ಹೊಸ ನೋಟಿಫಿಕೇಶನ್‍"</string>
     <string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್‌"</string>
     <string name="notification_channel_security" msgid="8516754650348238057">"ಭದ್ರತೆ"</string>
     <string name="notification_channel_car_mode" msgid="2123919247040988436">"ಕಾರ್ ಮೋಡ್"</string>
@@ -471,7 +471,7 @@
     <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಫೋನ್‌ನಲ್ಲಿ ಸಂಗ್ರಹವಾಗಿರುವ ಎಲ್ಲಾ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳನ್ನು ಓದಬಹುದು ಮತ್ತು ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು ಅಥವಾ ಉಳಿಸಬಹುದು."</string>
     <string name="permlab_writeCalendar" msgid="6422137308329578076">"ಮಾಲೀಕರ ಗಮನಕ್ಕೆ ತರದೆಯೇ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳನ್ನು ಸೇರಿಸಿ ಅಥವಾ ಮಾರ್ಪಡಿಸಿ ಮತ್ತು ಅತಿಥಿಗಳಿಗೆ ಇಮೇಲ್ ಕಳುಹಿಸಿ"</string>
     <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌ನಲ್ಲಿ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳನ್ನು ಸೇರಿಸಬಹುದು, ತೆಗೆದುಹಾಕಬಹುದು ಅಥವಾ ಬದಲಾಯಿಸಬಹುದು. ಈ ಅಪ್ಲಿಕೇಶನ್ ಕ್ಯಾಲೆಂಡರ್‌ನ ಮಾಲೀಕರಿಂದ ಬಂದಿರಬಹುದಾದ ಕಾಣಿಸಿಕೊಳ್ಳುವ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬಹುದು ಅಥವಾ ಅವರ ಮಾಲೀಕರಿಗೆ ತಿಳಿಸದಂತೆ ಘಟನೆಗಳು ಬದಲಾಯಿಸುವುದು."</string>
-    <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳನ್ನು ಸೇರಿಸಬಹುದು, ತೆಗೆದುಹಾಕಬಹುದು ಅಥವಾ ಬದಲಾಯಿಸಬಹುದು. ಈ ಅಪ್ಲಿಕೇಶನ್ ಕ್ಯಾಲೆಂಡರ್‌ನ ಮಾಲೀಕರಿಂದ ಬರುವಂತೆ ಕಾಣುವ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬಹುದು ಅಥವಾ ಅದರ ಮಾಲೀಕರಿಗೆ ಅಧಿಸೂಚನೆ ನೀಡದೆ ಈವೆಂಟ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಬಹುದು."</string>
+    <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳನ್ನು ಸೇರಿಸಬಹುದು, ತೆಗೆದುಹಾಕಬಹುದು ಅಥವಾ ಬದಲಾಯಿಸಬಹುದು. ಈ ಅಪ್ಲಿಕೇಶನ್ ಕ್ಯಾಲೆಂಡರ್‌ನ ಮಾಲೀಕರಿಂದ ಬರುವಂತೆ ಕಾಣುವ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬಹುದು ಅಥವಾ ಅದರ ಮಾಲೀಕರಿಗೆ ನೋಟಿಫಿಕೇಶನ್ ನೀಡದೆ ಈವೆಂಟ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಬಹುದು."</string>
     <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಫೋನ್‌ನಲ್ಲಿ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳನ್ನು ಸೇರಿಸಬಹುದು, ತೆಗೆದುಹಾಕಬಹುದು ಅಥವಾ ಬದಲಾಯಿಸಬಹುದು. ಈ ಅಪ್ಲಿಕೇಶನ್ ಕ್ಯಾಲೆಂಡರ್‌ನ ಮಾಲೀಕರಿಂದ ಬಂದಿರಬಹುದಾದ ಕಾಣಿಸಿಕೊಳ್ಳುವ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬಹುದು ಅಥವಾ ಅವರ ಮಾಲೀಕರಿಗೆ ತಿಳಿಸದಂತೆ ಘಟನೆಗಳು ಬದಲಾಯಿಸುವುದು."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"ಹೆಚ್ಚುವರಿ ಸ್ಥಳ ಪೂರೈಕೆದಾರರ ಆದೇಶಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"ಹೆಚ್ಚಿನ ಸ್ಥಳ ಪೂರೈಕೆದಾರ ಆದೇಶಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು GPS ಅಥವಾ ಇತರ ಸ್ಥಳ ಮೂಲಗಳ ಕಾರ್ಯಾಚರಣೆಯಲ್ಲಿ ಮಧ್ಯ ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅನುಮತಿಸಬಹುದು."</string>
@@ -766,8 +766,8 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"ಅಪ್ಲಿಕೇಶನ್‍‍ಗಳಿಗೆ ವಿರುದ್ಧವಾಗಿ ನೆಟ್‍‍ವರ್ಕ್ ಬಳಕೆಯನ್ನು ಹೇಗೆ ಲೆಕ್ಕಿಸಲಾಗಿದೆ ಎಂಬುದನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್‍‍ಗಳಲ್ಲಿ ಬಳಸಲಾಗುವುದಿಲ್ಲ."</string>
     <string name="permlab_accessNotifications" msgid="7130360248191984741">"ಅಧಿಸೂಚನೆಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
     <string name="permdesc_accessNotifications" msgid="761730149268789668">"ಇತರ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಮೂಲಕ ಪೋಸ್ಟ್ ಮಾಡಿರುವ ಅಧಿಸೂಚನೆಗಳೂ ಸೇರಿದಂತೆ, ಅಂತಹ ಅಧಿಸೂಚನೆಗಳನ್ನು ಹಿಂಪಡೆದುಕೊಳ್ಳಲು, ಪರೀಕ್ಷಿಸಲು ಮತ್ತು ತೆರವುಗೊಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
-    <string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"ಅಧಿಸೂಚನೆ ಕೇಳುಗರ ಸೇವೆಗೆ ಪ್ರತಿಬಂಧಿಸಿ"</string>
-    <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"ಅಧಿಸೂಚನೆ ಕೇಳುಗ ಸೇವೆಯ ಮೇಲ್ಮಟ್ಟದ ಇಂಟರ್ಫೇಸ್‌ಗೆ ಪ್ರತಿಬಂಧಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
+    <string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"ನೋಟಿಫಿಕೇಶನ್ ಕೇಳುಗರ ಸೇವೆಗೆ ಪ್ರತಿಬಂಧಿಸಿ"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"ನೋಟಿಫಿಕೇಶನ್ ಕೇಳುಗ ಸೇವೆಯ ಮೇಲ್ಮಟ್ಟದ ಇಂಟರ್ಫೇಸ್‌ಗೆ ಪ್ರತಿಬಂಧಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
     <string name="permlab_bindConditionProviderService" msgid="5245421224814878483">"ಕಂಡೀಶನ್‌‌ ಪೂರೈಕೆದಾರರ ಸೇವೆಯನ್ನು ಪ್ರತಿಬಂಧಿಸು"</string>
     <string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"ಕಂಡೀಶನ್‌ ಪೂರೈಕೆದಾರರ ಮೇಲ್ಮಟ್ಟದ ಇಂಟರ್ಫೇಸ್‌ಗೆ ಪ್ರತಿಬಂಧಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
     <string name="permlab_bindDreamService" msgid="4776175992848982706">"ಕನಸಿನ ಸೇವೆಗೆ ಪ್ರತಿಬಂಧಿಸಿ"</string>
@@ -1296,7 +1296,7 @@
     <string name="ringtone_silent" msgid="397111123930141876">"ಯಾವುದೂ ಇಲ್ಲ"</string>
     <string name="ringtone_picker_title" msgid="667342618626068253">"ರಿಂಗ್‌ಟೋನ್‌ಗಳು"</string>
     <string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"ಅಲಾರಮ್ ಧ್ವನಿಗಳು"</string>
-    <string name="ringtone_picker_title_notification" msgid="6387191794719608122">"ಅಧಿಸೂಚನೆ ಧ್ವನಿಗಳು"</string>
+    <string name="ringtone_picker_title_notification" msgid="6387191794719608122">"ನೋಟಿಫಿಕೇಶನ್ ಧ್ವನಿಗಳು"</string>
     <string name="ringtone_unknown" msgid="5059495249862816475">"ಅಪರಿಚಿತ"</string>
     <string name="wifi_available_sign_in" msgid="381054692557675237">"ವೈ-ಫೈ ನೆಟ್‍ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
     <string name="network_available_sign_in" msgid="1520342291829283114">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
@@ -1492,10 +1492,10 @@
     <string name="accessibility_binding_label" msgid="1974602776545801715">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ"</string>
     <string name="wallpaper_binding_label" msgid="1197440498000786738">"ವಾಲ್‌ಪೇಪರ್"</string>
     <string name="chooser_wallpaper" msgid="3082405680079923708">"ವಾಲ್‌ಪೇಪರ್ ಬದಲಿಸಿ"</string>
-    <string name="notification_listener_binding_label" msgid="2702165274471499713">"ಅಧಿಸೂಚನೆ ಕೇಳುಗ"</string>
+    <string name="notification_listener_binding_label" msgid="2702165274471499713">"ನೋಟಿಫಿಕೇಶನ್‍ ಕೇಳುಗ"</string>
     <string name="vr_listener_binding_label" msgid="8013112996671206429">"VR ಕೇಳುವಿಕೆ"</string>
     <string name="condition_provider_service_binding_label" msgid="8490641013951857673">"ಕಂಡೀಶನ್ ಪೂರೈಕೆದಾರರು"</string>
-    <string name="notification_ranker_binding_label" msgid="432708245635563763">"ಅಧಿಸೂಚನೆ ಶ್ರೇಣಿಯ ಸೇವೆ"</string>
+    <string name="notification_ranker_binding_label" msgid="432708245635563763">"ನೋಟಿಫಿಕೇಶನ್ ರ‍್ಯಾಂಕರ್ ಸೇವೆ"</string>
     <string name="vpn_title" msgid="5906991595291514182">"VPN ಸಕ್ರಿಯಗೊಂಡಿದೆ"</string>
     <string name="vpn_title_long" msgid="6834144390504619998">"<xliff:g id="APP">%s</xliff:g> ಮೂಲಕ VPN ಸಕ್ರಿಯಗೊಂಡಿದೆ"</string>
     <string name="vpn_text" msgid="2275388920267251078">"ನೆಟ್‍ವರ್ಕ್ ನಿರ್ವಹಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"ತೆಗೆದುಹಾಕು"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ವಾಲ್ಯೂಮ್‌ ಅನ್ನು ಶಿಫಾರಸು ಮಾಡಲಾದ ಮಟ್ಟಕ್ಕಿಂತಲೂ ಹೆಚ್ಚು ಮಾಡಬೇಕೆ?\n\nದೀರ್ಘ ಅವಧಿಯವರೆಗೆ ಹೆಚ್ಚಿನ ವಾಲ್ಯೂಮ್‌ನಲ್ಲಿ ಆಲಿಸುವುದರಿಂದ ನಿಮ್ಮ ಆಲಿಸುವಿಕೆ ಸಾಮರ್ಥ್ಯಕ್ಕೆ ಹಾನಿಯುಂಟು ಮಾಡಬಹುದು."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"ಎಚ್ಚರಿಕೆ,\nಒಬ್ಬ ವ್ಯಕ್ತಿ ಒಂದು ವಾರದಲ್ಲಿ ಹೆಡ್‌ಫೋನ್‌ಗಳ ಮೂಲಕ ಗಟ್ಟಿಯಾದ ವಾಲ್ಯೂಮ್‌ನಲ್ಲಿ ಸುರಕ್ಷಿತವಾಗಿ ಆಲಿಸಬಹುದಾದ ಮಿತಿಯನ್ನು ನೀವು ಮೀರಿದ್ದೀರಿ.\n\nಈ ಮಿತಿಯನ್ನು ಮೀರಿದರೆ ನಿಮ್ಮ ಆಲಿಸುವ ಸಾಮರ್ಥ್ಯಕ್ಕೆ ಶಾಶ್ವತ ಹಾನಿಯುಂಟಾಗುತ್ತದೆ."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"ಎಚ್ಚರಿಕೆ,\nಒಬ್ಬ ವ್ಯಕ್ತಿ ಒಂದು ವಾರದಲ್ಲಿ ಹೆಡ್‌ಫೋನ್‌ಗಳ ಮೂಲಕ ಸುರಕ್ಷಿತವಾಗಿ ಆಲಿಸಬಹುದಾದ ಗಟ್ಟಿಯಾದ ವಾಲ್ಯೂಮ್‌ನ 5 ಪಟ್ಟು ಮಿತಿಯನ್ನು ನೀವು ಮೀರಿದ್ದೀರಿ.\n\nನಿಮ್ಮ ಆಲಿಸುವ ಸಾಮರ್ಥ್ಯವನ್ನು ರಕ್ಷಿಸುವುದಕ್ಕಾಗಿ ವಾಲ್ಯೂಮ್ ಅನ್ನು ಕಡಿಮೆಗೊಳಿಸಲಾಗಿದೆ."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"ನೀವು ಪ್ರಸ್ತುತ ಆಲಿಸುತ್ತಿರುವ ವಾಲ್ಯೂಮ್‌ನಲ್ಲಿ ಮಾಧ್ಯಮವನ್ನು ಆಲಿಸುವುದನ್ನು ನೀವು ದೀರ್ಘಕಾಲ ಮುಂದುವರಿಸಿದರೆ, ನಿಮ್ಮ ಆಲಿಸುವ ಸಾಮರ್ಥ್ಯಕ್ಕೆ ಹಾನಿಯುಂಟಾಗಬಹುದು.\n\nಇದೇ ವಾಲ್ಯೂಮ್‌ನಲ್ಲಿ ದೀರ್ಘಕಾಲದವರೆಗೆ ಮಾಧ್ಯಮವನ್ನು ಪ್ಲೇ ಮಾಡುವುದನ್ನು ಮುಂದುವರಿಸಿದರೆ ನಿಮ್ಮ ಆಲಿಸುವ ಸಾಮರ್ಥ್ಯಕ್ಕೆ ಹಾನಿಯುಂಟಾಗಬಹುದು."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"ಎಚ್ಚರಿಕೆ,\nನೀವು ಪ್ರಸ್ತುತ ಅಸುರಕ್ಷಿತ ವಾಲ್ಯೂಮ್‌ನಲ್ಲಿ ಪ್ಲೇ ಆಗುತ್ತಿರುವ ಮಾಧ್ಯಮವನ್ನು ಆಲಿಸುತ್ತಿದ್ದೀರಿ.\n\nಇಷ್ಟು ಗಟ್ಟಿಯಾದ ವಾಲ್ಯೂಮ್‌ನಲ್ಲಿ ಆಲಿಸುವುದನ್ನು ಮುಂದುವರಿಸಿದರೆ, ನಿಮ್ಮ ಆಲಿಸುವ ಸಾಮರ್ಥ್ಯಕ್ಕೆ ಶಾಶ್ವತ ಹಾನಿಯುಂಟಾಗುತ್ತದೆ."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"ಹೆಚ್ಚಿನ ವಾಲ್ಯೂಮ್‌ನಲ್ಲಿ ಆಲಿಸುವುದನ್ನು ಮುಂದುವರಿಸಬೇಕೇ?\n\nಹೆಡ್‌ಫೋನ್‌ನ ವಾಲ್ಯೂಮ್ ಶಿಫಾರಸು ಮಾಡಿದ್ದಕ್ಕಿಂತಲೂ ಹೆಚ್ಚಿನ ಸಮಯದವರೆಗೆ ಅಧಿಕವಾಗಿದ್ದು, ಇದರಿಂದ ನಿಮ್ಮ ಶ್ರವಣ ಶಕ್ತಿಗೆ ಹಾನಿಯಾಗಬಹುದು"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"ದೊಡ್ಡ ಧ್ವನಿ ಪತ್ತೆಯಾಗಿದೆ\n\nಹೆಡ್‌ಫೋನ್ ವಾಲ್ಯೂಮ್ ಶಿಫಾರಸು ಮಾಡಿದ್ದಕ್ಕಿಂತಲೂ ಹೆಚ್ಚಾಗಿದ್ದು, ಇದರಿಂದ ನಿಮ್ಮ ಶ್ರವಣ ಶಕ್ತಿಗೆ ಹಾನಿಯಾಗಬಹುದು"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಶಾರ್ಟ್‌ಕಟ್ ಬಳಸುವುದೇ?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ಶಾರ್ಟ್‌ಕಟ್ ಆನ್ ಆಗಿರುವಾಗ, ಎರಡೂ ವಾಲ್ಯೂಮ್ ಬಟನ್‌ಗಳನ್ನು 3 ಸೆಕೆಂಡುಗಳ ಕಾಲ ಒತ್ತಿದರೆ ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ವೈಶಿಷ್ಟ್ಯವೊಂದು ಪ್ರಾರಂಭವಾಗುತ್ತದೆ."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ವೈಶಿಷ್ಟ್ಯಗಳಿಗಾಗಿ ಶಾರ್ಟ್‌ಕಟ್ ಆನ್ ಮಾಡಬೇಕೇ?"</string>
@@ -2074,7 +2072,7 @@
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಮತ್ತು ಬದಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಬದಲಾಗಿದೆ"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ಏನನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ ಎಂಬುದನ್ನು ಪರೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
-    <string name="review_notification_settings_title" msgid="5102557424459810820">"ಅಧಿಸೂಚನೆ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ"</string>
+    <string name="review_notification_settings_title" msgid="5102557424459810820">"ನೋಟಿಫಿಕೇಶನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ"</string>
     <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 ನಿಂದ ಪ್ರಾರಂಭಿಸಿ, ನೀವು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡುವ ಆ್ಯಪ್‌ಗಳಿಗೆ, ಅಧಿಸೂಚನೆಗಳನ್ನು ಕಳುಹಿಸಲು ನಿಮ್ಮ ಅನುಮತಿಯ ಅಗತ್ಯವಿದೆ. ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗಳಿಗಾಗಿ ಈ ಅನುಮತಿಯನ್ನು ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"ನಂತರ ರಿಮೈಂಡ್ ಮಾಡಿ"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"ವಜಾಗೊಳಿಸಿ"</string>
@@ -2093,8 +2091,8 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ಸರಿ"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"ಆಫ್ ಮಾಡಿ"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"ವರ್ಧಿತ ಅಧಿಸೂಚನೆಗಳು Android 12 ರಲ್ಲಿ Android ಅಡಾಪ್ಟಿವ್ ಅಧಿಸೂಚನೆಗಳನ್ನು ಬದಲಾಯಿಸಿವೆ. ಈ ವೈಶಿಷ್ಟ್ಯವು ಸೂಚಿಸಿದ ಕ್ರಿಯೆಗಳು ಮತ್ತು ಪ್ರತ್ಯುತ್ತರಗಳನ್ನು ತೋರಿಸುತ್ತದೆ ಮತ್ತು ನಿಮ್ಮ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆಯೋಜಿಸುತ್ತದೆ.\n\nವರ್ಧಿತ ಅಧಿಸೂಚನೆಗಳು ಸಂಪರ್ಕ ಹೆಸರುಗಳು ಮತ್ತು ಸಂದೇಶಗಳಂತಹ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಂತೆ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆ ವಿಷಯವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು. ಈ ವೈಶಿಷ್ಟ್ಯವು ಫೋನ್ ಕರೆಗಳಿಗೆ ಉತ್ತರಿಸುವುದು ಮತ್ತು \'ಅಡಚಣೆ ಮಾಡಬೇಡಿ\' ಅನ್ನು ನಿಯಂತ್ರಿಸುವಂತಹ ಅಧಿಸೂಚನೆಗಳನ್ನು ವಜಾಗೊಳಿಸಬಹುದು ಅಥವಾ ಪ್ರತಿಕ್ರಿಯಿಸಬಹುದು."</string>
-    <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ದೈನಂದಿನ ಸ್ಥಿತಿಯ ಮಾಹಿತಿಯ ಅಧಿಸೂಚನೆ"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"ವರ್ಧಿತ ನೋಟಿಫಿಕೇಶನ್‌ಗಳು Android 12 ರಲ್ಲಿ Android ಅಡಾಪ್ಟಿವ್ ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಿವೆ. ಈ ವೈಶಿಷ್ಟ್ಯವು ಸೂಚಿಸಿದ ಕ್ರಿಯೆಗಳು ಮತ್ತು ಪ್ರತ್ಯುತ್ತರಗಳನ್ನು ತೋರಿಸುತ್ತದೆ ಮತ್ತು ನಿಮ್ಮ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆಯೋಜಿಸುತ್ತದೆ.\n\nವರ್ಧಿತ ನೋಟಿಫಿಕೇಶನ್‌ಗಳು ಸಂಪರ್ಕ ಹೆಸರುಗಳು ಮತ್ತು ಸಂದೇಶಗಳಂತಹ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಂತೆ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆ ವಿಷಯವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು. ಈ ವೈಶಿಷ್ಟ್ಯವು ಫೋನ್ ಕರೆಗಳಿಗೆ ಉತ್ತರಿಸುವುದು ಮತ್ತು \'ಅಡಚಣೆ ಮಾಡಬೇಡಿ\' ಅನ್ನು ನಿಯಂತ್ರಿಸುವಂತಹ ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು ವಜಾಗೊಳಿಸಬಹುದು ಅಥವಾ ಪ್ರತಿಕ್ರಿಯಿಸಬಹುದು."</string>
+    <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ದೈನಂದಿನ ಸ್ಥಿತಿಯ ಮಾಹಿತಿಯ ನೋಟಿಫಿಕೇಶನ್"</string>
     <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"ಬ್ಯಾಟರಿ ಸೇವರ್ ಅನ್ನು ಆನ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯನ್ನು ವಿಸ್ತರಿಸಲು ಬ್ಯಾಟರಿ ಬಳಕೆಯನ್ನು ಕಡಿಮೆ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"ಬ್ಯಾಟರಿ ಸೇವರ್"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"ವಿರಾಮವನ್ನು ರದ್ದುಗೊಳಿಸಿ"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ಯಾವುದೇ ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳಿಲ್ಲ"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ಯಾವುದೇ ವೈಯಕ್ತಿಕ ಆ್ಯಪ್‌ಗಳಿಲ್ಲ"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"ಉದ್ಯೋಗದ <xliff:g id="APP">%s</xliff:g> ಆ್ಯಪ್‌ನಲ್ಲಿ ತೆರೆಯಬೇಕೆ?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"ವೈಯಕ್ತಿಕ <xliff:g id="APP">%s</xliff:g> ಆ್ಯಪ್‌ನಲ್ಲಿ ತೆರೆಯಬೇಕೆ?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"ವೈಯಕ್ತಿಕ <xliff:g id="APP">%s</xliff:g> ಆ್ಯಪ್‌ನಲ್ಲಿ ತೆರೆಯಬೇಕೆ?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ನಿಂದ ಕರೆ ಮಾಡಬೇಕೇ?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಬೇಕೇ?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳಿಂದ ಮಾತ್ರ ಕರೆಗಳನ್ನು ಮಾಡಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳಿಂದ ಮಾತ್ರ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ವೈಯಕ್ತಿಕ ಬ್ರೌಸರ್ ಬಳಸಿ"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ಉದ್ಯೋಗ ಬ್ರೌಸರ್ ಬಳಸಿ"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"ಕರೆ ಮಾಡಿ"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"ಬದಲಿಸಿ"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM ನೆಟ್‌ವರ್ಕ್‌ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವ ಪಿನ್‌"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM ನೆಟ್‌ವರ್ಕ್ ಸಬ್‌ಸೆಟ್‌ನ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವ ಪಿನ್‌"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM ಕಾರ್ಪೊರೇಟ್ ಅನ್‌ಲಾಕ್‌ ಮಾಡುವ ಪಿನ್‌"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 368c973..a4d4a73 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"삭제"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"권장 수준 이상으로 볼륨을 높이시겠습니까?\n\n높은 볼륨으로 장시간 청취하면 청력에 손상이 올 수 있습니다."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"경고:\n1주일 동안 헤드폰을 통해 안전하게 들을 수 있는 큰 소리 신호량을 초과했습니다.\n\n이 한도를 초과하면 청력이 영구적으로 손상됩니다."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"경고:\n1주일 동안 헤드폰을 통해 안전하게 들을 수 있는 큰 소리 신호량을 5배 초과했습니다.\n\n청력을 보호하기 위해 볼륨을 낮췄습니다."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"지금과 같은 수준으로 오랫동안 미디어를 청취할 경우 청력 손상이 발생할 수 있습니다.\n\n지금과 같은 수준으로 장기적으로 계속 들으면 청력이 손상될 수 있습니다."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"경고:\n현재 안전하지 않은 수준으로 크게 콘텐츠를 재생하여 듣고 있습니다.\n\n지금과 같은 수준으로 계속해서 들으면 청력이 영구적으로 손상됩니다."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"계속해서 높은 볼륨으로 들으시겠습니까?\n\n헤드폰 볼륨이 권장 시간보다 오랫동안 높은 상태였으며 이로 인해 청력 손상이 발생할 수 있습니다."</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"큰 소리가 감지됨\n\n헤드폰 볼륨이 권장 시간보다 오랫동안 높은 상태였으며 이로 인해 청력 손상이 발생할 수 있습니다."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"접근성 단축키를 사용하시겠습니까?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"단축키가 사용 설정된 경우 볼륨 버튼 두 개를 동시에 3초간 누르면 접근성 기능이 시작됩니다."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"접근성 기능 바로가기를 사용 설정하시겠습니까?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"일시중지 해제"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"직장 앱 없음"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"개인 앱 없음"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"직장 <xliff:g id="APP">%s</xliff:g> 앱을 여시겠습니까?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"개인 <xliff:g id="APP">%s</xliff:g> 앱에서 여시겠습니까?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"직장 <xliff:g id="APP">%s</xliff:g> 앱에서 여시겠습니까?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"직장 앱을 사용한 통화인가요?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"직장 앱으로 전환할까요?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"귀하의 조직에서 직장 앱을 사용한 통화만 허용했습니다."</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"귀하의 조직에서 직장 앱을 사용한 메시지 전송만 허용했습니다."</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"개인 브라우저 사용"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"직장 브라우저 사용"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"통화"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"전환"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM 네트워크 잠금 해제 PIN"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM 네트워크 하위 집합 잠금 해제 PIN"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM 회사 잠금 해제 PIN"</string>
@@ -2331,10 +2332,10 @@
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"설정으로 이동"</string>
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"사용 중지"</string>
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g>에 설정 완료됨"</string>
-    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"키보드 레이아웃이 <xliff:g id="LAYOUT_1">%s</xliff:g>(으)로 설정됩니다. 변경하려면 탭하세요."</string>
-    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"키보드 레이아웃이 <xliff:g id="LAYOUT_1">%1$s</xliff:g> 및 <xliff:g id="LAYOUT_2">%2$s</xliff:g>(으)로 설정됩니다. 변경하려면 탭하세요."</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"키보드 레이아웃이 <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>(으)로 설정됩니다. 변경하려면 탭하세요."</string>
-    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"키보드 레이아웃이 <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>(으)로 설정됩니다. 변경하려면 탭하세요."</string>
+    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"키보드 레이아웃이 <xliff:g id="LAYOUT_1">%s</xliff:g>로 설정됩니다. 변경하려면 탭하세요."</string>
+    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"키보드 레이아웃이 <xliff:g id="LAYOUT_1">%1$s</xliff:g> 및 <xliff:g id="LAYOUT_2">%2$s</xliff:g>로 설정됩니다. 변경하려면 탭하세요."</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"키보드 레이아웃이 <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>로 설정됩니다. 변경하려면 탭하세요."</string>
+    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"키보드 레이아웃이 <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>로 설정됩니다. 변경하려면 탭하세요."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"실제 키보드에 구성됨"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"키보드를 보려면 탭하세요."</string>
 </resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index c87911e..f599c2ce 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -441,7 +441,7 @@
     <string name="permdesc_writeSettings" msgid="8293047411196067188">"Колдонмого системанын коопсуздук параметрлеринин дайындарын өзгөртүү мүмкүнчүлүгүн берет. Кесепттүү колдонмолор системаңыздын конфигурациясын бузуп салышы мүмкүн."</string>
     <string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"түзмөктү жандырганда иштеп баштоо"</string>
     <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"Колдонмого тутум жүктөлүп бүтөөрү менен өзүн-өзү иштетүү мүмкүнчүлүгүн берет. Бул планшеттин ишке киргизилишин кыйла создуктуруп, планшеттин үзгүлтүксүз иштешин жайлатып салышы мүмкүн."</string>
-    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Тутум күйгүзүлөрү менен колдонмого өз алдынча иштеп баштоого уруксат берет. Ага байланыштуу Android TV түзмөгүңүз кечирээк күйгүзүлүп, ошондой эле колдонмо такай иштеп тургандыктан, түзмөк жайыраак иштеп калышы мүмкүн."</string>
+    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Система күйгүзүлөрү менен колдонмого өз алдынча иштеп баштоого уруксат берет. Ага байланыштуу Android TV түзмөгүңүз кечирээк күйгүзүлүп, ошондой эле колдонмо такай иштеп тургандыктан, түзмөк жайыраак иштеп калышы мүмкүн."</string>
     <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"Колдонмого тутум жүктөлүп бүтөөрү менен өзүн-өзү иштетүү мүмкүнчүлүгүн берет. Бул телефондун ишке киргизилишин кыйла создуктуруп, телефондун үзгүлтүксүз иштешин жайлатып салышы мүмкүн."</string>
     <string name="permlab_broadcastSticky" msgid="4552241916400572230">"жабышчаак таркатманы жөнөтүү"</string>
     <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"Колдонмого берүү токтогондон кийин улантыла берүүчү жабышкак берүүлөрдү жөнөтүү уруксатын берет. Муну ашыкча колдонуу, эстутумду өтө көп пайдаланууга алып келип, планшеттин жай же туруксуз иштөөсүнүнө себепкер болушу мүмкүн."</string>
@@ -678,7 +678,7 @@
     <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Тейлөө кызматына кайрылыңыз."</string>
     <string name="face_acquired_insufficient" msgid="6889245852748492218">"Жүзүңүздүн үлгүсү түзүлгөн жок. Кайталаңыз."</string>
     <string name="face_acquired_too_bright" msgid="8070756048978079164">"Өтө жарык. Жарыктыкты азайтып көрүңүз."</string>
-    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Жарык жетишсиз"</string>
+    <string name="face_acquired_too_dark" msgid="8539853432479385326">"Жарыгыраак жерге туруңуз"</string>
     <string name="face_acquired_too_close" msgid="4453646176196302462">"Телефонду алыстатыңыз"</string>
     <string name="face_acquired_too_far" msgid="2922278214231064859">"Телефонду жакындатыңыз"</string>
     <string name="face_acquired_too_high" msgid="8278815780046368576">"Телефонду өйдө жылдырыңыз"</string>
@@ -714,7 +714,7 @@
     <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Өтө көп жолу аракет кылдыңыз. \"Жүзүнөн таанып ачуу\" жеткиликсиз."</string>
     <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Өтө көп жолу аракет кылдыңыз. Эрканды кулпулоо функциясын колдонуңуз."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Жүз ырасталбай жатат. Кайталап көрүңүз."</string>
-    <string name="face_error_not_enrolled" msgid="1134739108536328412">"Жүзүнөн таанып ачуу функциясын жөндөй элексиз"</string>
+    <string name="face_error_not_enrolled" msgid="1134739108536328412">"Жүзүнөн таанып ачуу функциясын кое элексиз"</string>
     <string name="face_error_hw_not_present" msgid="7940978724978763011">"Жүзүнөн таанып ачуу функциясы бул түзмөктө иштебейт"</string>
     <string name="face_error_security_update_required" msgid="5076017208528750161">"Сенсор убактылуу өчүрүлгөн."</string>
     <string name="face_name_template" msgid="3877037340223318119">"Жүз <xliff:g id="FACEID">%d</xliff:g>"</string>
@@ -1207,7 +1207,7 @@
     <string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"Сүрөткө тартуу"</string>
     <string name="alwaysUse" msgid="3153558199076112903">"Бул аракет үчүн демейки боюнча колдонулсун."</string>
     <string name="use_a_different_app" msgid="4987790276170972776">"Башка колдонмону пайдалануу"</string>
-    <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Тутум жөндөөлөрүндөгү демейкини тазалоо &gt; Колдонмолор &gt; Жүктөлүп алынды."</string>
+    <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Система жөндөөлөрүндөгү демейкини тазалоо &gt; Колдонмолор &gt; Жүктөлүп алынды."</string>
     <string name="chooseActivity" msgid="8563390197659779956">"Аракет тандаңыз"</string>
     <string name="chooseUsbActivity" msgid="2096269989990986612">"USB түзмөгү үчүн колдонмо тандаңыз"</string>
     <string name="noApplications" msgid="1186909265235544019">"Бул аракетти аткара турган колдонмо жок."</string>
@@ -1623,7 +1623,7 @@
     <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Тышкы түзмөк"</string>
     <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Кулакчын"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
-    <string name="default_audio_route_category_name" msgid="5241740395748134483">"Тутум"</string>
+    <string name="default_audio_route_category_name" msgid="5241740395748134483">"Система"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="4214648773120426288">"Bluetooth аудио"</string>
     <string name="wireless_display_route_description" msgid="8297563323032966831">"Зымсыз дисплей"</string>
     <string name="media_route_button_content_description" msgid="2299223698196869956">"Тышкы экранга чыгаруу"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Өчүрүү"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Сунушталган деңгээлден да катуулатып уккуңуз келеби?\n\nМузыканы узакка чейин катуу уксаңыз, угууңуз начарлап кетиши мүмкүн."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Эскертүү,\nБир аптанын ичинде ден соолукка зыян келтирбестен гарнитура аркылуу уга турган катуу үн сигналдарынын чегинен аштыңыз.\n\nБул чектен ашуу угууңуздун биротоло бузулушуна алып келет."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Эскертүү,\nБир аптанын ичинде ден соолукка зыян келтирбестен гарнитура аркылуу уга турган катуу үн сигналдарынын чегинен 5 жолу аштыңыз.\n\nУгууңузду коргоо үчүн медианын үнү кичирейтилди."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Медианы узак убакыт ушундай катуулукта уга берсеңиз, угууңуз начарлашы мүмкүн.\n\nУшундай катуулукта өтө көп уксаңыз, угууңуз бузулат."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Эскертүү,\nУчурдагы медианын үнүн өтө катуу кылып угуп жатасыз.\n\nМындай катуулукта уга берсеңиз, угууңуз биротоло бузулат."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Үнүн катуу кылып уга бересизби?\n\nГарнитуранын үнүн катуу чыгарып, сунушталган убакыттан узагыраак угуп жатасыз. Этияттаңыз, кулагыңыздын угуусу начарлап кетиши мүмкүн"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Үнүн катуу кылып угуп жатасыз\n\nГарнитуранын үнүн катуу чыгарып, сунушталган убакыттан узагыраак угуп жатасыз. Этияттаңыз, кулагыңыздын угуусу начарлап кетиши мүмкүн"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Ыкчам иштетесизби?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Атайын мүмкүнчүлүктөр функциясын пайдалануу үчүн ал күйгүзүлгөндө, үндү катуулатып/акырындаткан эки баскычты тең 3 секунддай коё бербей басып туруңуз."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Атайын мүмкүнчүлүктөрдүн ыкчам баскычын иштетесизби?"</string>
@@ -2068,7 +2066,7 @@
     <string name="screenshot_edit" msgid="7408934887203689207">"Түзөтүү"</string>
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Чалуулар менен билдирмелер дирилдөө режиминде иштейт"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Чалуулар менен эскертмелердин үнү өчүрүлөт"</string>
-    <string name="notification_channel_system_changes" msgid="2462010596920209678">"Тутум өзгөрүүлөрү"</string>
+    <string name="notification_channel_system_changes" msgid="2462010596920209678">"Система өзгөрүүлөрү"</string>
     <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Тынчымды алба"</string>
     <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Жаңы: \"Тынчымды алба\" режими билдирмелерди жашырууда"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Көбүрөөк маалымат алып, өзгөртүү үчүн таптаңыз."</string>
@@ -2078,7 +2076,7 @@
     <string name="review_notification_settings_text" msgid="5916244866751849279">"Android 13 версиясынан баштап билдирмелерди жөнөтүү үчүн орноткон колдонмолоруңузга уруксат берүү керек. Учурдагы колдонмолор үчүн бул уруксатты өзгөртүү үчүн таптап коюңуз."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Кийинчерээк эскертүү"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Жабуу"</string>
-    <string name="notification_app_name_system" msgid="3045196791746735601">"Тутум"</string>
+    <string name="notification_app_name_system" msgid="3045196791746735601">"Система"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Параметрлер"</string>
     <string name="notification_appops_camera_active" msgid="8177643089272352083">"Камера"</string>
     <string name="notification_appops_microphone_active" msgid="581333393214739332">"Микрофон"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Иштетүү"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Жумуш колдонмолору жок"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Жеке колдонмолор жок"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Жумуш үчүн <xliff:g id="APP">%s</xliff:g> колдонмосун ачасызбы?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Жеке <xliff:g id="APP">%s</xliff:g> колдонмосунда ачасызбы?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Жумуш <xliff:g id="APP">%s</xliff:g> колдонмосунда ачасызбы?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Жумуш колдонмосунан чаласызбы?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Жумуш колдонмосуна которуласызбы?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Уюмуңуз жумуш колдонмолорунан гана чалууга уруксат берет"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Уюмуңуз билдирүүлөрдү жумуш колдонмолорунан гана жөнөтүүгө уруксат берет"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Жеке серепчини колдонуу"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Жумуш серепчисин колдонуу"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Чалуу"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Которулуу"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM карта тармагынын кулпусун ачуучу PIN код"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM кичи тармагынын кулпусун ачуучу PIN код"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM картанын корпоративдик кулпусун ачуучу PIN код"</string>
@@ -2331,10 +2332,10 @@
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"Параметрлерге өтүү"</string>
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Өчүрүү"</string>
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> конфигурацияланды"</string>
-    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Баскычтоп калыбы төмөнкүгө коюлду: <xliff:g id="LAYOUT_1">%s</xliff:g>. Өзгөртүү үчүн басыңыз."</string>
-    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Баскычтоп калыбы төмөнкүгө коюлду: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Өзгөртүү үчүн басыңыз."</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Баскычтоп калыбы төмөнкүгө коюлду: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Өзгөртүү үчүн басыңыз."</string>
-    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Баскычтоп калыбы төмөнкүгө коюлду: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Өзгөртүү үчүн басыңыз."</string>
+    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Баскычтопко төмөнкү калып коюлду: <xliff:g id="LAYOUT_1">%s</xliff:g>. Өзгөртүү үчүн басыңыз."</string>
+    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Баскычтопко төмөнкү калып коюлду: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Өзгөртүү үчүн басыңыз."</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Баскычтопко төмөнкү калып коюлду: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Өзгөртүү үчүн басыңыз."</string>
+    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Баскычтопко төмөнкү калып коюлду: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Өзгөртүү үчүн басыңыз."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физикалык баскычтоптор конфигурацияланды"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Баскычтопторду көрүү үчүн басыңыз"</string>
 </resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index ec593c0..7677206 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"ລຶບອອກ"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ເພີ່ມ​ລະ​ດັບ​ສຽງ​ໃຫ້​ເກີນກວ່າ​ລະ​ດັບ​ທີ່​ແນະ​ນຳ​ບໍ?\n\n​ການ​ຮັບ​ຟັງ​ສຽງ​ໃນ​ລະ​ດັບ​ທີ່​ສູງ​ເປັນ​ໄລ​ຍະ​ເວ​ລາ​ດົນ​​ອາດ​ເຮັດ​ໃຫ້​ການ​ຟັງ​ຂອງ​ທ່ານ​ມີ​ບັນ​ຫາ​ໄດ້."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"ຄຳເຕືອນ,\nທ່ານມີສັນຍານສຽງດັງເກີນຈຳນວນທີ່ຄົນເຮົາສາມາດຟັງໄດ້ຢ່າງປອດໄພໃນໜຶ່ງອາທິດຜ່ານຫູຟັງ.\n\nການໃຊ້ເກີນຂີດຈຳກັດນີ້ຈະທຳລາຍການໄດ້ຍິນຂອງທ່ານຢ່າງຖາວອນ."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"ຄຳເຕືອນ,\nທ່ານມີສັນຍານສຽງດັງເກີນ 5 ເທື່ອຂອງສັນຍານສຽງທີ່ຄົນເຮົາສາມາດຟັງໄດ້ຢ່າງປອດໄພໃນໜຶ່ງອາທິດຜ່ານຫູຟັງ.\n\nໄດ້ຫຼຸດລະດັບສຽງລົງແລ້ວເພື່ອປົກປ້ອງການໄດ້ຍິນຂອງທ່ານ."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"ລະດັບທີ່ທ່ານກໍາລັງຟັງສື່ສາມາດສົ່ງຜົນໃຫ້ເກີດຄວາມເສຍຫາຍຕໍ່ການໄດ້ຍິນເມື່ອຖືກຄົງໄວ້ເປັນເວລາດົນນານ.\n\nການສືບຕໍ່ຫຼິ້ນໃນລະດັບນີ້ເປັນເວລາດົນອາດເຮັດໃຫ້ການໄດ້ຍິນຂອງທ່ານເສຍຫາຍໄດ້."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"ຄຳເຕືອນ,\nປັດຈຸບັນນີ້ທ່ານກຳລັງຟັງເນື້ອຫາທີ່ມີສຽງດັງໃນລະດັບທີ່ບໍ່ປອດໄພ.\n\nການສືບຕໍ່ຟັງສຽງດັງນີ້ຈະທໍາລາຍການໄດ້ຍິນຂອງທ່ານຢ່າງຖາວອນ."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"ສືບຕໍ່ຟັງໃນລະດັບສຽງທີ່ດັງບໍ?\n\nຫູຟັງຢູ່ໃນລະດັບສຽງທີ່ດັງເປັນໄລຍະເວລາດົນກວ່າທີ່ແນະນຳ, ເຊິ່ງສາມາດເປັນອັນຕະລາຍຕໍ່ການໄດ້ຍິນຂອງທ່ານໄດ້"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"ກວດພົບສຽງດັງ\n\nຫູຟັງຢູ່ໃນລະດັບສຽງທີ່ດັງກວ່າທີ່ແນະນຳ, ເຊິ່ງສາມາດເປັນອັນຕະລາຍຕໍ່ການໄດ້ຍິນຂອງທ່ານໄດ້"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ໃຊ້ປຸ່ມລັດການຊ່ວຍເຂົ້າເຖິງບໍ?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ເມື່ອເປີດໃຊ້ທາງລັດແລ້ວ, ການກົດປຸ່ມລະດັບສຽງທັງສອງຄ້າງໄວ້ 3 ວິນາທີຈະເປັນການເລີ່ມຄຸນສົມບັດການຊ່ວຍເຂົ້າເຖິງ."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"ເປີດໃຊ້ທາງລັດສຳລັບຄຸນສົມບັດການຊ່ວຍເຂົ້າເຖິງບໍ?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"ຍົກເລີກການຢຸດຊົ່ວຄາວ"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ບໍ່ມີແອັບບ່ອນເຮັດວຽກ"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ບໍ່ມີແອັບສ່ວນຕົວ"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"ເປີດ <xliff:g id="APP">%s</xliff:g> ສຳລັບວຽກບໍ?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"ເປີດໃນ <xliff:g id="APP">%s</xliff:g> ສ່ວນຕົວບໍ?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"ເປີດໃນ <xliff:g id="APP">%s</xliff:g> ສຳລັບວຽກບໍ?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"ໂທຈາກແອັບບ່ອນເຮັດວຽກບໍ?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ສະຫຼັບໄປເປັນແອັບບ່ອນເຮັດວຽກບໍ?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"ອົງການຈັດຕັ້ງຂອງທ່ານອະນຸຍາດໃຫ້ທ່ານໂທຈາກແອັບບ່ອນເຮັດວຽກເທົ່ານັ້ນ"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"ອົງການຈັດຕັ້ງຂອງທ່ານອະນຸຍາດໃຫ້ທ່ານສົ່ງຂໍ້ຄວາມໄດ້ຈາກແອັບບ່ອນເຮັດວຽກເທົ່ານັ້ນ"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ໃຊ້ໂປຣແກຣມທ່ອງເວັບສ່ວນຕົວ"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ໃຊ້ໂປຣແກຣມທ່ອງເວັບບ່ອນເຮັດວຽກ"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"ໂທ"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"ສະຫຼັບ"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN ປົດລັອກເຄືອຂ່າຍຊິມ"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN ການປົດລັອກຊຸດຍ່ອຍເຄືອຂ່າຍຊິມ"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN ປົດລັອກ SIM ອົງການ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 5d0e148..eb1ab56 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1684,10 +1684,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Pašalinti"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Padidinti garsą daugiau nei rekomenduojamas lygis?\n\nIlgai klausydami dideliu garsu galite pažeisti klausą."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Įspėjimas.\nViršijote savaitės garsių garso signalų kiekį, kurio būtų saugu klausytis per ausines.\n\nViršijus šį apribojimą bus negrįžtamai pažeista jūsų klausa."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Įspėjimas.\nViršijote savaitės garsių garso signalų kiekį (penki kartai), kurio būtų saugu klausytis per ausines.\n\nGarsumas sumažintas apsaugant jūsų klausą."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Garsumas, kuriuo klausotės medijos, klausantis ilgai gali pakenkti jūsų klausai.\n\nToliau ilgai leidžiant šiuo garsumu gali būti pakenkta jūsų klausai."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Įspėjimas.\nŠiuo metu klausotės nesaugiu garsumu leidžiamo turinio.\n\nToliau klausantis tokiu garsumu leidžiamo turinio bus negrįžtamai pakenkta jūsų klausai."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Toliau klausytis nustačius aukštą garsumo lygį?\n\nAusinių garsumo lygis yra aukštas ilgiau, nei rekomenduojama, o tai gali pakenkti klausai"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Aptiktas garsus garsas\n\nAusinių garsumo lygis yra aukštesnis, nei rekomenduojama, o tai gali pakenkti klausai"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Naudoti spartųjį pritaikymo neįgaliesiems klavišą?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kai spartusis klavišas įjungtas, paspaudus abu garsumo mygtukus ir palaikius 3 sekundes bus įjungta pritaikymo neįgaliesiems funkcija."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Įjungti pritaikymo neįgaliesiems funkcijų spartųjį klavišą?"</string>
@@ -2166,14 +2164,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Atšaukti pristabdymą"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nėra darbo programų"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nėra asmeninių programų"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Atidaryti darbo programą „<xliff:g id="APP">%s</xliff:g>“?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Atidaryti asmeninėje programoje „<xliff:g id="APP">%s</xliff:g>“?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Atidaryti darbo programoje „<xliff:g id="APP">%s</xliff:g>“?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Skambinti iš darbo programos?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Perjungti į darbo programą?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Jūsų organizacija leidžia skambinti tik iš darbo programų"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Jūsų organizacija leidžia siųsti pranešimus tik iš darbo programų"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Naudoti asmeninę naršyklę"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Naudoti darbo naršyklę"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Skambinti"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Perjungti"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM tinklo operatoriaus pasirinkimo ribojimo panaikinimo PIN kodas"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM tinklo poaibio operatoriaus pasirinkimo ribojimo panaikinimo PIN kodas"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM bendrojo operatoriaus pasirinkimo ribojimo panaikinimo PIN kodas"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 91b62f2..249fb1f 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -636,7 +636,7 @@
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Pārāk spilgts"</string>
     <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Konstatēta barošanas pogas nospiešana"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Mēģiniet mainīt pozīciju"</string>
-    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Katru reizi mazliet mainiet pirksta pozīciju."</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Katru reizi mazliet mainiet pirksta pozīciju"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Pirksta nospiedums netika atpazīts"</string>
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">"  — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Noņemt"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vai palielināt skaļumu virs ieteicamā līmeņa?\n\nIlgstoši klausoties skaņu lielā skaļumā, var tikt bojāta dzirde."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Brīdinājums!\nEsat pārsniedzis skaļu skaņas signālu apjomu, ko vienā nedēļā var droši klausīties austiņās.\n\nPārsniedzot šo ierobežojumu, jūsu dzirde neatgriezeniski pasliktināsies."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Brīdinājums!\nEsat pieckārt pārsniedzis skaļu skaņas signālu apjomu, ko vienā nedēļā var droši klausīties austiņās.\n\nSkaļums tika samazināts, lai aizsargātu jūsu dzirdi."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Ilgstoši klausoties multivides saturu šādā skaļumā, var rasties dzirdes bojājumi.\n\nJa turpināsiet ilgstoši atskaņot saturu šādā skaļumā, jums var pasliktināties dzirde."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Brīdinājums!\nJūs pašlaik klausāties saturu tik skaļi, ka tas nav droši.\n\nJa turpināsiet klausīties šādā skaļumā, jūsu dzirde neatgriezeniski pasliktināsies."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Vai turpināt klausīties lielā skaļumā?\n\nAustiņu skaļums ir bijis liels ilgāk, nekā ieteicams, tādējādi jums var pasliktināties dzirde."</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Uztverta skaļa skaņa\n\nAustiņu skaļums ir lielāks, nekā ieteicams, tādējādi jums var pasliktināties dzirde."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vai izmantot pieejamības saīsni?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kad īsinājumtaustiņš ir ieslēgts, nospiežot abas skaļuma pogas un 3 sekundes turot tās, tiks aktivizēta pieejamības funkcija."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Vai ieslēgt pieejamības funkciju saīsni?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Aktivizēt"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nav darba lietotņu"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nav personīgu lietotņu"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Vai atvērt lietotni <xliff:g id="APP">%s</xliff:g> darba profilā?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Vai atvērt lietotnes <xliff:g id="APP">%s</xliff:g> personīgajā profilā?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Vai atvērt lietotnes <xliff:g id="APP">%s</xliff:g> darba profilā?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Vai zvanīt no darba lietotnes?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Vai pārslēgties uz darba lietotni?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Jūsu organizācija ļauj jums veikt zvanus tikai no darba lietotnēm."</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Jūsu organizācija ļauj jums sūtīt ziņojumus tikai no darba lietotnēm."</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Izmantot personīgo pārlūku"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Izmantot darba pārlūku"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Zvanīt"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Pārslēgties"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM tīkla atbloķēšanas PIN"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM tīkla apakškopas atbloķēšanas PIN"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM Corporate atbloķēšanas PIN"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 2ed22d4..6c570c2 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -686,7 +686,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"Поместете го телефонот налево"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"Поместете го телефонот надесно"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Погледнете подиректно во уредот."</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Не ви се гледа ликот. Држете го телефонот во висина на очите."</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Не се гледа ликот. Држете го телефонот во висина на очите."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Премногу движење. Држете го телефонот стабилно."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Повторно регистрирајте го лицето."</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"Не се препознава ликот. Обидете се пак."</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Отстрани"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Да го зголемиме звукот над препорачаното ниво?\n\nСлушањето звуци со голема јачина подолги периоди може да ви го оштети сетилото за слух."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Опомена,\nго надминавте ограничувањето за гласни звучни сигнали кои може безбедно да се слушаат во една седмица на слушалки.\n\nАко го надминете ограничувањево, може да го оштетите слухот."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Опомена,\nго надминавте ограничувањето од 5 гласни звучни сигнали кои може безбедно да се слушаат во една седмица на слушалки.\n\nГласноста е намалена за да ви се заштити слухот."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Гласноста со која слушате аудиовизуелни содржини може да предизвика оштетување на слухот ако трае подолг временски период.\n\nАко продолжите да слушате со оваа гласност подолг временски период, може да го оштетите слухот."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Опомена,\nтековно слушате гласни содржини што се репродуцираат со небезбедна гласност.\n\nАко продолжите да слушате волку гласно, може трајно да го оштетите слухот."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Сакате да продолжите да слушате со висока јачина на звукот?\n\nЈачината на звукот на слушалките беше висока подолго од препорачаното, што може да доведе до оштетување на слухот"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Откриен е гласен звук\n\nЈачината на звукот на слушалките беше повисока од препорачаната, што може да доведе до оштетување на слухот"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Да се користи кратенка за „Пристапност“?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Кога е вклучена кратенката, ако ги притиснете двете копчиња за јачина на звук во времетраење од 3 секунди, ќе се стартува функција за пристапност."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Да се вклучи кратенка за функциите за пристапност?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Прекини ја паузата"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Нема работни апликации"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Нема лични апликации"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Да се отвори работната апликација <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Да се отвори во личната апликација <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Да се отвори во работната апликација <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Да се повика од работна апликација?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Да се префрли на работна апликација?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Вашата организацијата ви дозволува да упатувате повици само од работни апликации"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Вашата организацијата ви дозволува да испраќате пораки само од работни апликации"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Користи личен прелистувач"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Користи работен прелистувач"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Повикај"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Префрли"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN за отклучување на мрежата на SIM-картичката"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN за отклучување на подмножество на мрежата на SIM-картичката"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN за отклучување на корпоративната SIM-картичка"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index eebe42c..23e3b3a 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"നീക്കംചെയ്യുക"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"മുകളിൽക്കൊടുത്തിരിക്കുന്ന ശുപാർശചെയ്‌ത ലെവലിലേക്ക് വോളിയം വർദ്ധിപ്പിക്കണോ?\n\nഉയർന്ന വോളിയത്തിൽ ദീർഘനേരം കേൾക്കുന്നത് നിങ്ങളുടെ ശ്രവണ ശേഷിയെ ദോഷകരമായി ബാധിക്കാം."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"മുന്നറിയിപ്പ്,\nഒരാൾക്ക് ഒരാഴ്ച ഹെഡ്ഫോണുകളിലൂടെ സുരക്ഷിതമായി കേൾക്കാനാകുന്ന ഉച്ചത്തിലുള്ള ശബ്ദ സിഗ്നലുകളുടെ അളവ് നിങ്ങൾ മറികടന്നിരിക്കുന്നു.\n\nഈ പരിധിക്ക് മുകളിൽ പോകുന്നത് നിങ്ങളുടെ കേൾവിശക്തിയെ ശാശ്വതമായി തകരാറിലാക്കും."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"മുന്നറിയിപ്പ്,\nഒരാൾക്ക് ഒരാഴ്ചയിൽ ഹെഡ്ഫോണുകളിലൂടെ സുരക്ഷിതമായി കേൾക്കാനാകുന്ന ഉച്ചത്തിലുള്ള ശബ്ദ സിഗ്നലുകളുടെ അളവിന്റെ 5 മടങ്ങ് നിങ്ങൾ മറികടന്നിരിക്കുന്നു.\n\nനിങ്ങളുടെ കേൾവിശക്തി സംരക്ഷിക്കുന്നതിനായി വോളിയം കുറച്ചു."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"നിങ്ങൾ ഇപ്പോൾ മീഡിയ കേൾക്കുന്ന ലെവൽ ദീർഘകാലം ഉപയോഗിച്ചാൽ അത് കേൾവി തകരാറിലേക്ക് നയിച്ചേക്കാം.\n\nഈ ലെവലിൽ തുടർന്നും ദീർഘകാലം പ്ലേ ചെയ്യുന്നത് നിങ്ങളുടെ കേൾവിശക്തി തകരാറിലാക്കിയേക്കാം."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"മുന്നറിയിപ്പ്,\nസുരക്ഷിതമല്ലാത്ത ലെവലിൽ പ്ലേ ചെയ്യുന്ന ഉച്ചത്തിലുള്ള ഉള്ളടക്കമാണ് നിങ്ങൾ നിലവിൽ കേൾക്കുന്നത്.\n\nഇത്ര ഉച്ചത്തിൽ കേൾക്കുന്നത് തുടർന്നാൽ നിങ്ങളുടെ കേൾവിശക്തി ശാശ്വതമായി തകരാറിലാകും."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"ഉയർന്ന വോളിയത്തിൽ കേൾക്കുന്നത് തുടരണോ?\n\nഹെഡ്‌ഫോണിന്റെ വോളിയം, നിർദ്ദേശിച്ചിരിക്കുന്നതിനേക്കാൾ കൂടുതൽ സമയം ഉയർന്ന നിലയിലായിരുന്നു, ഇത് നിങ്ങളുടെ കേൾവിക്ക് തകരാറുണ്ടാക്കും"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"ഉച്ചത്തിലുള്ള വോളിയം തിരിച്ചറിഞ്ഞു\n\nഹെഡ്‌ഫോണിന്റെ വോളിയം, നിർദ്ദേശിച്ചിരിക്കുന്നതിനേക്കാൾ ഉയർന്ന നിലയിലായിരുന്നു, ഇത് നിങ്ങളുടെ കേൾവിക്ക് തകരാറുണ്ടാക്കും"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ഉപയോഗസഹായി കുറുക്കുവഴി ഉപയോഗിക്കണോ?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"കുറുക്കുവഴി ഓണായിരിക്കുമ്പോൾ, രണ്ട് വോളിയം ബട്ടണുകളും 3 സെക്കൻഡ് നേരത്തേക്ക് അമർത്തുന്നത് ഉപയോഗസഹായി ഫീച്ചർ ആരംഭിക്കും."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"ഉപയോഗസഹായി ഫീച്ചറുകൾക്കുള്ള കുറുക്കുവഴി ഓണാക്കണോ?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"താൽക്കാലികമായി നിർത്തിയത് മാറ്റുക"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ഔദ്യോഗിക ആപ്പുകൾ ഇല്ല"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"വ്യക്തിപര ആപ്പുകൾ ഇല്ല"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"ഔദ്യോഗിക <xliff:g id="APP">%s</xliff:g> തുറക്കണോ?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"സ്വകാര്യ <xliff:g id="APP">%s</xliff:g> എന്നതിൽ തുറക്കണോ?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"ഔദ്യോഗിക <xliff:g id="APP">%s</xliff:g> എന്നതിൽ തുറക്കണോ?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"ഔദ്യോഗിക ആപ്പിൽ നിന്ന് കോൾ ചെയ്യണോ?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ഔദ്യോഗിക ആപ്പിലേക്ക് മാറണോ?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"സ്ഥാപനം ഔദ്യോഗിക ആപ്പുകളിൽ നിന്ന് കോളുകൾ ചെയ്യാൻ മാത്രമേ നിങ്ങളെ അനുവദിക്കുന്നുള്ളൂ"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"സ്ഥാപനം ഔദ്യോഗിക ആപ്പുകളിൽ നിന്ന് സന്ദേശമയയ്ക്കാൻ മാത്രമേ നിങ്ങളെ അനുവദിക്കുന്നുള്ളൂ"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"വ്യക്തിപരമായ ബ്രൗസർ ഉപയോഗിക്കുക"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ഔദ്യോഗിക ബ്രൗസർ ഉപയോഗിക്കുക"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"കോൾ ചെയ്യുക"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"മാറുക"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"സിം നെറ്റ്‌വർക്ക് അൺലോക്ക് ചെയ്യാനുള്ള പിൻ"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"സിം നെറ്റ്‌വർക്ക് സബ്സെറ്റ് അൺലോക്ക് ചെയ്യാനുള്ള പിൻ"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"സിം കോർപ്പറേറ്റ് അൺലോക്ക് ചെയ്യാനുള്ള പിൻ"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 740bb6f..00c6240 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Устгах"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Дууг санал болгосноос чанга болгож өсгөх үү?\n\nУрт хугацаанд чанга хөгжим сонсох нь таны сонсголыг муутгаж болно."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Сануулга,\nТа чихэвчээр долоо хоногийн турш аюулгүйгээр сонсож болох чанга дууны дохионы хэмжээг хэтрүүлсэн байна.\n\nЭнэ хязгаарыг давах нь таны сонсголыг бүрмөсөн гэмтээнэ."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Сануулга,\nТа чихэвчээр долоо хоногийн турш аюулгүйгээр сонсож болох чанга дууны дохионы хэмжээг 5 дахин хэтрүүлсэн байна.\n\nТаны сонсголыг хамгаалахын тулд дууны түвшнийг багасгасан."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Та удаан хугацааны туршид медиаг тасралтгүй энэ түвшинд сонссоор байвал сонсголыг гэмтээж болзошгүй.\n\nЭнэ түвшинд удаан хугацаанд үргэлжлүүлэн тоглуулах нь таны сонсголыг гэмтээж болно."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Сануулга,\nТа одоогоор аюултай түвшинд тоглуулж буй маш чанга контентыг сонсож байна.\n\nЭнэ чанга дууг үргэлжлүүлэн сонсох нь таны сонсголыг бүрмөсөн гэмтээнэ."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Өндөр дууны түвшинд сонссоор байх уу?\n\nЧихэвчийн дууны түвшин санал болгосноос удаан хугацааны турш өндөр байгаа бөгөөд таны сонсголыг гэмтээх боломжтой"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Чанга дуу чимээ илэрлээ\n\nЧихэвчийн дууны түвшин санал болгосноос өндөр байгаа нь таны сонсголыг гэмтээх боломжтой"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Хүртээмжийн товчлолыг ашиглах уу?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Товчлол асаалттай үед дууны түвшний хоёр товчлуурыг хамтад нь 3 секунд дарснаар хандалтын онцлогийг эхлүүлнэ."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Хандалтын онцлогуудын товчлолыг асаах уу?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Үргэлжлүүлэх"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Ямар ч ажлын апп байхгүй байна"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Ямар ч хувийн апп байхгүй байна"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Ажлын <xliff:g id="APP">%s</xliff:g>-г нээх үү?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Хувийн <xliff:g id="APP">%s</xliff:g>-д нээх үү?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Ажлын <xliff:g id="APP">%s</xliff:g>-д нээх үү?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Ажлын аппаас залгах уу?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Ажлын апп руу сэлгэх үү?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Танай байгууллага танд зөвхөн ажлын аппуудаас дуудлага хийхийг зөвшөөрдөг"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Танай байгууллага танд зөвхөн ажлын аппуудаас мессеж илгээхийг зөвшөөрдөг"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Хувийн хөтөч ашиглах"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Ажлын хөтөч ашиглах"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Залгах"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Сэлгэх"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Сүлжээний SIM-н түгжээг тайлах ПИН"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Сүлжээний дэд олонлогийн SIM-н түгжээг тайлах ПИН"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Байгууллагын SIM-н түгжээг тайлах ПИН"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index cd9b87a..c74a1ca 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1059,7 +1059,7 @@
     <string name="factorytest_not_system" msgid="5658160199925519869">"FACTORY_TEST कृती फक्त /सिस्टीम/अ‍ॅप मध्ये इंस्टॉल केलेल्या पॅकेजसाठी सपोर्ट आहे."</string>
     <string name="factorytest_no_action" msgid="339252838115675515">"FACTORY_TEST क्रिया प्रदान करणारे कोणतेही पॅकेज आढळले नाही."</string>
     <string name="factorytest_reboot" msgid="2050147445567257365">"रीबूट करा"</string>
-    <string name="js_dialog_title" msgid="7464775045615023241">"\"<xliff:g id="TITLE">%s</xliff:g>\" वरील पेज हे म्हणते:"</string>
+    <string name="js_dialog_title" msgid="7464775045615023241">"\"<xliff:g id="TITLE">%s</xliff:g>\" वरील पेज पुढील गोष्टी दर्शवते:"</string>
     <string name="js_dialog_title_default" msgid="3769524569903332476">"JavaScript"</string>
     <string name="js_dialog_before_unload_title" msgid="7012587995876771246">"नेव्हिगेशनची पुष्टी करा"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="4274257182303565509">"हे पेज सोडा"</string>
@@ -1082,7 +1082,7 @@
     <string name="menu_space_shortcut_label" msgid="5949311515646872071">"स्पेस"</string>
     <string name="menu_enter_shortcut_label" msgid="6709499510082897320">"एंटर"</string>
     <string name="menu_delete_shortcut_label" msgid="4365787714477739080">"हटवा"</string>
-    <string name="search_go" msgid="2141477624421347086">"शोध"</string>
+    <string name="search_go" msgid="2141477624421347086">"शोधा"</string>
     <string name="search_hint" msgid="455364685740251925">"शोधा…"</string>
     <string name="searchview_description_search" msgid="1045552007537359343">"शोधा"</string>
     <string name="searchview_description_query" msgid="7430242366971716338">"शोध क्वेरी"</string>
@@ -1229,7 +1229,7 @@
     <string name="force_close" msgid="9035203496368973803">"ठीक"</string>
     <string name="report" msgid="2149194372340349521">"अहवाल द्या"</string>
     <string name="wait" msgid="7765985809494033348">"प्रतीक्षा करा"</string>
-    <string name="webpage_unresponsive" msgid="7850879412195273433">"पेज प्रतिसाद न देणारे झाले आहे.\n\nतुम्ही हे बंद करू इच्छिता?"</string>
+    <string name="webpage_unresponsive" msgid="7850879412195273433">"पेज प्रतिसाद देत नाही.\n\nतुम्ही ते बंद करू इच्छिता का?"</string>
     <string name="launch_warning_title" msgid="6725456009564953595">"अ‍ॅप पुनर्निर्देशित केला"</string>
     <string name="launch_warning_replace" msgid="3073392976283203402">"<xliff:g id="APP_NAME">%1$s</xliff:g> आता चालत आहे."</string>
     <string name="launch_warning_original" msgid="3332206576800169626">"<xliff:g id="APP_NAME">%1$s</xliff:g> मूळतः लाँच केले."</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"काढा"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"शिफारस केलेल्‍या पातळीच्या वर आवाज वाढवायचा?\n\nउच्च आवाजात दीर्घ काळ ऐकण्‍याने आपल्‍या श्रवणशक्तीची हानी होऊ शकते."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"चेतावणी,\nव्यक्तीची सुरक्षितरीत्या हेडफोनवर मोठ्या आवाजातील सिग्नल ऐकण्याची एका आठवड्याची मर्यादा तुम्ही ओलांडली आहे.\n\nही मर्यादा ओलांडणे तुमच्या श्रवणशक्तीचे कायमचे नुकसान करू करेल."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"चेतावणी,\nव्यक्तीची सुरक्षितरीत्या हेडफोनवर मोठ्या आवाजातील सिग्नल ऐकण्याची एका आठवड्याची मर्यादा तुम्ही पाचपट ओलांडली आहे.\n\nतुमच्या श्रवणशक्तीच्या संरक्षणासाठी व्हॉल्यूम कमी केला गेला आहे."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"तुम्ही ज्या पातळीवर मीडिया ऐकत आहात, असे जास्त कालावधीसाठी सुरू राहिल्याचा परिणाम म्हणून तुमच्या श्रवणशक्तीचे कायमचे नुकसान होऊ शकते.\n\nया पातळीवर जास्त कालावधीसाठी प्ले करणे पुढे सुरू ठेवल्यामुळे तुमच्या श्रवणशक्तीचे नुकसान होऊ शकते."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"चेतावणी,\nतुम्ही सध्या असुरक्षित पातळीवर प्ले होणारा मोठ्या आवाजातील आशय ऐकत आहात.\n\nएवढ्या मोठ्याने ऐकणे पुढे सुरू ठेवणे तुमच्या श्रवणशक्तीचे कायमचे नुकसान करेल."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"उच्च व्हॉल्यूममध्ये ऐकत राहायचे आहे का?\n\n हेडफोनचा व्हॉल्यूम हा शिफारस केलेल्या वेळेपेक्षा जास्त वेळ उच्च आहे, जो तुमच्या ऐकण्याच्या क्षमतेवर विपरीत परिणाम करू शकतो"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"मोठा आवाज डिटेक्ट झाला आहे\n\nहेडफोनचा व्हॉल्यूम हा शिफारस केलेल्या व्हॉल्यूमपेक्षा उच्च आहे, जो तुमच्या ऐकण्याच्या क्षमतेवर विपरीत परिणाम करू शकतो"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"प्रवेशयोग्यता शॉर्टकट वापरायचा?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"शॉर्टकट सुरू असताना, दोन्ही व्‍हॉल्‍यूम बटणे तीन सेकंदांसाठी प्रेस करून ठेवल्याने अ‍ॅक्सेसिबिलिटी वैशिष्ट्य सुरू होईल."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"अ‍ॅक्सेसिबिलिटी वैशिष्ट्यांसाठी शॉर्टकट सुरू करायचा आहे का?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"पुन्हा सुरू करा"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"कोणतीही कार्य ॲप्स सपोर्ट करत नाहीत"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"कोणतीही वैयक्तिक ॲप्स सपोर्ट करत नाहीत"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"ऑफिसची प्रोफाइल <xliff:g id="APP">%s</xliff:g> उघडायची आहे का?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"वैयक्तिक प्रोफाइल <xliff:g id="APP">%s</xliff:g> मध्ये उघडायची आहे का?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"ऑफिसची प्रोफाइल <xliff:g id="APP">%s</xliff:g> मध्ये उघडायची आहे का?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"work app मधून कॉल करायचा आहे का?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"work app वर स्विच करायचे आहे का?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"तुमची संस्था तुम्हाला फक्त work app वरून कॉल करण्याची अनुमती देते"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"तुमची संस्था तुम्हाला फक्त work app वरून मेसेज पाठवण्याची अनुमती देते"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"वैयक्तिक ब्राउझर वापरा"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"कार्य ब्राउझर वापरा"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"कॉल करा"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"स्विच करा"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"सिम नेटवर्क अनलॉक पिन"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM नेटवर्क सबसेट अनलॉक पिन"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM कॉर्पोरेट अनलॉक पिन"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 7d0dfcc..e8c5ab9 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -625,11 +625,11 @@
     <string name="biometric_error_generic" msgid="6784371929985434439">"Ralat semasa membuat pengesahan"</string>
     <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Gunakan kunci skrin"</string>
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Masukkan kunci skrin untuk teruskan"</string>
-    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Tekan dengan kuat pada penderia"</string>
+    <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Tekan penderia dengan kuat"</string>
     <string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Tidak dapat mengecam cap jari. Cuba lagi."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Bersihkan penderia cap jari dan cuba lagi"</string>
     <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Bersihkan penderia dan cuba lagi"</string>
-    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Tekan dengan kuat pada penderia"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Tekan penderia dengan kuat"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Jari digerakkan terlalu perlahan. Sila cuba lagi."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Cuba cap jari lain"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Terlalu terang"</string>
@@ -686,14 +686,14 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"Gerakkan telefon ke kiri anda"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"Gerakkan telefon ke kanan anda"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Sila lihat terus pada peranti anda."</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Gagal mengesan wajah anda. Pegang telefon anda pada paras mata."</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Wajah tidak kelihatan. Pegang telefon pada paras mata."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Terlalu bnyk gerakan. Pegang telefon dgn stabil."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Sila daftarkan semula wajah anda."</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"Tidak dapat mengecam wajah. Cuba lagi."</string>
     <string name="face_acquired_too_similar" msgid="8882920552674125694">"Tukar sedikit kedudukan kepala anda"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Lihat terus pada telefon anda"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Lihat terus pada telefon anda"</string>
-    <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Lihat terus pada telefon anda"</string>
+    <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Lihat lebih lurus pada telefon"</string>
+    <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Lihat lebih lurus pada telefon"</string>
+    <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Lihat lebih lurus pada telefon"</string>
     <string name="face_acquired_obscured" msgid="4917643294953326639">"Tanggalkan apa-apa yang menutup wajah anda."</string>
     <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Bersihkan bahagian atas skrin anda, termasuk bar hitam"</string>
     <!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
@@ -1396,7 +1396,7 @@
     <string name="hardware" msgid="1800597768237606953">"Tunjukkan papan kekunci maya"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurasikan <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurasikan papan kekunci fizikal"</string>
-    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Ketik untuk memilih bahasa dan susun atur"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Ketik untuk memilih bahasa dan reka letak"</string>
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Paparkan di atas apl lain"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Alih keluar"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Naikkan kelantangan melebihi paras yang disyokorkan?\n\nMendengar pada kelantangan yang tinggi untuk tempoh yang lama boleh merosakkan pendengaran anda."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Amaran,\nAnda telah melebihi jumlah isyarat bunyi kuat yang boleh didengari dengan selamat menggunakan fon kepala dalam masa seminggu.\n\nMendengar melebihi had ini akan merosakkan pendengaran anda secara kekal."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Amaran,\nAnda telah melebihi 5 kali ganda jumlah isyarat bunyi kuat yang boleh didengari dengan selamat menggunakan fon kepala dalam masa seminggu.\n\nKelantangan telah dikurangkan untuk melindungi pendengaran anda."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Kelantangan media yang anda dengar boleh mengakibatkan kerosakan pendengaran apabila dilakukan untuk jangka masa yang panjang.\n\nMemainkan media pada kelantangan ini secara berterusan untuk jangka masa yang panjang boleh merosakkan pendengaran anda."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Amaran,\nAnda sedang mendengar kandungan lantang yang dimainkan pada tahap yang tidak selamat.\n\nMendengar pada kelantangan secara berterusan ini akan merosakkan pendengaran anda secara kekal."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Teruskan mendengar pada kelantangan tinggi?\n\nKelantangan fon kepala tinggi melebihi tempoh yang disyorkan. Kelantangan ini boleh merosakkan pendengaran anda"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Bunyi kuat telah dikesan\n\nKelantangan fon kepala lebih tinggi daripada tahap yang disyorkan. Kelantangan ini boleh merosakkan pendengaran anda"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gunakan Pintasan Kebolehaksesan?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Apabila pintasan dihidupkan, tindakan menekan kedua-dua butang kelantangan selama 3 saat akan memulakan ciri kebolehaksesan."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Hidupkan pintasan untuk ciri kebolehaksesan?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Nyahjeda"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Tiada apl kerja"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Tiada apl peribadi"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Buka <xliff:g id="APP">%s</xliff:g> kerja?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Buka pada <xliff:g id="APP">%s</xliff:g> peribadi?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Buka pada <xliff:g id="APP">%s</xliff:g> kerja?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Panggil daripada apl kerja?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Beralih kepada apl kerja?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Organisasi anda hanya membenarkan anda membuat panggilan daripada apl kerja"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Organisasi anda hanya membenarkan anda menghantar mesej daripada apl kerja"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Gunakan penyemak imbas peribadi"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Gunakan penyemak imbas kerja"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Panggil"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Beralih"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN buka kunci rangkaian SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN buka kunci subset rangkaian SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN buka kunci korporat SIM"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 196a641..e206ad3 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -635,7 +635,7 @@
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"အလွန် လင်းသည်"</string>
     <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"ဖွင့်ပိတ်ခလုတ် နှိပ်လိုက်သည်"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ပြင်ဆင်ကြည့်ပါ"</string>
-    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"အကြိမ်တိုင်း လက်ချောင်းအနေအထားကို အနည်းငယ်ပြောင်းပါ"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"လက်ချောင်းအနေအထား နည်းနည်းစီ ပြောင်းပါ"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_error_not_match" msgid="4599441812893438961">"လက်ဗွေကို မသိရှိပါ"</string>
@@ -1369,7 +1369,7 @@
     <string name="usb_power_notification_message" msgid="7284765627437897702">"ချိတ်ဆက်ထားသည့် စက်ပစ္စည်းကို အားသွင်းနေသည်။ နောက်ထပ်ရွေးချယ်စရာများအတွက် တို့ပါ။"</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"အန်နာလော့ အသံကိရိယာကို တွေ့ထားပါသည်"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"တပ်ဆင်ထားသော ကိရိယာကို ဤဖုန်းနှင့် တွဲသုံး၍မရပါ။ ပိုမိုလေ့လာရန် တို့ပါ။"</string>
-    <string name="adb_active_notification_title" msgid="408390247354560331">"USB အမှားရှာပြင်ခြင်း ချိတ်ဆက်ထားသည်"</string>
+    <string name="adb_active_notification_title" msgid="408390247354560331">"USB အမှားရှာပြင်ခြင်း ချိတ်ထားသည်"</string>
     <string name="adb_active_notification_message" msgid="5617264033476778211">"USB အမှားရှာပြင်ခြင်းကို ပိတ်ရန် တို့ပါ"</string>
     <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB ဖြင့် အမှားရှာပြင်ခြင်းကို ပိတ်ရန် ရွေးပါ။"</string>
     <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ကြိုးမဲ့ အမှားရှာပြင်ခြင်းကို ချိတ်ဆက်ပြီးပြီ"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"ဖယ်ရှားရန်"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"အသံကို အကြံပြုထားသည့် ပမာဏထက် မြှင့်ပေးရမလား?\n\nအသံကို မြင့်သည့် အဆင့်မှာ ကြာရှည်စွာ နားထောင်ခြင်းက သင်၏ နားကို ထိခိုက်စေနိုင်သည်။"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"သတိပေးချက်-\nတစ်ပတ်တာအတွင်း နားကြပ်ဖြင့် ဘေးကင်းကင်း အသံကျယ်လောင်စွာ နားထောင်နိုင်သည့် ပမာဏကို ကျော်လွန်သွားပါပြီ။\n\nဤကန့်သတ်ချက်ကျော်လွန်ခြင်းက သင့်အကြားအာရုံကို ထာဝရထိခိုက်စေမည်။"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"သတိပေးချက်-\nတစ်ပတ်တာအတွင်း နားကြပ်ဖြင့် ဘေးကင်းကင်း အသံကျယ်လောင်စွာ နားထောင်နိုင်သည့် ပမာဏထက် ၅ ဆ ကျော်လွန်သွားပါပြီ။\n\nသင့်အကြားအာရုံကို မထိခိုက်စေရန် အသံတိုးလိုက်သည်။"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"မီဒီယာကို ယခုနားထောင်သည့်အဆင့်ဖြင့် အချိန်ကြာမြင့်စွာ နားထောင်ပါက အကြားအာရုံကို ထိခိုက်နိုင်သည်။\n\nဤအဆင့်ဖြင့် အချိန်ကြာမြင့်စွာ ဆက်ဖွင့်ခြင်းက သင့်အကြားအာရုံကို ထိခိုက်စေနိုင်သည်။"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"သတိပေးချက်-\nသင်သည် ကျယ်လောင်သော အကြောင်းအရာကို အန္တရာယ်ရှိသောအဆင့်ဖြင့် လက်ရှိဖွင့်ထားသည်။\n\nဤသို့ကျယ်လောင်စွာ ဆက်လက်နားထောင်ခြင်းက သင့်အကြားအာရုံကို ထာဝရထိခိုက်စေမည်။"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"အသံကျယ်ကျယ်ဖြင့် ဆက်နားဆင်မလား။\n\nနားကြပ်အသံအား အကြံပြုထားသည်ထက် ပိုကြာရှည်စွာ ချဲ့ထားပြီး ၎င်းက သင့်အကြားအာရုံကို ထိခိုက်စေနိုင်သည်"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"ကျယ်လောင်သောအသံကို သိရှိသည်\n\nနားကြပ်အသံအား အကြံပြုထားသည်ထက် ပိုချဲ့ထားပြီး ၎င်းက သင့်အကြားအာရုံကို ထိခိုက်စေနိုင်သည်"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"အများသုံးနိုင်မှု ဖြတ်လမ်းလင့်ခ်ကို အသုံးပြုလိုပါသလား။"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ဖြတ်လမ်းလင့်ခ်ကို ဖွင့်ထားစဉ် အသံထိန်းခလုတ် နှစ်ခုစလုံးကို ၃ စက္ကန့်ခန့် ဖိထားခြင်းဖြင့် အများသုံးနိုင်သည့် ဝန်ဆောင်မှုကို ဖွင့်နိုင်သည်။"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"အများသုံးစွဲနိုင်မှုဆိုင်ရာ ဝန်ဆောင်မှုများအတွက် ဖြတ်လမ်းကို ဖွင့်မလား။"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"ပြန်ဖွင့်ရန်"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"အလုပ်သုံးအက်ပ်များ မရှိပါ"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ကိုယ်ပိုင်အက်ပ်များ မရှိပါ"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"အလုပ်သုံး <xliff:g id="APP">%s</xliff:g> ဖွင့်မလား။"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"ကိုယ်ပိုင် <xliff:g id="APP">%s</xliff:g> တွင် ဖွင့်မလား။"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"အလုပ် <xliff:g id="APP">%s</xliff:g> တွင် ဖွင့်မလား။"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"အလုပ်သုံးအက်ပ်မှ ဖုန်းဆက်မလား။"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"အလုပ်သုံးအက်ပ်သို့ ပြောင်းမလား။"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"သင့်အဖွဲ့အစည်းသည် သင့်အား အလုပ်သုံးအက်ပ်များမှသာ ဖုန်းဆက်ခွင့်ပြုသည်"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"သင့်အဖွဲ့အစည်းသည် သင့်အား အလုပ်သုံးအက်ပ်များမှသာ မက်ဆေ့ဂျ်ပို့ခွင့်ပြုသည်"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ကိုယ်ပိုင်ဘရောင်ဇာ သုံးရန်"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"အလုပ်သုံးဘရောင်ဇာ သုံးရန်"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"ဖုန်းဆက်ရန်"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"ပြောင်းရန်"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"ဆင်းမ်ကွန်ရက် လော့ခ်ဖွင့်ရန် ပင်နံပါတ်"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"ဆင်းမ်ကွန်ရက်ခွဲ လော့ခ်ဖွင့်ရန် ပင်နံပါတ်"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"ဆင်းမ်ကော်ပိုရိတ် လော့ခ်ဖွင့်ရန် ပင်နံပါတ်"</string>
@@ -2332,8 +2333,8 @@
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ပိတ်ရန်"</string>
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> စီစဉ်သတ်မှတ်ထားသည်"</string>
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"ကီးဘုတ်အပြင်အဆင်ကို <xliff:g id="LAYOUT_1">%s</xliff:g> ဟု သတ်မှတ်ထားသည်။ ပြောင်းရန်တို့ပါ။"</string>
-    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"ကီးဘုတ်အပြင်အဆင်ကို <xliff:g id="LAYOUT_1">%1$s</xliff:g>၊ <xliff:g id="LAYOUT_2">%2$s</xliff:g> ဟု သတ်မှတ်ထားသည်။ ပြောင်းရန်တို့ပါ။"</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"ကီးဘုတ်အပြင်အဆင်ကို <xliff:g id="LAYOUT_1">%1$s</xliff:g>၊ <xliff:g id="LAYOUT_2">%2$s</xliff:g>၊ <xliff:g id="LAYOUT_3">%3$s</xliff:g> ဟု သတ်မှတ်ထားသည်။ ပြောင်းရန်တို့ပါ။"</string>
+    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"ကီးဘုတ်ကို <xliff:g id="LAYOUT_1">%1$s</xliff:g>၊ <xliff:g id="LAYOUT_2">%2$s</xliff:g> ဟု သတ်မှတ်ထားသည်။ ပြောင်းရန်တို့ပါ။"</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"ကီးဘုတ်ကို <xliff:g id="LAYOUT_1">%1$s</xliff:g>၊ <xliff:g id="LAYOUT_2">%2$s</xliff:g>၊ <xliff:g id="LAYOUT_3">%3$s</xliff:g> ဟု သတ်မှတ်ထားသည်။ ပြောင်းရန်တို့ပါ။"</string>
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ကီးဘုတ်အပြင်အဆင်ကို <xliff:g id="LAYOUT_1">%1$s</xliff:g>၊ <xliff:g id="LAYOUT_2">%2$s</xliff:g>၊ <xliff:g id="LAYOUT_3">%3$s</xliff:g> သို့ သတ်မှတ်လိုက်သည်… ပြောင်းရန် တို့ပါ။"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ပကတိကီးဘုတ်များကို စီစဉ်သတ်မှတ်ထားသည်"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ကီးဘုတ်များကြည့်ရန် တို့ပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 43bbac7e..a2102bc 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Fjern"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vil du øke volumet til over anbefalt nivå?\n\nHvis du hører på et høyt volum over lengre perioder, kan det skade hørselen din."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Advarsel:\nDu har overskredet antallet høye lydsignaler det er trygt å lytte til i løpet av en uke via hodetelefoner.\n\nHvis du går over denne grensen, blir hørselen permanent skadet."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Advarsel:\nDu har overskredet 5 ganger antallet høye lydsignaler det er trygt å lytte til i løpet av en uke via hodetelefoner.\n\nVolumet er senket for å beskytte hørselen."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Lydnivået du bruker til å lytte til medier, kan føre til hørselsskade når det vedvarer over lengre perioder.\n\nHvis du fortsetter å spille av på dette nivået over lengre perioder, kan du skade hørselen."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Advarsel:\nDu lytter til høyt innhold som spilles av på et utrygt nivå.\n\nHvis du fortsetter å lytte på dette lydnivået, fører det til permanent hørselsskade."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Vil du fortsette å lytte på høyt volum?\n\nVolumet på hodetelefonene har vært høyt lenger enn anbefalt, noe som kan skade hørselen din"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Høy lyd registrert\n\nVolumet på hodetelefonene har vært høyere enn anbefalt, noe som kan skade hørselen din"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vil du bruke tilgjengelighetssnarveien?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Når snarveien er på, starter en tilgjengelighetsfunksjon når du trykker inn begge volumknappene i tre sekunder."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Vil du slå på snarveien for tilgjengelighetsfunksjoner?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Slå av pausen"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Ingen jobbapper"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Ingen personlige apper"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Vil du åpne <xliff:g id="APP">%s</xliff:g> for jobb?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Vil du åpne i <xliff:g id="APP">%s</xliff:g> for personlig bruk?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Vil du åpne i <xliff:g id="APP">%s</xliff:g> for jobb?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Vil du ringe fra en jobbapp?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Vil du bytte til en jobbapp?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Organisasjonen din tillater bare at du ringer fra jobbapper"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Organisasjonen din tillater bare at du sender meldinger fra jobbapper"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Bruk den personlige nettleseren"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Bruk jobbnettleseren"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Ring"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Bytt"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN-kode for å fjerne operatørlåser"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN-kode for å fjerne bestemte operatørlåser"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN-kode for å låse opp SIM-kort for bedrifter"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 903ee0b..83cde3c 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -179,7 +179,7 @@
     <string name="low_memory" product="watch" msgid="3479447988234030194">"भण्डारण भरिएको छ हेर्नुहोस्। ठाउँ खाली गर्न केही फाइलहरू मेटाउनुहोस्।"</string>
     <string name="low_memory" product="tv" msgid="6663680413790323318">"Android टिभी डिभाइसको भण्डारण भरिएको छ। ठाउँ खाली गर्न केही फाइलहरू मेट्नुहोस्।"</string>
     <string name="low_memory" product="default" msgid="2539532364144025569">"फोन भण्डारण भरिएको छ! ठाउँ खाली गर्नको लागि केही फाइलहरू मेटाउनुहोस्।"</string>
-    <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{प्रमाणपत्र जारी गर्ने निकाय इन्स्टल गरियो}other{प्रमाणपत्र जारी गर्ने निकायहरू इन्स्टल गरियो}}"</string>
+    <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{प्रमाणपत्र जारी गर्ने निकायको प्रमाणपत्र इन्स्टल गरियो}other{प्रमाणपत्र जारी गर्ने निकायका प्रमाणपत्रहरू इन्स्टल गरिए}}"</string>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"अज्ञात तेस्रो पक्ष द्वारा"</string>
     <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"तपाईंको कार्य प्रोफाइलका प्रशासकद्वारा"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"<xliff:g id="MANAGING_DOMAIN">%s</xliff:g> द्वारा"</string>
@@ -694,7 +694,7 @@
     <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"आफ्नो फोनमा अझ सीधा हेर्नुहोस्"</string>
     <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"आफ्नो फोनमा अझ सीधा हेर्नुहोस्"</string>
     <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"आफ्नो फोनमा अझ सीधा हेर्नुहोस्"</string>
-    <string name="face_acquired_obscured" msgid="4917643294953326639">"तपाईंको अनुहार लुकाउने सबै कुरा हटाउनुहोस्।"</string>
+    <string name="face_acquired_obscured" msgid="4917643294953326639">"आफ्नो अनुहार छोप्ने सबै कुरा हटाउनुहोस्।"</string>
     <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"कालो रङको पट्टीलगायत आफ्नो स्क्रिनको माथिल्लो भाग सफा गर्नुहोस्"</string>
     <!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
     <skip />
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"हटाउनुहोस्"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"सिफारिस तहभन्दा आवाज ठुलो गर्नुहुन्छ?\n\nलामो समय सम्म उच्च आवाजमा सुन्दा तपाईँको सुन्ने शक्तिलाई हानी गर्न सक्छ।"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"चेतावनी,\nतपाईंले एक हप्तामा हेडफोनमार्फत सुरक्षित रूपमा सुन्न मिल्ने ठुला आवाजयुक्त सिग्नलहरूको मात्राका सम्बन्धमा तोकिएको सीमा नाघ्नुभएको छ।\n\nयो सीमा नाघेका खण्डमा तपाईंको श्रवण शक्ति सदाका लागि खराब हुने छ।"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"चेतावनी,\nतपाईंले एक हप्तामा हेडफोनमार्फत सुरक्षित रूपमा सुन्न मिल्ने ठुला आवाजयुक्त सिग्नलहरूको मात्राका सम्बन्धमा तोकिएको सीमा ५ गुणाले नाघ्नुभएको छ।\n\nतपाईंको श्रवण शक्तिमा असर नपरोस् भन्नाका लागि भोल्युम घटाइएको छ।"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"तपाईंले अहिले जति भोल्युममा मिडिया सुनिरहनुभएको छ त्यति नै भोल्युममा लामो समयसम्म मिडिया सुन्नुभयो भने तपाईंको श्रवण शक्ति खराब हुन सक्छ।\n\nतपाईंले लामो समयसम्म यति नै भोल्युममा मिडिया सुनिराख्नुभयो भने तपाईंको श्रवण शक्ति खराब हुन सक्छ।"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"चेतावनी,\nतपाईं अहिले असुरक्षित रूपमा उच्च भोल्युममा सामग्री सुन्दै हुनुहुन्छ।\n\nतपाईंले लामो समयसम्म यति नै भोल्युममा सामग्री सुनिराख्नुभयो भने तपाईंको श्रवण शक्ति सदाका लागि खराब हुने छ।"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"ठुलो आवाजमा सुनिरहन चाहनुहुन्छ?\n\nहेडफोनको भोल्युम सिफारिस गरिएको समयभन्दा लामो समयदेखि उच्च छ। यसले तपाईंको श्रवण शक्तिमा क्षति पुर्‍याउन सक्छ"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"ठुलो आवाज पत्ता लाग्यो\n\nहेडफोनको भोल्युम सिफारिस गरिएको स्तरभन्दा उच्च छ। यसले तपाईंको श्रवण शक्ति क्षय गर्न सक्छ"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"पहुँच सम्बन्धी सर्टकट प्रयोग गर्ने हो?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"यो सर्टकट सक्रिय हुँदा, ३ सेकेन्डसम्म दुवै भोल्युम बटन थिच्नुले पहुँचसम्बन्धी कुनै सुविधा सुरु गर्ने छ।"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"एक्सेसिबिलिटीसम्बन्धी सुविधा  प्रयोग गर्न सर्टकट अन गर्ने हो?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"अनपज गर्नुहोस्"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"यो सामग्री खोल्न मिल्ने कुनै पनि कामसम्बन्धी एप छैन"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"यो सामग्री खोल्न मिल्ने कुनै पनि व्यक्तिगत एप छैन"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"कामसम्बन्धी <xliff:g id="APP">%s</xliff:g> खोल्ने हो?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"व्यक्तिगत <xliff:g id="APP">%s</xliff:g> मा खोल्ने हो?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"कामसम्बन्धी <xliff:g id="APP">%s</xliff:g> मा खोल्ने हो?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"कामसम्बन्धी एपबाट कल गर्ने हो?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"कामसम्बन्धी एप प्रयोग गर्ने हो?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"तपाईंको सङ्गठनले तपाईंलाई कामसम्बन्धी एपहरूमार्फत मात्र कल गर्ने अनुमति दिन्छ"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"तपाईंको सङ्गठनले तपाईंलाई कामसम्बन्धी एपहरूमार्फत मात्र म्यासेज पठाउने अनुमति दिन्छ"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"व्यक्तिगत ब्राउजर प्रयोग गर्नुहोस्"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"कार्य ब्राउजर प्रयोग गर्नुहोस्"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"कल गर्नुहोस्"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"बदल्नुहोस्"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM को नेटवर्क अनलक गर्ने PIN"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM को नेटवर्कको सबसेट अनलक गर्ने PIN"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM को कर्पोरेट लक खोल्ने PIN"</string>
@@ -2331,10 +2332,10 @@
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"सेटिङमा जानुहोस्"</string>
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"अफ गर्नुहोस्"</string>
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> कन्फिगर गरिएको छ"</string>
-    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"किबोर्ड लेआउट सेट गरी <xliff:g id="LAYOUT_1">%s</xliff:g> बनाइएको छ। परिवर्तन गर्न ट्याप गर्नुहोस्।"</string>
-    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"किबोर्ड लेआउट सेट गरी <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> बनाइएको छ। परिवर्तन गर्न ट्याप गर्नुहोस्।"</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"किबोर्ड लेआउट सेट गरी <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> बनाइएको छ। परिवर्तन गर्न ट्याप गर्नुहोस्।"</string>
-    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"किबोर्ड लेआउट सेट गरी <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> बनाइएको छ… परिवर्तन गर्न ट्याप गर्नुहोस्।"</string>
+    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"किबोर्ड लेआउट <xliff:g id="LAYOUT_1">%s</xliff:g> भाषामा सेट गरिएको छ। बदल्न ट्याप गर्नुहोस्।"</string>
+    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"किबोर्ड लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> भाषामा सेट गरिएको छ। बदल्न ट्याप गर्नुहोस्।"</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"किबोर्ड लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> भाषामा सेट गरिएको छ। बदल्न ट्याप गर्नुहोस्।"</string>
+    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"किबोर्ड लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> भाषामा सेट गरिएको छ… बदल्न ट्याप गर्नुहोस्।"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"भौतिक किबोर्डहरू कन्फिगर गरिएका छन्"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"किबोर्डहरू हेर्न ट्याप गर्नुहोस्"</string>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index fc1f9c8..345807b 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Verwijderen"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Volume verhogen tot boven het aanbevolen niveau?\n\nAls je langere tijd op hoog volume naar muziek luistert, raakt je gehoor mogelijk beschadigd."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Waarschuwing:\nJe hebt de hoeveelheid harde geluidssignalen waarnaar iemand veilig in een week kan luisteren via een hoofdtelefoon overschreden.\n\nAls je over deze limiet gaat, kun je je gehoor permanent beschadigen."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Waarschuwing:\nJe hebt de limiet voor harde geluidssignalen waarnaar iemand veilig in een week kan luisteren via een hoofdtelefoon 5 keer overschreden.\n\nHet volume is lager gezet om je gehoor te beschermen."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Het niveau waarop je naar media luistert, kan leiden tot gehoorschade bij langdurig gebruik.\n\nAls je langere tijd dit geluidsniveau aanhoudt, kan dit je gehoor beschadigen."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Waarschuwing:\nJe luistert momenteel naar content met een hoog, onveilig geluidsniveau.\n\nAls je blijft luisteren op dit geluidsniveau, kun je je gehoor permanent beschadigen."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Wil je blijven luisteren op hoog volume?\n\nHet hoofdtelefoonvolume is langer dan de aanbevolen tijd hoog geweest, wat je gehoor kan beschadigen"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Hard geluid gedetecteerd\n\nHet hoofdtelefoonvolume is hoger dan aanbevolen, wat je gehoor kan beschadigen"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Snelkoppeling toegankelijkheid gebruiken?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Als de snelkoppeling aanstaat, houd je beide volumeknoppen 3 seconden ingedrukt om een toegankelijkheidsfunctie te starten."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Snelkoppeling voor toegankelijkheidsfuncties aanzetten?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Hervatten"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Geen werk-apps"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Geen persoonlijke apps"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"<xliff:g id="APP">%s</xliff:g> voor het werk openen?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Openen in persoonlijke <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Openen in <xliff:g id="APP">%s</xliff:g> voor het werk?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Bellen vanuit werk-app?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Overschakelen naar werk-app?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Je organisatie staat je alleen toe om te bellen vanuit werk-apps"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Je organisatie staat je alleen toe om berichten te sturen vanuit werk-apps"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Persoonlijke browser gebruiken"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Werkbrowser gebruiken"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Bellen"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Overschakelen"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Ontgrendelingspincode voor SIM-netwerk"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Ontgrendelingspincode voor subset van SIM-netwerk"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Ontgrendelingspincode voor zakelijke simkaart"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 6d038e1..cf8aa30 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -635,7 +635,7 @@
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ବହୁତ ଉଜ୍ଜ୍ୱଳ"</string>
     <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"ପାୱାର ବଟନ ଦବାଇବା ଚିହ୍ନଟ କରାଯାଇଛି"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ଆଡଜଷ୍ଟ କରି ଦେଖନ୍ତୁ"</string>
-    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ପ୍ରତି ଥର ଆପଣଙ୍କ ଆଙ୍ଗୁଠିର ସ୍ଥାନ ସାମାନ୍ୟ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ପ୍ରତି ଥର ଆପଣଙ୍କ ଆଙ୍ଗୁଠିର ଅବସ୍ଥିତି ସାମାନ୍ୟ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ଟିପଚିହ୍ନ ଚିହ୍ନଟ ହେଲା ନାହିଁ"</string>
@@ -1081,7 +1081,7 @@
     <string name="menu_function_shortcut_label" msgid="2367112760987662566">"Function+"</string>
     <string name="menu_space_shortcut_label" msgid="5949311515646872071">"ସ୍ପେସ୍‍"</string>
     <string name="menu_enter_shortcut_label" msgid="6709499510082897320">"ଏଣ୍ଟର୍"</string>
-    <string name="menu_delete_shortcut_label" msgid="4365787714477739080">"ଡିଲିଟ୍‌ କରନ୍ତୁ"</string>
+    <string name="menu_delete_shortcut_label" msgid="4365787714477739080">"ଡିଲିଟ କରନ୍ତୁ"</string>
     <string name="search_go" msgid="2141477624421347086">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
     <string name="search_hint" msgid="455364685740251925">"ସର୍ଚ୍ଚ କରନ୍ତୁ…"</string>
     <string name="searchview_description_search" msgid="1045552007537359343">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
@@ -1147,7 +1147,7 @@
     <string name="paste" msgid="461843306215520225">"ପେଷ୍ଟ କରନ୍ତୁ"</string>
     <string name="paste_as_plain_text" msgid="7664800665823182587">"ସାଦା ଟେକ୍ସଟ୍‍ ଭାବରେ ପେଷ୍ଟ କରନ୍ତୁ"</string>
     <string name="replace" msgid="7842675434546657444">"ବଦଳାନ୍ତୁ…"</string>
-    <string name="delete" msgid="1514113991712129054">"ଡିଲିଟ୍‍ କରନ୍ତୁ"</string>
+    <string name="delete" msgid="1514113991712129054">"ଡିଲିଟ କରନ୍ତୁ"</string>
     <string name="copyUrl" msgid="6229645005987260230">"URL କପି କରନ୍ତୁ"</string>
     <string name="selectTextMode" msgid="3225108910999318778">"ଟେକ୍ସଟ୍‍ ଚୟନ କରନ୍ତୁ"</string>
     <string name="undo" msgid="3175318090002654673">"ପୂର୍ବ ପରି କରନ୍ତୁ"</string>
@@ -1155,7 +1155,7 @@
     <string name="autofill" msgid="511224882647795296">"ଅଟୋଫିଲ୍‌"</string>
     <string name="textSelectionCABTitle" msgid="5151441579532476940">"ଟେକ୍ସଟ୍‍ ଚୟନ"</string>
     <string name="addToDictionary" msgid="8041821113480950096">"ଶବ୍ଦକୋଷରେ ଯୋଗ କରନ୍ତୁ"</string>
-    <string name="deleteText" msgid="4200807474529938112">"ଡିଲିଟ୍‍ କରନ୍ତୁ"</string>
+    <string name="deleteText" msgid="4200807474529938112">"ଡିଲିଟ କରନ୍ତୁ"</string>
     <string name="inputMethod" msgid="1784759500516314751">"ଇନପୁଟ୍ ପଦ୍ଧତି"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"ଟେକ୍ସଟ୍‌ କାର୍ଯ୍ୟ"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"ପଛକୁ ଫେରନ୍ତୁ"</string>
@@ -1369,7 +1369,7 @@
     <string name="usb_power_notification_message" msgid="7284765627437897702">"ଯୋଡ଼ାଯାଇଥିବା ଡିଭାଇସ୍ ଚାର୍ଜ ହେଉଛି। ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"ଆନାଲଗ୍‍ ଅଡିଓ ଆକ୍ସେସରୀ ଚିହ୍ନଟ ହେଲା"</string>
     <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ଏହି ଫୋନ୍‌ରେ କନେକ୍ଟ ଥିବା ଡିଭାଇସ୍‍ କମ୍ପାଟିବଲ୍‍ ନୁହେଁ। ଅଧିକ ଜାଣିବା ପାଇଁ ଟାପ୍‌ କରନ୍ତୁ।"</string>
-    <string name="adb_active_notification_title" msgid="408390247354560331">"USB ଡିବଗିଂ କନେକ୍ଟ କରାଯାଇଛି"</string>
+    <string name="adb_active_notification_title" msgid="408390247354560331">"USB ଡିବଗିଂ କନେକ୍ଟ ହୋଇଛି"</string>
     <string name="adb_active_notification_message" msgid="5617264033476778211">"USB ଡିବଗିଂକୁ ବନ୍ଦ କରିବା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
     <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB ଡିବଗିଙ୍ଗକୁ ଅକ୍ଷମ କରିବା ପାଇଁ ଚୟନ କରନ୍ତୁ।"</string>
     <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ୱାୟାରଲେସ୍ ଡିବଗିଂ ସଂଯୋଗ କରାଯାଇଛି"</string>
@@ -1396,7 +1396,7 @@
     <string name="hardware" msgid="1800597768237606953">"ଭର୍ଚୁଆଲ୍ କୀ’ବୋର୍ଡ ଦେଖାନ୍ତୁ"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>କୁ କନଫିଗର କରନ୍ତୁ"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ଫିଜିକାଲ କୀବୋର୍ଡଗୁଡ଼ିକୁ କନଫିଗର କରନ୍ତୁ"</string>
-    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ଭାଷା ଓ ଲେଆଉଟ୍‍ ଚୟନ କରିବା ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ଭାଷା ଓ ଲେଆଉଟ ଚୟନ କରିବା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"ଅନ୍ୟ ଆପ୍‌ଗୁଡ଼ିକ ଉପରେ ଦେଖାନ୍ତୁ"</string>
@@ -1513,7 +1513,7 @@
     <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"ଡ୍ରାଇଭିଙ୍ଗ ଆପ୍‌ରୁ ବାହାରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
     <string name="back_button_label" msgid="4078224038025043387">"ଫେରନ୍ତୁ"</string>
     <string name="next_button_label" msgid="6040209156399907780">"ପରବର୍ତ୍ତୀ"</string>
-    <string name="skip_button_label" msgid="3566599811326688389">"ଛାଡ଼ିଦିଅନ୍ତୁ"</string>
+    <string name="skip_button_label" msgid="3566599811326688389">"ବାଦ ଦିଅନ୍ତୁ"</string>
     <string name="no_matches" msgid="6472699895759164599">"କୌଣସି ମେଳକ ନାହିଁ"</string>
     <string name="find_on_page" msgid="5400537367077438198">"ପୃଷ୍ଠାରେ ଖୋଜନ୍ତୁ"</string>
     <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{#ଟି ମେଳ}other{{total}ଟିରୁ #ଟି ମେଳ}}"</string>
@@ -1557,7 +1557,7 @@
     <string name="date_picker_next_month_button" msgid="4858207337779144840">"ପରବର୍ତ୍ତୀ ମାସ"</string>
     <string name="keyboardview_keycode_alt" msgid="8997420058584292385">"ALT"</string>
     <string name="keyboardview_keycode_cancel" msgid="2134624484115716975">"ବାତିଲ କରନ୍ତୁ"</string>
-    <string name="keyboardview_keycode_delete" msgid="2661117313730098650">"ଡିଲିଟ୍‍ କରନ୍ତୁ"</string>
+    <string name="keyboardview_keycode_delete" msgid="2661117313730098650">"ଡିଲିଟ କରନ୍ତୁ"</string>
     <string name="keyboardview_keycode_done" msgid="2524518019001653851">"ହୋଇଗଲା"</string>
     <string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"ମୋଡ୍‍ ପରିବର୍ତ୍ତନ"</string>
     <string name="keyboardview_keycode_shift" msgid="3026509237043975573">"ଶିଫ୍ଟ"</string>
@@ -1663,7 +1663,7 @@
     <string name="kg_login_instructions" msgid="3619844310339066827">"ଅନଲକ୍‌ କରିବା ପାଇଁ, ଆପଣଙ୍କ Google ଆକାଉଣ୍ଟ ସହ ସାଇନ୍-ଇନ୍ କରନ୍ତୁ।"</string>
     <string name="kg_login_username_hint" msgid="1765453775467133251">"ୟୁଜରନେମ୍‍ (ଇମେଲ୍)"</string>
     <string name="kg_login_password_hint" msgid="3330530727273164402">"ପାସୱାର୍ଡ"</string>
-    <string name="kg_login_submit_button" msgid="893611277617096870">"ସାଇନ୍-ଇନ୍"</string>
+    <string name="kg_login_submit_button" msgid="893611277617096870">"ସାଇନ ଇନ କରନ୍ତୁ"</string>
     <string name="kg_login_invalid_input" msgid="8292367491901220210">"ଅମାନ୍ୟ ୟୁଜରନେମ୍‍ କିମ୍ୱା ପାସ୍‌ୱର୍ଡ।"</string>
     <string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"ଆପଣଙ୍କର ୟୁଜରନେମ୍‍ କିମ୍ୱା ପାସ୍‌ୱର୍ଡ ଭୁଲି ଯାଇଛନ୍ତି କି?\n"<b>"google.com/accounts/recovery"</b>" ଭିଜିଟ୍‍ କରନ୍ତୁ।"</string>
     <string name="kg_login_checking_password" msgid="4676010303243317253">"ଆକାଉଣ୍ଟ ଯାଞ୍ଚ କରାଯାଉଛି…"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"କାଢ଼ି ଦିଅନ୍ତୁ"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ମାତ୍ରା ବଢ଼ାଇ ସୁପାରିଶ ସ୍ତର ବଢ଼ାଉଛନ୍ତି? \n\n ଲମ୍ବା ସମୟ ପର୍ଯ୍ୟନ୍ତ ଉଚ୍ଚ ଶବ୍ଦରେ ଶୁଣିଲେ ଆପଣଙ୍କ ଶ୍ରବଣ ଶକ୍ତି ଖରାପ ହୋଇପାରେ।"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"ଚେତାବନୀ,\nହେଡଫୋନରେ ଗୋଟିଏ ସପ୍ତାହରେ ଜଣେ ସୁରକ୍ଷିତ ଭାବେ ଶୁଣିପାରୁଥିବା ଉଚ୍ଚ ସାଉଣ୍ଡ ସିଗନାଲର ପରିମାଣକୁ ଆପଣ ଅତିକ୍ରମ କରିଛନ୍ତି।\n\nଏହି ସୀମା ଅତିକ୍ରମ କରିବା ଫଳରେ ଆପଣଙ୍କ ଶ୍ରବଣଶକ୍ତି ସ୍ଥାୟୀ ଭାବେ ନଷ୍ଟ ହୋଇଯିବ।"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"ଚେତାବନୀ,\nହେଡଫୋନରେ ଗୋଟିଏ ସପ୍ତାହରେ ଜଣେ ସୁରକ୍ଷିତ ଭାବେ ଶୁଣିପାରୁଥିବା ଉଚ୍ଚ ସାଉଣ୍ଡ ସିଗନାଲର ପରିମାଣକୁ ଆପଣ 5 ଥର ଅତିକ୍ରମ କରିଛନ୍ତି।\n\nଆପଣଙ୍କ ଶ୍ରବଣଶକ୍ତିକୁ ସୁରକ୍ଷିତ ରଖିବା ପାଇଁ ଭଲ୍ୟୁମକୁ କମ କରିଦିଆଯାଇଛି।"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"ଆପଣ ଯେଉଁ ଲେଭେଲରେ ମିଡିଆ ଶୁଣୁଛନ୍ତି ତାହା ଦୀର୍ଘ ସମୟ ପାଇଁ ଜାରି ରହିଲେ ଶ୍ରବଣଶକ୍ତି ନଷ୍ଟ ହୋଇପାରେ।\n\nଦୀର୍ଘ ସମୟ ପାଇଁ ଏହି ଲେଭେଲରେ ପ୍ଲେ କରିବା ଜାରି ରଖିବା ଫଳରେ ଆପଣଙ୍କ ଶ୍ରବଣଶକ୍ତି ନଷ୍ଟ ହୋଇପାରେ।"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"ଚେତାବନୀ,\nବର୍ତ୍ତମାନ ଆପଣ ଏକ ଅସୁରକ୍ଷିତ ଲେଭେଲରେ ପ୍ଲେ ହେଉଥିବା ଉଚ୍ଚ ସାଉଣ୍ଡର ବିଷୟବସ୍ତୁ ଶୁଣୁଛନ୍ତି।\n\nଏହି ଉଚ୍ଚ ସାଉଣ୍ଡ ଶୁଣିବା ଜାରି ରଖିବା ଫଳରେ ଆପଣଙ୍କ ଶ୍ରବଣଶକ୍ତି ସ୍ଥାୟୀ ଭାବେ ନଷ୍ଟ ହୋଇଯିବ।"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"ଅଧିକ ଭଲ୍ୟୁମରେ ଶୁଣିବା ଜାରି ରଖିବେ?\n\nସୁପାରିଶ କରାଯାଇଥିବା ଅପେକ୍ଷା ଅଧିକ ସମୟ ପାଇଁ ହେଡଫୋନର ଭଲ୍ୟୁମ ଅଧିକ ଅଛି, ଯାହା ଆପଣଙ୍କ ଶ୍ରବଣ ଶକ୍ତିକୁ ନଷ୍ଟ କରିପାରିବ"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"ଉଚ୍ଚ ସାଉଣ୍ଡ ଚିହ୍ନଟ କରାଯାଇଛି\n\nହେଡଫୋନର ଭଲ୍ୟୁମ ସୁପାରିଶ କରାଯାଇଥିବା ଅପେକ୍ଷା ଅଧିକ ଅଛି, ଯାହା ଆପଣଙ୍କ ଶ୍ରବଣ ଶକ୍ତିକୁ ନଷ୍ଟ କରିପାରିବ"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ଆକ୍ସେସବିଲିଟି ଶର୍ଟକଟ୍‍ ବ୍ୟବହାର କରିବେ?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ସର୍ଟକଟ୍ ଚାଲୁ ଥିବା ବେଳେ, ଉଭୟ ଭଲ୍ୟୁମ୍ ବଟନ୍ 3 ସେକେଣ୍ଡ ପାଇଁ ଦବାଇବା ଦ୍ୱାରା ଏକ ଆକ୍ସେସବିଲିଟି ଫିଚର୍ ଆରମ୍ଭ ହେବ।"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"ଆକ୍ସେସିବିଲିଟୀ ଫିଚରଗୁଡ଼ିକ ପାଇଁ ସର୍ଟକଟ୍ ଚାଲୁ କରିବେ?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"ପୁଣି ଚାଲୁ କରନ୍ତୁ"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"କୌଣସି ୱାର୍କ ଆପ୍ ନାହିଁ"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"କୌଣସି ବ୍ୟକ୍ତିଗତ ଆପ୍ ନାହିଁ"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"ୱାର୍କ <xliff:g id="APP">%s</xliff:g>କୁ ଖୋଲିବେ?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"ବ୍ୟକ୍ତିଗତ <xliff:g id="APP">%s</xliff:g>ରେ ଖୋଲିବେ?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"ୱାର୍କ <xliff:g id="APP">%s</xliff:g>ରେ ଖୋଲିବେ?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"ୱାର୍କ ଆପରୁ କଲ କରିବେ?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ୱାର୍କ ଆପକୁ ସୁଇଚ କରିବେ?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"ଆପଣଙ୍କ ସଂସ୍ଥା ଆପଣଙ୍କୁ କେବଳ ୱାର୍କ ଆପ୍ସରୁ କଲ କରିବାକୁ ଅନୁମତି ଦିଏ"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"ଆପଣଙ୍କ ସଂସ୍ଥା ଆପଣଙ୍କୁ କେବଳ ୱାର୍କ ଆପ୍ସରୁ ମେସେଜ ପଠାଇବା ପାଇଁ ଅନୁମତି ଦିଏ"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ବ୍ୟକ୍ତିଗତ ବ୍ରାଉଜର୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ୱାର୍କ ବ୍ରାଉଜର୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"କଲ କରନ୍ତୁ"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"ସୁଇଚ କରନ୍ତୁ"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM ନେଟୱାର୍କ ଅନଲକ୍ PIN"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM ନେଟୱାର୍କର ସବସେଟ୍ ଅନଲକ୍ PIN"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM କର୍ପୋରେଟ୍ ଅନଲକ୍ PIN"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 32bfb06..9c083fa 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"ਹਟਾਓ"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ਕੀ ਵੌਲਿਊਮ  ਸਿਫ਼ਾਰਸ਼  ਕੀਤੇ ਪੱਧਰ ਤੋਂ ਵਧਾਉਣੀ ਹੈ?\n\nਲੰਮੇ ਸਮੇਂ ਤੱਕ ਉੱਚ ਵੌਲਿਊਮ ਤੇ ਸੁਣਨ ਨਾਲ ਤੁਹਾਡੀ ਸੁਣਨ ਸ਼ਕਤੀ ਨੂੰ ਨੁਕਸਾਨ ਪਹੁੰਚ ਸਕਦਾ ਹੈ।"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"ਚਿਤਾਵਨੀ,\nਤੁਸੀਂ ਉੱਚੀ ਧੁਨੀ ਦੇ ਸਿਗਨਲਾਂ ਦੀ ਮਾਤਰਾ ਨੂੰ ਪਾਰ ਕਰ ਚੁੱਕੇ ਹੋ ਜਿਸਨੂੰ ਕੋਈ ਵਿਅਕਤੀ ਹਫ਼ਤੇ ਵਿੱਚ ਹੈੱਡਫ਼ੋਨਾਂ \'ਤੇ ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਸੁਣ ਸਕਦਾ ਹੈ।\n\nਇਸ ਸੀਮਾ ਨੂੰ ਪਾਰ ਕਰਨ ਨਾਲ ਤੁਹਾਡੀ ਸੁਣਨ ਸ਼ਕਤੀ ਨੂੰ ਪੱਕੇ ਤੌਰ \'ਤੇ ਨੁਕਸਾਨ ਹੋ ਜਾਵੇਗਾ।"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"ਚਿਤਾਵਨੀ,\nਤੁਸੀਂ ਉੱਚੀ ਧੁਨੀ ਦੇ ਸਿਗਨਲਾਂ ਦੀ ਮਾਤਰਾ ਤੋਂ 5 ਗੁਣਾ ਪਾਰ ਕਰ ਚੁੱਕੇ ਹੋ ਜਿਸਨੂੰ ਕੋਈ ਵਿਅਕਤੀ ਹਫ਼ਤੇ ਵਿੱਚ ਹੈੱਡਫ਼ੋਨਾਂ \'ਤੇ ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਸੁਣ ਸਕਦਾ ਹੈ।\n\nਤੁਹਾਡੀ ਸੁਣਨ ਸ਼ਕਤੀ ਦੀ ਸੁਰੱਖਿਆ ਕਰਨ ਲਈ ਆਵਾਜ਼ ਨੂੰ ਘਟਾ ਦਿੱਤਾ ਗਿਆ ਹੈ।"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"ਜਿਸ ਪੱਧਰ \'ਤੇ ਤੁਸੀਂ ਮੀਡੀਆ ਨੂੰ ਸੁਣ ਰਹੇ ਹੋ, ਤਾਂ ਉਸ ਨੂੰ ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਸੁਣਨ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਸੁਣਨ ਸ਼ਕਤੀ ਨੂੰ ਨੁਕਸਾਨ ਹੋ ਸਕਦਾ ਹੈ।\n\nਲੰਬੇ ਸਮੇਂ ਤੱਕ ਇਸ ਪੱਧਰ \'ਤੇ ਚਲਾਉਣਾ ਜਾਰੀ ਰੱਖਣ ਨਾਲ ਤੁਹਾਡੀ ਸੁਣਨ ਸ਼ਕਤੀ ਨੂੰ ਨੁਕਸਾਨ ਹੋ ਸਕਦਾ ਹੈ।"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"ਚਿਤਾਵਨੀ,\nਤੁਸੀਂ ਫ਼ਿਲਹਾਲ ਅਸੁਰੱਖਿਅਤ ਪੱਧਰ \'ਤੇ ਚੱਲ ਰਹੀ ਉੱਚੀ ਆਵਾਜ਼ ਵਿੱਚ ਸਮੱਗਰੀ ਨੂੰ ਸੁਣ ਰਹੇ ਹੋ।\n\nਇਸ ਉੱਚੀ ਆਵਾਜ਼ ਨੂੰ ਸੁਣਨਾ ਜਾਰੀ ਰੱਖਣ ਨਾਲ ਤੁਹਾਡੇ ਸੁਣਨ ਸ਼ਕਤੀ ਨੂੰ ਪੱਕੇ ਤੌਰ \'ਤੇ ਨੁਕਸਾਨ ਹੋ ਸਕਦਾ ਹੈ।"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"ਕੀ ਉੱਚੀ ਅਵਾਜ਼ ਵਿੱਚ ਸੁਣਨਾ ਜਾਰੀ ਰੱਖਣਾ ਹੈ?\n\nਹੈੱਡਫ਼ੋਨ ਦੀ ਅਵਾਜ਼ ਸਿਫ਼ਾਰਸ਼ੀ ਸਮੇਂ ਨਾਲੋਂ ਜ਼ਿਆਦਾ ਦੇਰ ਤੱਕ ਉੱਚੀ ਰੱਖੀ ਗਈ, ਜਿਸ ਨਾਲ ਤੁਹਾਡੀ ਸੁਣਨ ਸ਼ਕਤੀ ਨੂੰ ਨੁਕਸਾਨ ਪਹੁੰਚ ਸਕਦਾ ਹੈ"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"ਉੱਚੀ ਧੁਨੀ ਦਾ ਪਤਾ ਲੱਗਾ\n\nਹੈੱਡਫ਼ੋਨ ਦੀ ਅਵਾਜ਼ ਨੂੰ ਸਿਫ਼ਾਰਸ਼ੀ ਪੱਧਰ ਨਾਲੋਂ ਜ਼ਿਆਦਾ ਦੇਰ ਤੱਕ ਉੱਚੀ ਰੱਖਿਆ ਗਿਆ, ਜਿਸ ਨਾਲ ਤੁਹਾਡੀ ਸੁਣਨ ਸ਼ਕਤੀ ਨੂੰ ਨੁਕਸਾਨ ਪਹੁੰਚ ਸਕਦਾ ਹੈ"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ਕੀ ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਵਰਤਣਾ ਹੈ?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ਸ਼ਾਰਟਕੱਟ ਚਾਲੂ ਹੋਣ \'ਤੇ, ਕਿਸੇ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਦੋਵੇਂ ਅਵਾਜ਼ ਬਟਨਾਂ ਨੂੰ 3 ਸਕਿੰਟ ਲਈ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"ਕੀ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਲਈ ਸ਼ਾਰਟਕੱਟ ਚਾਲੂ ਕਰਨਾ ਹੈ?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"ਰੋਕ ਹਟਾਓ"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ਕੋਈ ਕੰਮ ਸੰਬੰਧੀ ਐਪ ਨਹੀਂ"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ਕੋਈ ਨਿੱਜੀ ਐਪ ਨਹੀਂ"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"ਕੀ ਕੰਮ ਸੰਬੰਧੀ <xliff:g id="APP">%s</xliff:g> ਨੂੰ ਖੋਲ੍ਹਣਾ ਹੈ?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"ਕੀ ਨਿੱਜੀ <xliff:g id="APP">%s</xliff:g> ਵਿੱਚ ਖੋਲ੍ਹਣਾ ਹੈ?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"ਕੀ ਕੰਮ ਸੰਬੰਧੀ <xliff:g id="APP">%s</xliff:g> ਵਿੱਚ ਖੋਲ੍ਹਣਾ ਹੈ?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"ਕੀ ਕੰਮ ਸੰਬੰਧੀ ਐਪ ਤੋਂ ਕਾਲ ਕਰਨੀ ਹੈ?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ਕੀ ਕੰਮ ਸੰਬੰਧੀ ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰਨਾ ਹੈ?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਤੁਹਾਨੂੰ ਸਿਰਫ਼ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੋਂ ਕਾਲਾਂ ਕਰਨ ਦਿੰਦੀ ਹੈ"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਤੁਹਾਨੂੰ ਸਿਰਫ਼ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੋਂ ਹੀ ਸੁਨੇਹੇ ਭੇਜਣ ਦਿੰਦੀ ਹੈ"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ਨਿੱਜੀ ਬ੍ਰਾਊਜ਼ਰ ਵਰਤੋ"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ਕੰਮ ਸੰਬੰਧੀ ਬ੍ਰਾਊਜ਼ਰ ਵਰਤੋ"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"ਕਾਲ ਕਰੋ"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"ਸਿਮ ਨੈੱਟਵਰਕ ਅਣਲਾਕ ਪਿੰਨ"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"ਸਿਮ ਨੈੱਟਵਰਕ ਸਬਸੈੱਟ ਅਣਲਾਕ ਪਿੰਨ"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"ਸਿਮ ਕਾਰਪੋਰੇਟ ਅਣਲਾਕ ਪਿੰਨ"</string>
@@ -2333,7 +2334,7 @@
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> ਦਾ ਸੰਰੂਪਣ ਕੀਤਾ ਗਿਆ"</string>
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"ਕੀ-ਬੋਰਡ ਦਾ ਖਾਕਾ <xliff:g id="LAYOUT_1">%s</xliff:g> \'ਤੇ ਸੈੱਟ ਹੈ। ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"ਕੀ-ਬੋਰਡ ਦਾ ਖਾਕਾ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> \'ਤੇ ਸੈੱਟ ਹੈ। ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"ਕੀ-ਬੋਰਡ ਦਾ ਖਾਕਾ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>\'ਤੇ ਸੈੱਟ ਹੈ। ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"ਕੀ-ਬੋਰਡ ਦਾ ਖਾਕਾ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> \'ਤੇ ਸੈੱਟ ਹੈ। ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ਕੀ-ਬੋਰਡ ਦਾ ਖਾਕਾ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> \'ਤੇ ਸੈੱਟ ਹੈ… ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡਾਂ ਦਾ ਸੰਰੂਪਣ ਕੀਤਾ ਗਿਆ"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ਕੀ-ਬੋਰਡਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 540b45f..46202c9 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -637,7 +637,7 @@
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Zbyt jasno"</string>
     <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Wykryto naciśnięcie przycisku zasilania"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Popraw"</string>
-    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Za każdym razem lekko zmieniaj ułożenie palca"</string>
+    <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Za każdym razem lekko zmieniaj ułożenie palca"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Nie rozpoznano odcisku palca"</string>
@@ -1398,7 +1398,7 @@
     <string name="hardware" msgid="1800597768237606953">"Pokaż klawiaturę wirtualną"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Skonfiguruj urządzenie <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Skonfiguruj klawiatury fizyczne"</string>
-    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Kliknij, by wybrać język i układ"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Kliknij, aby wybrać język i układ"</string>
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Wyświetlanie nad innymi aplikacjami"</string>
@@ -1684,10 +1684,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Usuń"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Zwiększyć głośność ponad zalecany poziom?\n\nSłuchanie głośno przez długi czas może uszkodzić Twój słuch."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Ostrzeżenie\nLimit głośnych dźwięków, jakich przez tydzień możesz bezpiecznie słuchać przez słuchawki, został przekroczony.\n\nPrzekroczenie limitu spowoduje trwałe uszkodzenie słuchu."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Ostrzeżenie\nLimit głośnych dźwięków, jakich przez tydzień możesz bezpiecznie słuchać przez słuchawki, został 5-krotnie przekroczony.\n\nGłośność została zmniejszona, aby chronić Twój słuch."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Poziom głośności, na jakim słuchasz multimediów, może spowodować uszkodzenie słuchu, jeśli będzie się utrzymywał przez dłuższy czas.\n\nDalsze odtwarzanie na tym poziomie głośności przez dłuższy czas może uszkodzić Twój słuch."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Ostrzeżenie\nSłuchasz obecnie treści odtwarzanych na niebezpiecznym poziomie głośności.\n\nDalsze słuchanie przy takiej głośności trwale uszkodzi Twój słuch."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Słuchać dalej z wysokim poziomem głośności?\n\nGłośność na słuchawkach jest zbyt duża przez czas dłuższy niż zalecany, co może doprowadzić do uszkodzenia słuchu"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Wykryto głośny dźwięk\n\nGłośność na słuchawkach przekracza zalecane wartości, co może doprowadzić do uszkodzenia słuchu"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Użyć skrótu ułatwień dostępu?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Gdy skrót jest włączony, jednoczesne naciskanie przez trzy sekundy obu przycisków głośności uruchamia funkcję ułatwień dostępu."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Włączyć skrót ułatwień dostępu?"</string>
@@ -2166,14 +2164,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Cofnij wstrzymanie"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Brak aplikacji służbowych"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Brak aplikacji osobistych"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Otworzyć aplikację służbową <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Otworzyć w osobistej aplikacji <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Otworzyć w służbowej aplikacji <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Zadzwonić z aplikacji służbowej?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Przełączyć na aplikację służbową?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Twoja organizacja zezwala na nawiązywanie połączeń tylko z aplikacji służbowych"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Twoja organizacja zezwala na wysyłanie wiadomości tylko z aplikacji służbowych"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Użyj przeglądarki osobistej"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Użyj przeglądarki służbowej"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Zadzwoń"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Przełącz"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Kod PIN do karty SIM odblokowujący sieć"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Kod PIN odblokowujący podzbiór sieci na karcie SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Kod PIN odblokowujący dane korporacyjne na karcie SIM"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index cd47728..ced2958 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Remover"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Aumentar o volume acima do nível recomendado?\n\nOuvir em volume alto por longos períodos pode danificar sua audição."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Alerta,\nVocê excedeu a quantidade semanal de sinais de ruído alto que pode ser ouvida por fones de ouvido com segurança.\n\nUltrapassar esse limite vai prejudicar sua audição permanentemente."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Alerta,\nVocê excedeu em cinco vezes a quantidade semanal de sinais de ruído alto que pode ser ouvida por fones de ouvido com segurança.\n\nO volume foi diminuído para proteger sua audição."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Você está escutando mídia em um volume que pode resultar em danos à audição quando mantido por períodos prolongados.\n\nContinuar a reproduzir mídia nesse volume por períodos prolongados pode resultar em danos à sua audição."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Alerta,\nVocê está ouvindo conteúdo em um volume perigoso.\n\nContinuar a ouvir nesse volume vai prejudicar sua audição permanentemente."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Continuar ouvindo em volume alto?\n\nO volume dos fones de ouvido está alto há mais tempo que o recomendado. Isso pode causar danos à audição"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Som alto detectado\n\nO volume dos fones de ouvido está mais alto que o recomendado. Isso pode causar danos à audição"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Usar atalho de Acessibilidade?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Quando o atalho estiver ativado, pressione os dois botões de volume por três segundos para iniciar um recurso de acessibilidade."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Ativar atalho para recursos de acessibilidade?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Reativar"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nenhum app de trabalho"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nenhum app pessoal"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Abrir <xliff:g id="APP">%s</xliff:g> do perfil de trabalho?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Abrir no app <xliff:g id="APP">%s</xliff:g> do perfil pessoal?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Abrir no app <xliff:g id="APP">%s</xliff:g> do perfil de trabalho?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Ligar pelo app de trabalho?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Trocar para o app de trabalho?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Sua organização só permite fazer ligações usando apps de trabalho"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Sua organização só permite o envio de mensagens usando apps de trabalho"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usar o navegador pessoal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usar o navegador de trabalho"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Ligar"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Trocar"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN para desbloqueio da rede do chip"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN para desbloqueio do subconjunto de rede do chip"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN para desbloqueio do chip corporativo"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 7329334..3511eac 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -313,7 +313,7 @@
     <string name="permgroupdesc_storage" msgid="5378659041354582769">"aceder aos ficheiros no seu dispositivo"</string>
     <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Música e áudio"</string>
     <string name="permgroupdesc_readMediaAural" msgid="7565467343667089595">"aceder a música e áudio no seu dispositivo"</string>
-    <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Fotos e vídeos"</string>
+    <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"fotos e vídeos"</string>
     <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"aceder a fotos e vídeos no seu dispositivo"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Microfone"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"gravar áudio"</string>
@@ -687,7 +687,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"Mova o telemóvel para a sua esquerda"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"Mova o telemóvel para a sua direita"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Olhe mais diretamente para o dispositivo."</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Rosto não detetado. Segure o telemóvel ao nível dos olhos."</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"Rosto não detetado. Segure o telemóvel ao nível dos olhos"</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Demasiado movimento. Mantenha o telemóvel firme."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Volte a inscrever o rosto."</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"Impossível reconhecer o rosto. Tente novamente."</string>
@@ -703,7 +703,7 @@
     <skip />
     <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Não é possível criar o seu modelo de rosto. Tente novamente."</string>
     <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Óculos escuros detetados. O seu rosto tem de estar completamente visível."</string>
-    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Cobertura facial detetada. Todo o rosto tem de estar visível."</string>
+    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Máscara detetada. Todo o rosto tem de estar visível."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="5085202213036026288">"Não pode validar o rosto. Hardware não disponível."</string>
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" - "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Remover"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Aumentar o volume acima do nível recomendado?\n\nOuvir com um volume elevado durante longos períodos poderá ser prejudicial para a sua audição."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Aviso,\nExcedeu a quantidade de sinais sonoros altos que uma pessoa pode ouvir em segurança numa semana através de auscultadores.\n\nUltrapassar este limite prejudica permanentemente a sua audição."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Aviso,\nExcedeu 5 vezes a quantidade de sinais sonoros altos que uma pessoa pode ouvir em segurança numa semana através de auscultadores.\n\nO volume foi reduzido para proteger a sua audição."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"O nível ao qual está a ouvir conteúdo multimédia pode resultar em danos auditivos se o fizer durante longos períodos.\n\nContinuar a ouvir a este nível durante longos períodos pode ser prejudicial para a sua audição."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Aviso,\nEstá a ouvir conteúdo reproduzido com um volume alto e inseguro.\n\nContinuar a ouvir a este volume vai prejudicar permanentemente a sua audição."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Quer continuar a ouvir com um volume elevado?\n\nO volume dos auscultadores está elevado há mais tempo do que o recomendado, o que pode ser prejudicial para a sua audição"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Som alto detetado\n\nO volume dos auscultadores tem estado mais elevado do que o recomendado, o que pode ser prejudicial para a sua audição"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Pretende utilizar o atalho de acessibilidade?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Quando o atalho está ativado, premir ambos os botões de volume durante 3 segundos inicia uma funcionalidade de acessibilidade."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Ativar o atalho das funcionalidades de acessibilidade?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Retomar"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Sem apps de trabalho"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Sem apps pessoais"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Abrir a app <xliff:g id="APP">%s</xliff:g> de trabalho?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Abrir na app <xliff:g id="APP">%s</xliff:g> pessoal?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Abrir na app <xliff:g id="APP">%s</xliff:g> de trabalho?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Ligar a partir da app de trabalho?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Mudar para a app de trabalho?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"A sua organização só lhe permite fazer chamadas a partir de apps de trabalho"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"A sua organização só lhe permite enviar mensagens a partir de apps de trabalho"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usar navegador pessoal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usar navegador de trabalho"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Ligar"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Mudar"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN para desbloqueio de rede do cartão SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN para desbloqueio do subconjunto da rede do cartão SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN para desbloqueio empresarial do cartão SIM"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index cd47728..ced2958 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Remover"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Aumentar o volume acima do nível recomendado?\n\nOuvir em volume alto por longos períodos pode danificar sua audição."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Alerta,\nVocê excedeu a quantidade semanal de sinais de ruído alto que pode ser ouvida por fones de ouvido com segurança.\n\nUltrapassar esse limite vai prejudicar sua audição permanentemente."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Alerta,\nVocê excedeu em cinco vezes a quantidade semanal de sinais de ruído alto que pode ser ouvida por fones de ouvido com segurança.\n\nO volume foi diminuído para proteger sua audição."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Você está escutando mídia em um volume que pode resultar em danos à audição quando mantido por períodos prolongados.\n\nContinuar a reproduzir mídia nesse volume por períodos prolongados pode resultar em danos à sua audição."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Alerta,\nVocê está ouvindo conteúdo em um volume perigoso.\n\nContinuar a ouvir nesse volume vai prejudicar sua audição permanentemente."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Continuar ouvindo em volume alto?\n\nO volume dos fones de ouvido está alto há mais tempo que o recomendado. Isso pode causar danos à audição"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Som alto detectado\n\nO volume dos fones de ouvido está mais alto que o recomendado. Isso pode causar danos à audição"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Usar atalho de Acessibilidade?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Quando o atalho estiver ativado, pressione os dois botões de volume por três segundos para iniciar um recurso de acessibilidade."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Ativar atalho para recursos de acessibilidade?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Reativar"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nenhum app de trabalho"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nenhum app pessoal"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Abrir <xliff:g id="APP">%s</xliff:g> do perfil de trabalho?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Abrir no app <xliff:g id="APP">%s</xliff:g> do perfil pessoal?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Abrir no app <xliff:g id="APP">%s</xliff:g> do perfil de trabalho?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Ligar pelo app de trabalho?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Trocar para o app de trabalho?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Sua organização só permite fazer ligações usando apps de trabalho"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Sua organização só permite o envio de mensagens usando apps de trabalho"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usar o navegador pessoal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usar o navegador de trabalho"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Ligar"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Trocar"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN para desbloqueio da rede do chip"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN para desbloqueio do subconjunto de rede do chip"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN para desbloqueio do chip corporativo"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 00c4a18..d4bddd3 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Elimină"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Mărești volumul peste nivelul recomandat?\n\nDacă asculți perioade lungi la volum ridicat, auzul poate fi afectat."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Avertisment\nAi depășit numărul de semnale cu sunet puternic pe care le poți asculta într-o săptămână în căști.\n\nDepășirea limitei îți va afecta definitiv auzul."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Avertisment\nAi depășit de cinci ori numărul de semnale cu sunet puternic pe care le poți asculta într-o săptămână în căști.\n\nAm micșorat volumul pentru a-ți proteja auzul."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Nivelul la care asculți conținut media îți poate afecta auzul dacă este susținut pe perioade lungi de timp.\n\nContinuarea redării la acest nivel pentru perioade lungi de timp îți poate afecta auzul."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Avertisment\nAsculți conținut zgomotos la un nivel de sunet nesigur.\n\nContinuarea ascultării la acest volum îți va afecta definitiv auzul."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Vrei să asculți în continuare la volum ridicat?\n\nVolumul căștilor a fost ridicat mai mult timp decât este recomandat, iar acest lucru îți poate afecta auzul"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"S-au detectat sunete cu volum ridicat\n\nVolumul căștilor a fost mai ridicat decât este recomandat, iar acest lucru îți poate afecta auzul"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Folosești comanda rapidă pentru accesibilitate?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Când comanda rapidă e activată, dacă apeși ambele butoane de volum timp de trei secunde, vei lansa o funcție de accesibilitate."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Activezi comanda rapidă pentru funcțiile de accesibilitate?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Reactivează"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nicio aplicație pentru lucru"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nicio aplicație personală"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Deschizi <xliff:g id="APP">%s</xliff:g> pentru lucru?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Deschizi în aplicația <xliff:g id="APP">%s</xliff:g> personală?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Deschizi în aplicația <xliff:g id="APP">%s</xliff:g> pentru lucru?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Apelezi din aplicația pentru lucru?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Comuți la aplicația pentru lucru?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Organizația îți permite să inițiezi apeluri numai din aplicațiile pentru lucru"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Organizația îți permite să trimiți mesaje numai din aplicațiile pentru lucru"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Folosește browserul personal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Folosește browserul de serviciu"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Apelează"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Comută"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Codul PIN de deblocare SIM privind rețeaua"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Codul PIN de deblocare SIM privind subsetul de rețea"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Codul PIN de deblocare SIM corporativă"</string>
@@ -2335,7 +2336,7 @@
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Aspectul tastaturii este setat la <xliff:g id="LAYOUT_1">%s</xliff:g>. Atinge pentru a-l schimba."</string>
     <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Aspectul tastaturii este setat la <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Atinge pentru a-l schimba."</string>
     <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Aspectul tastaturii este setat la <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Atinge pentru a-l schimba."</string>
-    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Aspectul tastaturii este setat la <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Atinge pentru a-l schimba."</string>
+    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Tastatura este setată la <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Atinge pentru a schimba."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Tastaturile fizice au fost configurate"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Atinge pentru a vedea tastaturile"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index eaaa99d..fb1d5c6 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1684,10 +1684,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Удалить"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Установить громкость выше рекомендуемого уровня?\n\nВоздействие громкого звука в течение долгого времени может привести к повреждению слуха."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Внимание!\nПревышено количество громких звуков, которое считается безопасным при прослушивании в наушниках в течение недели.\n\nВыход за пределы лимита ведет к необратимому повреждению слуха."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Внимание!\nКоличество громких звуков, которое считается безопасным при прослушивании в наушниках в течение недели, превышено в 5 раз.\n\nГромкость снижена для защиты слуха."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Выбранный у вас уровень громкости вреден для слуха при долгом воздействии.\n\nПрослушивание на текущем уровне громкости в течение длительного времени может привести к повреждению слуха."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Внимание!\nВы слушаете аудио на опасном уровне громкости.\n\nПрослушивание на текущем уровне громкости ведет к необратимому повреждению слуха."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Продолжить воспроизведение с высокой громкостью?\n\nВы используете наушники при высоком уровне громкости дольше, чем рекомендуется. Это может привести к повреждению слуха."</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Обнаружен громкий звук\n\nУровень громкости наушников выше, чем рекомендуется. Это может привести к повреждению слуха."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Использовать быстрое включение?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Чтобы использовать функцию специальных возможностей, когда она включена, нажмите и удерживайте обе кнопки регулировки громкости в течение трех секунд."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Использовать быстрое включение?"</string>
@@ -2166,14 +2164,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Включить"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Не поддерживается рабочими приложениями."</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Не поддерживается личными приложениями."</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Открыть рабочее приложение \"<xliff:g id="APP">%s</xliff:g>\"?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Открыть в личном приложении \"<xliff:g id="APP">%s</xliff:g>\"?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Открыть в рабочем приложении \"<xliff:g id="APP">%s</xliff:g>\"?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Позвонить из рабочего приложения?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Перейти в рабочее приложение?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"В вашей организации разрешено звонить только из рабочих приложений."</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"В вашей организации разрешено отправлять сообщения только из рабочих приложений."</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Использовать личный браузер"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Использовать рабочий браузер"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Позвонить"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Перейти"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN-код для разблокировки сети SIM-карты"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN-код для разблокировки подмножества сети SIM-карты"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN-код для разблокировки корпоративной SIM-карты"</string>
@@ -2333,10 +2334,10 @@
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"Открыть настройки"</string>
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Отключить"</string>
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Устройство \"<xliff:g id="DEVICE_NAME">%s</xliff:g>\" настроено"</string>
-    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Для клавиатуры настроена раскладка <xliff:g id="LAYOUT_1">%s</xliff:g>. Нажмите, чтобы изменить."</string>
-    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Для клавиатуры настроены раскладки <xliff:g id="LAYOUT_1">%1$s</xliff:g> и <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Нажмите, чтобы изменить."</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Для клавиатуры настроены раскладки <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> и <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Нажмите, чтобы изменить."</string>
-    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Для клавиатуры настроено несколько раскладок: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> и другие. Нажмите, чтобы изменить."</string>
+    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Настроена раскладка клавиатуры для яз.: <xliff:g id="LAYOUT_1">%s</xliff:g>. Нажмите, чтобы изменить."</string>
+    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Настроены раскладки клавиатуры для яз.: <xliff:g id="LAYOUT_1">%1$s</xliff:g> и <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Нажмите, чтобы изменить."</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Настроены раскладки клавиатуры для яз.: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> и <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Нажмите, чтобы изменить."</string>
+    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Настроены раскладки клавиатуры для яз.: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> и др. Нажмите, чтобы изменить."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физические клавиатуры настроены"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Нажмите, чтобы посмотреть подключенные клавиатуры."</string>
 </resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index f4aef67..f1636db 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -702,7 +702,7 @@
     <skip />
     <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"ඔබගේ මුහුණු ආකෘතිය තැනිය නොහැකිය. නැවත උත්සාහ කරන්න."</string>
     <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"අඳුරු කණ්ණාඩි අනාවරණය කර ගන්නා ලදි. ඔබගේ මුහුණ සම්පූර්ණයෙන් දෘශ්‍යමාන විය යුතුය."</string>
-    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"මුහුණු ආවරණය අනාවරණය කර ගන්නා ලදි. ඔබගේ මුහුණ සම්පූර්ණයෙන් දෘශ්‍යමාන විය යුතුය."</string>
+    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"මුහුණු වැසීමක් හමු විය. මුහුණ සම්පූර්ණයෙන්ම පෙනිය යුතුය."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="5085202213036026288">"මුහුණ සත්‍යාපනය කළ නොහැක. දෘඩාංගය නොමැත."</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"ඉවත් කරන්න"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"නිර්දේශිතයි මට්ටමට වඩා ශබ්දය වැඩිද?\n\nදිගු කාලයක් සඳහා ඉහළ ශබ්දයක් ඇසීමෙන් ඇතැම් විට ඔබගේ ඇසීමට හානි විය හැක."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"අවවාදයයි,\nඔබ හෙඩ්ෆෝන් හරහා සතියක් තුළ සුරක්ෂිතව සවන් දිය හැකි ශබ්ද සංඥා ප්‍රමාණය ඉක්මවා ඇත.\n\nමෙම සීමාව ඉක්මවා යාම ඔබේ ශ්‍රවණයට ස්ථිරවම හානි කරනු ඇත."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"අවවාදයයි,\nඔබ හෙඩ්ෆෝන් හරහා සතියක් තුළ සුරක්ෂිතව සවන් දිය හැකි ශබ්ද සංඥා ප්‍රමාණය මෙන් 5 ගුණයක් ඉක්මවා ඇත.\n\nඔබේ ශ්‍රවණය ආරක්ෂා කිරීමට ශබ්දය අඩු කර ඇත."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"ඔබ මාධ්‍යයට සවන් දෙන මට්ටම දීර්ඝ කාලයක් තිස්සේ පවතින විට ශ්‍රවණාබාධ ඇති විය හැක.\n\nදිගු කාලයක් මෙම මට්ටමේ දී වාදනය කිරීම ඔබේ ශ්‍රවණයට හානි කළ හැක."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"අවවාදයයි,\nඔබ දැනට අනාරක්ෂිත මට්ටමින් වාදනය වන ඝෝෂාකාරී අන්තර්ගතයට සවන් දෙයි.\n\nමෙම මහා හඬින් සවන් දීම ඔබේ ශ්‍රවණයට ස්ථිරවම හානි කරනු ඇත."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"ඉහළ හඬකින් දිගටම සවන් දෙනවා ද?\n\nනිර්දේශිත කාලයට වඩා දිගු කාලයක් හෙඩ්ෆෝන් හඬ පරිමාව ඉහළ මට්ටමක පවතින අතර, එය ඔබේ ශ්‍රවණයට හානි කළ හැක"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"ඝෝෂාකාරී හඬ අනාවරණය විය\n\nනිර්දේශිත ප්‍රමාණයට වඩා හෙඩ්ෆෝන් හඬ පරිමාව වැඩි වී ඇති අතර, එය ඔබේ ශ්‍රවණයට හානි කළ හැක"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ප්‍රවේශ්‍යතා කෙටිමඟ භාවිතා කරන්නද?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"කෙටිමග ක්‍රියාත්මක විට, හඬ පරිමා බොත්තම් දෙකම තත්පර 3ක් තිස්සේ එබීමෙන් ප්‍රවේශ්‍යතා විශේෂාංගය ආරම්භ වනු ඇත."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"ප්‍රවේශ්‍යතා විශේෂාංග සඳහා කෙටි මග ක්‍රියාත්මක කරන්නද?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"විරාම නොකරන්න"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"කාර්යාල යෙදුම් නැත"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"පුද්ගලික යෙදුම් නැත"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"කාර්යාල <xliff:g id="APP">%s</xliff:g> විවෘත කරන්න ද?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"පුද්ගලික <xliff:g id="APP">%s</xliff:g> තුළ විවෘත කරන්න ද?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"කාර්යාල <xliff:g id="APP">%s</xliff:g> තුළ විවෘත කරන්න ද?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"කාර්යාල යෙදුමෙන් අමතන්න ද?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"කාර්යාල යෙදුම වෙත මාරු වන්නද?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"ඔබේ සංවිධානය ඔබට කාර්යාල යෙදුම්වලින් ඇමතුම් කිරීමට පමණක් ඉඩ දෙයි"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"ඔබේ සංවිධානය ඔබට කාර්යාල යෙදුම්වලින් පණිවුඩ යැවීමට පමණක් ඉඩ දෙයි"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"පුද්ගලික බ්‍රව්සරය භාවිත කරන්න"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"කාර්යාල බ්‍රව්සරය භාවිත කරන්න"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"අමතන්න"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"මාරු කරන්න"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM ජාල අගුලු හැරීමේ PIN"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM ජාල උප කට්ටල අගුලු හැරීමේ PIN"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM සමාගම් අගුලු හැරීමේ PIN"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index e9df03c..f9c2a9b 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -967,7 +967,7 @@
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Ak chcete odomknúť telefón alebo uskutočniť tiesňové volanie, stlačte Menu."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Telefón odomknete stlačením tlačidla Menu."</string>
     <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Odomknite nakreslením vzoru"</string>
-    <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Stav tiesne"</string>
+    <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Tiesňová linka"</string>
     <string name="lockscreen_return_to_call" msgid="3156883574692006382">"Zavolať späť"</string>
     <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Správne!"</string>
     <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Skúsiť znova"</string>
@@ -1684,10 +1684,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Odstrániť"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Zvýšiť hlasitosť nad odporúčanú úroveň?\n\nDlhodobé počúvanie pri vysokej hlasitosti môže poškodiť váš sluch."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Upozornenie:\nPrekročili ste počet hlasných zvukových signálov, ktoré je možné počas týždňa bezpečne počúvať v slúchadlách.\n\nPrekročením tohto limitu si natrvalo poškodíte sluch."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Upozornenie:\nPäťnásobne ste prekročili počet hlasných zvukových signálov, ktoré je možné počas týždňa bezpečne počúvať v slúchadlách.\n\nHlasitosť bola znížená, aby sa chránil váš sluch."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Dlhodobé vystavenie hluku na úrovni, na ktorej počúvate médiá, môže viesť k poškodeniu sluchu.\n\nAk ich budete naďalej dlhodobo prehrávať na tejto úrovni, môžete si poškodiť sluch."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Upozornenie:\nMomentálne počúvate hlasný obsah prehrávaný na nebezpečnej úrovni.\n\nAk budete naďalej počúvať pri tejto hlasitosti, natrvalo si poškodíte sluch."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Počúvate pri vysokej hlasitosti?\n\nHlasitosť slúchadiel bola vyššia dlhšie ako sa odporúča, čo môže poškodiť váš sluch"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Bol rozpoznaný hlasný zvuk\n\nHlasitosť slúchadiel bola vyššia, ako sa odporúča, čo môže poškodiť váš sluch"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Použiť skratku dostupnosti?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Keď je skratka zapnutá, stlačením obidvoch tlačidiel hlasitosti na tri sekundy spustíte funkciu dostupnosti."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Chcete zapnúť skratku pre funkcie dostupnosti?"</string>
@@ -1956,7 +1954,7 @@
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Znova spustiť aplikáciu"</string>
     <string name="work_mode_off_title" msgid="6367463960165135829">"Zrušiť pozast. prac. aplikácií?"</string>
     <string name="work_mode_turn_on" msgid="5316648862401307800">"Zrušiť pozastavenie"</string>
-    <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Zavolať na tiesňovú linku"</string>
+    <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Tiesňová linka"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Aplikácia nie je dostupná"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> nie je teraz dostupná."</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nie je k dispozícii"</string>
@@ -2166,14 +2164,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Zrušiť pozastavenie"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Žiadne pracovné aplikácie"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Žiadne osobné aplikácie"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Chcete otvoriť pracovnú aplikáciu <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Chcete obsah otvoriť v osobnej aplikácii <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Chcete obsah otvoriť v pracovnej aplikácii <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Chcete volať z pracovnej aplikácie?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Chcete prepnúť na pracovnú aplikáciu?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Vaša organizácia vám povoľuje volať iba z pracovných aplikácií"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Vaša organizácia vám povoľuje posielať správy iba z pracovných aplikácií"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Použiť osobný prehliadač"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Použiť pracovný prehliadač"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Volať"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Prepnúť"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN na odomknutie siete pre SIM kartu"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN na odomknutie podmnožiny siete pre SIM kartu"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN na odomknutie podnikovej SIM karty"</string>
@@ -2335,7 +2336,7 @@
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Klávesnica <xliff:g id="DEVICE_NAME">%s</xliff:g> je nakonfigurovaná"</string>
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Rozloženie klávesnice je nastavené na jazyk <xliff:g id="LAYOUT_1">%s</xliff:g>. Môžete to zmeniť klepnutím."</string>
     <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Rozloženie klávesnice je nastavené na jazyky <xliff:g id="LAYOUT_1">%1$s</xliff:g> a <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Môžete to zmeniť klepnutím."</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Rozloženie klávesnice je nastavené na jazyky <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> a <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Môžete to zmeniť klepnutím."</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Rozloženie klávesnice je nastavené na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> a <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Môžete to zmeniť klepnutím."</string>
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Rozloženie klávesnice je nastavené na jazyky <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> a <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Môžete to zmeniť klepnutím."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fyzické klávesnice sú nakonfigurované"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Klávesnice si zobrazíte klepnutím"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index e5e7303..a661ad8 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1684,10 +1684,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Odstrani"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ali želite povečati glasnost nad priporočeno raven?\n\nDolgotrajno poslušanje pri veliki glasnosti lahko poškoduje sluh."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Opozorilo!\nPrekoračili ste količino glasnih zvočnih signalov, ki je še varna pri poslušanju prek slušalk v enem tednu.\n\nPrekoračenje te omejitve vam bo povzročilo trajne poškodbe sluha."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Opozorilo!\nZa petkrat ste prekoračili količino glasnih zvočnih signalov, ki je še varna pri poslušanju prek slušalk v enem tednu.\n\nZaradi zaščite sluha je bila glasnost zmanjšana."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Raven glasnosti, pri kateri poslušate predstavnost, lahko ob dolgotrajnejši izpostavljenosti povzroči poškodbe sluha.\n\nNadaljnje dolgotrajno poslušanje pri takšni glasnosti vam lahko poškoduje sluh."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Opozorilo!\nTrenutno poslušate glasno vsebino pri ravni glasnosti, ki ni varna.\n\nNadaljnje poslušanje pri takšni glasnosti vam bo povzročilo trajne poškodbe sluha."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Želite še naprej poslušati pri visoki glasnosti?\n\nGlasnost v slušalkah je bila visoka dalj časa, kot je priporočeno, kar vam lahko poškoduje sluh."</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Zaznan je bil glasen zvok\n\nGlasnost v slušalkah je višja od priporočene, kar vam lahko poškoduje sluh."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Želite uporabljati bližnjico za dostopnost?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Ko je bližnjica vklopljena, pritisnite gumba za glasnost in ju pridržite tri sekunde, če želite zagnati funkcijo dostopnosti."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Želite vklopiti bližnjico za funkcije za dostopnost?"</string>
@@ -2154,7 +2152,7 @@
     <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Skupinski pogovor"</string>
     <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Osebno"</string>
-    <string name="resolver_work_tab" msgid="2690019516263167035">"Služba"</string>
+    <string name="resolver_work_tab" msgid="2690019516263167035">"Delo"</string>
     <string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Pogled osebnega profila"</string>
     <string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Pogled delovnega profila"</string>
     <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Blokiral skrbnik za IT"</string>
@@ -2166,14 +2164,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Znova aktiviraj"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nobena delovna aplikacija ni na voljo"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nobena osebna aplikacija"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Želite odpreti delovno aplikacijo <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Želite odpreti v osebni aplikaciji <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Želite odpreti v delovni aplikaciji <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Želite poklicati iz delovne aplikacije?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Želite preklopiti na delovno aplikacijo?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Organizacija vam omogoča klicanje samo iz delovnih aplikacij."</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Organizacija vam omogoča pošiljanje sporočil samo iz delovnih aplikacij."</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Uporabi osebni brskalnik"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Uporabi delovni brskalnik"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Pokliči"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Preklopi"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Koda PIN za odklepanje omrežja kartice SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Koda PIN za odklepanje podnabora omrežja kartice SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Koda PIN za odklepanje kartice SIM za podjetje"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 63cdf13..6cbbd28 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" - "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Hiq"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Të ngrihet volumi mbi nivelin e rekomanduar?\n\nDëgjimi me volum të lartë për periudha të gjata mund të dëmtojë dëgjimin."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Paralajmërim:\nE ke kaluar sasinë e sinjaleve të larta zanore që mund të dëgjojë në mënyrë të sigurt një person gjatë një jave nëpërmjet kufjeve.\n\nNëse e kalon këtë kufi, kjo gjë do ta dëmtojë përgjithmonë dëgjimin tënd."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Paralajmërim:\nE ke kaluar 5 herë sasinë e sinjaleve të larta zanore që mund të dëgjojë në mënyrë të sigurt një person gjatë një jave nëpërmjet kufjeve.\n\nVolumi është ulur për të mbrojtur dëgjimin tënd."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Niveli me të cilin po dëgjon median mund të shkaktojë dëmtim të dëgjimit nëse vazhdon për periudha të gjata kohore.\n\nNëse vazhdon të luash me këtë nivel për periudha të gjata kohore, kjo gjë mund të dëmtojë dëgjimin tënd."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Paralajmërim:\nPo dëgjon aktualisht përmbajtje me zë të lartë që po luhet në një nivel jo të sigurt.\n\nNëse vazhdon të dëgjosh me një nivel kaq të lartë, kjo gjë do të dëmtojë përgjithmonë dëgjimin tënd."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"A do të vazhdosh të dëgjosh me një volum të lartë?\n\nVolumi i kufjeve ka qenë i lartë për një kohë më të gjatë nga sa rekomandohet, çka mund të të dëmtojë dëgjimin"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"U zbulua tingull i lartë\n\nVolumi i kufjeve ka qenë më i lartë nga sa rekomandohet, çka mund të të dëmtojë dëgjimin"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Të përdoret shkurtorja e qasshmërisë?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kur shkurtorja është e aktivizuar, shtypja e të dy butonave për 3 sekonda do të nisë një funksion qasshmërie."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Të aktivizohet shkurtorja për veçoritë e qasshmërisë?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Hiq nga pauza"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nuk ka aplikacione pune"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nuk ka aplikacione personale"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Të hapet <xliff:g id="APP">%s</xliff:g> i punës?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Të hapet te <xliff:g id="APP">%s</xliff:g> personal?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Të hapet te <xliff:g id="APP">%s</xliff:g> i punës?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Të telefonohet nga aplikacioni i punës?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Të kalohet tek aplikacioni i punës?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Organizata jote të lejon që të telefonosh vetëm nga aplikacionet e punës"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Organizata jote të lejon që të dërgosh mesazhe vetëm nga aplikacionet e punës"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Përdor shfletuesin personal"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Përdor shfletuesin e punës"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Telefono"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Ndërro"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Kodi PIN i shkyçjes së rrjetit të kartës SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Kodi PIN i shkyçjes së nënrenditjes së rrjetit të kartës SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Kodi PIN i shkyçjes së kartës SIM të korporatës"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index f363d7f..9753ee0 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1683,10 +1683,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Уклони"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Желите да појачате звук изнад препорученог нивоа?\n\nСлушање гласне музике дуже време може да вам оштети слух."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Упозорење,\nпремашили сте број гласних звучних сигнала које је безбедно слушати преко слушалица током недељу дана.\n\nПрекорачењем тог ограничења трајно ћете оштетити слух."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Упозорење,\nПет пута сте премашили број гласних звучних сигнала које је безбедно слушати преко слушалица током недељу дана.\n\nЈачина звука треба да се смањи да бисте заштитили слух."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Ниво на ком слушате медијски садржај може да доведе до оштећења слуха ако то траје током дужег периода.\n\nАко наставите да слушате тако гласно током дужег периода, може да дође до оштећења слуха."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Упозорење,\nтренутно слушате гласан садржај на небезбедном нивоу.\n\nАко наставите да слушате тако гласно, трајно ћете оштетити слух."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Желите да наставите да слушате гласну музику?\n\nЈачина звука у слушалицама је била висока дуже него што се препоручује, што може да оштети слух"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Препознат је гласан звук\n\nЈачина звука у слушалицама је била већа него што се препоручује, што може да оштети слух"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Желите ли да користите пречицу за приступачност?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Када је пречица укључена, притисните оба дугмета за јачину звука да бисте покренули функцију приступачности."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Желите да укључите пречицу за функције приступачности?"</string>
@@ -2165,14 +2163,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Поново активирај"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Нема пословних апликација"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Нема личних апликација"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Желите да отворите пословну апликацију <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Желите да отворите у личној апликацији <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Желите да отворите у пословној апликацији <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Желите да позовете из пословне апликације?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Желите да пребаците на пословну апликацију?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Ваша организација дозвољава позивање само из пословних апликација"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Ваша организација дозвољава слање порука само из пословних апликација"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Користи лични прегледач"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Користи пословни прегледач"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Позови"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Пребаци"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN за откључавање SIM мреже"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN за откључавање подскупа SIM мреже"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN за откључавање пословне SIM картице"</string>
@@ -2334,7 +2335,7 @@
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Уређај <xliff:g id="DEVICE_NAME">%s</xliff:g> је конфигурисан"</string>
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Распоред тастатуре је подешен на <xliff:g id="LAYOUT_1">%s</xliff:g>. Додирните да бисте то променили."</string>
     <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Распоред тастатуре је подешен на <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Додирните да бисте то променили."</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Распоред тастатуре је подешен на <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Додирните да бисте то променили."</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Распоред тастатуре је <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Додирните да бисте то променили."</string>
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Распоред тастатуре је подешен на <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Додирните да бисте променили."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физичке тастатуре су конфигурисане"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Додирните да бисте видели тастатуре"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index eca78dc..6da10ec 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Ta bort"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Vill du höja volymen över den rekommenderade nivån?\n\nAtt lyssna med stark volym långa stunder åt gången kan skada hörseln."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Varning!\nDu har överskridit den säkra mängden höga ljudsignaler man kan lyssna på i hörlurar under en vecka.\n\nDin hörsel skadas permanent om du överskrider gränsen."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Varning!\nDu har lyssnat på över fem gånger den säkra mängden höga ljudsignaler man kan lyssna på i hörlurar under en vecka.\n\nVolymen har sänkts för att skydda din hörsel."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Du lyssnar på media med en volym som kan leda till hörselskador om den bibehålls under lång tid.\n\nDin hörsel kan skadas om du fortsätter att spela upp på den här nivån under lång tid."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Varning!\nDu lyssnar just nu på innehåll med farligt hög volym.\n\nDin hörsel skadas permanent om du fortsätter att lyssna med den här volymen."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Vill du fortsätta lyssna på hög volym?\n\nVolymen i hörlurarna har varit hög längre än vad som rekommenderas, vilket kan skada hörseln"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Högt ljud har upptäckts\n\nVolymen i hörlurarna har varit högre än vad som rekommenderas, vilket kan skada hörseln"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Vill du använda Aktivera tillgänglighet snabbt?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"När kortkommandot har aktiverats startar du en tillgänglighetsfunktion genom att trycka ned båda volymknapparna i tre sekunder."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Vill du aktivera genvägen till tillgänglighetsfunktioner?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Återuppta"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Inga jobbappar"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Inga privata appar"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Vill du öppna <xliff:g id="APP">%s</xliff:g> med din jobbprofil?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Vill du öppna med din privata profil i <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Vill du öppna med din jobbprofil i <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Vill du ringa med jobbappen?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Vill du byta till jobbappen?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Organisationen tillåter endast att du ringer samtal med jobbappar"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Organisationen tillåter endast att du skickar meddelanden med jobbappar"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Använd privat webbläsare"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Använd jobbwebbläsare"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Ring"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Byt"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Pinkod för upplåsning av nätverk för SIM-kort"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Pinkod för upplåsning av delnätverk för SIM-kort"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Pinkod för upplåsning av företag för SIM-kort"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 64a9fd5..2fb0d17 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Ondoa"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ungependa kupandisha sauti zaidi ya kiwango kinachopendekezwa?\n\nKusikiliza kwa sauti ya juu kwa muda mrefu kunaweza kuharibu uwezo wako wa kusikia."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Tahadhari,\nUmezidi kiasi cha mawimbi ya sauti ya juu ambayo mtu anaweza kusikiliza kwa usalama ndani ya wiki kupitia vipokea sauti vya kichwani.\n\nKuvuka kikomo hiki kutaharibu usikivu wako kabisa."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Tahadhari,\nUmezidisha mara 5 ya kiwango cha mawimbi ya sauti ya juu ambayo mtu anaweza kusikiliza kwa usalama ndani ya wiki kupitia vipokea sauti vya kichwani.\n\nSauti imepunguzwa ili kulinda usikivu wako."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Kiwango cha sauti ambacho unasikilizia maudhui kinaweza kusababisha athari kwenye usikivu unapoendelea kusikiliza kwa muda mrefu.\n\nKuendelea kucheza maudhui katika kiwango hiki cha sauti kwa muda mrefu kunaweza kuharibu usikivu wako."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Tahadhari,\nKwa sasa unasikiliza maudhui ya sauti yanayochezwa kwa kiwango cha sauti kisicho salama.\n\nKuendelea kusikiliza maudhui katika kiwango hiki cha sauti ya juu kutaharibu usikivu wako kabisa."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Ungependa kuendelea kusikiliza kwa sauti ya kiwango cha juu?\n\nKiwango cha sauti ya vipokea sauti vya kichwani kimekuwa juu kwa muda mrefu kuliko inavyopendekezwa, hali ambayo inaweza kuharibu uwezo wako wa kusikia"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Sauti ya kiwango cha juu imetambuliwa\n\nKiwango cha sauti ya vipokea sauti vya kichwani kimekuwa juu zaidi kuliko inavyopendekezwa, hali ambayo inaweza kuharibu uwezo wako wa kusikia"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Ungependa kutumia njia ya mkato ya ufikivu?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Unapowasha kipengele cha njia ya mkato, hatua ya kubonyeza vitufe vyote viwili vya sauti kwa sekunde tatu itafungua kipengele cha ufikivu."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Ungependa kuwasha njia ya mkato ya vipengele vya ufikivu?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Acha kusitisha"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Hakuna programu za kazini"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Hakuna programu za binafsi"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Ungependa kufungua <xliff:g id="APP">%s</xliff:g> ukitumia wasifu wa kazini?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Ungependa kufungua <xliff:g id="APP">%s</xliff:g> ukitumia wasifu wa binafsi?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Ungependa kufungua <xliff:g id="APP">%s</xliff:g> ukitumia wasifu wa kazini?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Ungependa kupiga simu ukitumia programu ya kazini?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Ungependa kubadilisha ili utumie programu ya kazini?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Shirika lako linakuruhusu upige simu ukitumia programu za kazini pekee"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Shirika lako linakuruhusu utume ujumbe ukitumia programu za kazini pekee"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Tumia kivinjari cha binafsi"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Tumia kivinjari cha kazini"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Piga simu"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Badilisha"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN ya kufungua mtandao wa SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN ya kufungua SIM iliyofungwa na mtoa huduma za simu"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN ya kufungua SIM ya shirika"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 6db4100..1467033 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1630,7 +1630,7 @@
     <string name="media_route_chooser_title" msgid="6646594924991269208">"சாதனத்துடன் இணைக்கவும்"</string>
     <string name="media_route_chooser_title_for_remote_display" msgid="3105906508794326446">"ஸ்கிரீனை சாதனத்தில் திரையிடு"</string>
     <string name="media_route_chooser_searching" msgid="6119673534251329535">"சாதனங்களைத் தேடுகிறது..."</string>
-    <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"அமைப்பு"</string>
+    <string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"அமைப்புகள்"</string>
     <string name="media_route_controller_disconnect" msgid="7362617572732576959">"துண்டி"</string>
     <string name="media_route_status_scanning" msgid="8045156315309594482">"ஸ்கேன் செய்கிறது..."</string>
     <string name="media_route_status_connecting" msgid="5845597961412010540">"இணைக்கிறது..."</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"அகற்று"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"பரிந்துரைத்த அளவை விட ஒலியை அதிகரிக்கவா?\n\nநீண்ட நேரத்திற்கு அதிகளவில் ஒலி கேட்பது கேட்கும் திறனைப் பாதிக்கலாம்."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"எச்சரிக்கை,\nஒரு வாரத்திற்கு ஹெட்ஃபோன்களில் ஒருவர் பாதுகாப்பாகக் கேட்கக்கூடிய சத்தமான ஒலியளவு வரம்பைக் கடந்துவிட்டீர்கள்.\n\nதொடர்ந்து இந்த வரம்பை மீறினால் உங்கள் கேட்கும் திறன் நிரந்தரப் பாதிப்புக்குள்ளாகும்."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"எச்சரிக்கை,\nஒரு வாரத்திற்கு ஹெட்ஃபோன்களில் ஒருவர் பாதுகாப்பாகக் கேட்கக்கூடிய சத்தமான ஒலியளவு வரம்பை 5 முறை கடந்துவிட்டீர்கள்.\n\nஉங்கள் கேட்கும் திறனின் நலன் கருதி ஒலியளவு குறைக்கப்பட்டுள்ளது."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"நீங்கள் தற்போது கேட்கும் ஒலியளவிலேயே தொடர்ந்து மீடியாவைக் கேட்டு வந்தால் உங்கள் கேட்கும் திறன் பாதிப்புக்குள்ளாகும்.\n\nஇந்த அளவிலேயே தொடர்ந்து கேட்டால் உங்கள் கேட்கும் திறன் பாதிப்படையலாம்."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"எச்சரிக்கை,\nபாதுகாப்பற்ற ஒலியளவில் மீடியாவைத் தற்போது சத்தமாகக் கேட்கிறீர்கள்.\n\nதொடர்ந்து இந்தளவில் கேட்டால் உங்கள் கேட்கும் திறன் நிரந்தரப் பாதிப்புக்குள்ளாகும்."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"அதிக ஒலியளவில் தொடர்ந்து கேட்க வேண்டுமா?\n\nபரிந்துரைக்கப்பட்டதைவிட அதிக நேரமாக அதிகளவில் ஹெட்ஃபோன் ஒலியளவு உள்ளது, இது உங்கள் கேட்கும் திறனைப் பாதிக்கலாம்"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"அதிகச் சத்தம் கண்டறியப்பட்டது\n\nஹெட்ஃபோன் ஒலியளவு பரிந்துரைக்கப்பட்டதைவிட அதிகளவில் உள்ளது, இது கேட்கும் திறனைப் பாதிக்கலாம்"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"அணுகல்தன்மை ஷார்ட்கட்டைப் பயன்படுத்தவா?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"ஷார்ட்கட் இயக்கத்தில் இருக்கும்போது ஒலியளவு பட்டன்கள் இரண்டையும் 3 வினாடிகளுக்கு அழுத்தினால் அணுகல்தன்மை அம்சம் இயக்கப்படும்."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"அணுகல்தன்மை அம்சங்களுக்கான ஷார்ட்கட்டை ஆன் செய்யவா?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"மீண்டும் இயக்கு"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"பணி ஆப்ஸ் எதுவுமில்லை"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"தனிப்பட்ட ஆப்ஸ் எதுவுமில்லை"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"பணிக் கணக்கில் உள்நுழைந்துள்ள <xliff:g id="APP">%s</xliff:g> ஆப்ஸைத் திறக்கவா?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"தனிப்பட்ட கணக்கில் <xliff:g id="APP">%s</xliff:g> ஆப்ஸைத் திறக்கவா?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"பணிக் கணக்கில் <xliff:g id="APP">%s</xliff:g> ஆப்ஸைத் திறக்கவா?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"பணி ஆப்ஸிலிருந்து அழைக்கவா?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"பணி ஆப்ஸுக்கு மாற வேண்டுமா?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"உங்கள் நிறுவனம் பணி ஆப்ஸில் இருந்து மட்டுமே அழைக்க உங்களை அனுமதிக்கிறது"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"உங்கள் நிறுவனம் பணி ஆப்ஸில் இருந்து மட்டுமே மெசேஜ்களை அனுப்ப உங்களை அனுமதிக்கிறது"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"தனிப்பட்ட உலாவியைப் பயன்படுத்து"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"பணி உலாவியைப் பயன்படுத்து"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"அழை"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"மாற்று"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"சிம் நெட்வொர்க் அன்லாக் பின்"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"சிம் நெட்வொர்க் சப்செட் அன்லாக் பின்"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"கார்ப்பரேட் அன்லாக் பின்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index b8a57dc..f0e9201 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1396,7 +1396,7 @@
     <string name="hardware" msgid="1800597768237606953">"వర్చువల్ కీబోర్డ్‌ను చూపు"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>‌ను కాన్ఫిగర్ చేయండి"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ఫిజికల్ కీబోర్డ్‌లను కాన్ఫిగ‌ర్ చేయండి"</string>
-    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"భాష మరియు లేఅవుట్‌ను ఎంచుకోవడానికి నొక్కండి"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"భాషను, లేఅవుట్‌ను ఎంచుకోవడానికి ట్యాప్ చేయండి"</string>
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"ఇతర యాప్‌ల ఎగువన ప్రదర్శన"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"తీసివేయండి"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"వాల్యూమ్‌ను సిఫార్సు చేయబడిన స్థాయి కంటే ఎక్కువగా పెంచాలా?\n\nసుదీర్ఘ వ్యవధుల పాటు అధిక వాల్యూమ్‌లో వినడం వలన మీ వినికిడి శక్తి దెబ్బ తినవచ్చు."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"హెచ్చరిక,\nమీరు ఒక వారంలో హెడ్‌ఫోన్స్ ద్వారా సురక్షితంగా వినగలిగే భారీ సౌండ్ సిగ్నల్స్ పరిమాణాన్ని మించిపోయారు.\n\nఈ పరిమితిని మించిపోవడం వల్ల మీ వినికిడి శాశ్వతంగా దెబ్బతింటుంది."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"హెచ్చరిక,\nమీరు ఒక వారంలో హెడ్‌ఫోన్స్ ద్వారా సురక్షితంగా వినగలిగే భారీ సౌండ్ సిగ్నల్స్ కంటే 5 రెట్లు మించిపోయారు.\n\nమీ వినికిడిని రక్షించడానికి వాల్యూమ్ తగ్గించబడింది."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"మీరు ప్రస్తుతం వింటున్న వాల్యూమ్‌లో మీడియాను వినడం కొనసాగిస్తే, మీ వినికిడి దెబ్బతినవచ్చు.\n\nఎక్కువ సమయం పాటు ఈ స్థాయిలో మీడియాను ప్లే చేయడం వల్ల మీ వినికిడి దెబ్బతినవచ్చు."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"హెచ్చరిక,\nమీరు ప్రస్తుతం బిగ్గరగా వినిపించే కంటెంట్‌ను అసురక్షిత వాల్యూమ్ స్థాయిలో వింటున్నారు.\n\nఇంత బిగ్గరగా వినడం కొనసాగించడం వల్ల మీ వినికిడి శాశ్వతంగా దెబ్బతింటుంది."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"అధిక వాల్యూమ్‌లో వినడం కొనసాగించాలనుకుంటున్నారా?\n\nహెడ్‌ఫోన్ వాల్యూమ్, సిఫార్సు చేసిన సమయం కంటే ఎక్కువసేపు అధిక వాల్యూమ్‌లో ఉంది, ఇది మీ వినికిడిని దెబ్బతీయవచ్చు"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"అధిక సౌండ్‌ను గుర్తించడం జరిగింది\n\nహెడ్‌ఫోన్ వాల్యూమ్, సిఫార్సు చేసిన సమయం కంటే ఎక్కువసేపు అధిక వాల్యూమ్‌లో ఉంది, ఇది మీ వినికిడిని దెబ్బతీయవచ్చు"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"యాక్సెస్ సామర్థ్యం షార్ట్‌కట్‌ను ఉపయోగించాలా?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"షార్ట్‌కట్ ఆన్ చేసి ఉన్నప్పుడు, రెండు వాల్యూమ్ బటన్‌లను 3 సెకన్ల పాటు నొక్కి ఉంచితే యాక్సెస్ సౌలభ్య ఫీచర్ ప్రారంభం అవుతుంది."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"యాక్సెస్ సౌలభ్య ఫీచర్‌ల కోసం షార్ట్‌కట్‌ను ఆన్ చేయాలా?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"అన్‌పాజ్ చేయండి"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"వర్క్ యాప్‌లు లేవు"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"వ్యక్తిగత యాప్‌లు లేవు"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"వర్క్ <xliff:g id="APP">%s</xliff:g> యాప్‌ను తెరవాలా?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"వ్యక్తిగత <xliff:g id="APP">%s</xliff:g> యాప్‌లో తెరవాలా?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"వర్క్ <xliff:g id="APP">%s</xliff:g> యాప్‌లో తెరవాలా?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"వర్క్ యాప్ నుండి కాల్ చేయాలా?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"వర్క్ యాప్‌నకు మారాలా?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"మీ సంస్థ, వర్క్ యాప్‌ల నుండి మాత్రమే కాల్స్ చేయడానికి మిమ్మల్ని అనుమతిస్తుంది"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"మీ సంస్థ, వర్క్ యాప్‌ల నుండి మాత్రమే మెసేజ్‌లను పంపడానికి మిమ్మల్ని అనుమతిస్తుంది"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"వ్యక్తిగత బ్రౌజర్‌ను ఉపయోగించండి"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"వర్క్ బ్రౌజర్‌ను ఉపయోగించండి"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"కాల్ చేయండి"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"మారండి"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM నెట్‌వర్క్ అన్‌లాక్ పిన్‌"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM నెట్‌వర్క్ సబ్‌సెట్ అన్‌లాక్ పిన్"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM కార్పొరేట్ అన్‌లాక్ పిన్"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 00c8d01..bfe85bf 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"ลบ"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"นี่เป็นการเพิ่มระดับเสียงเกินระดับที่แนะนำ\n\nการฟังเสียงดังเป็นเวลานานอาจทำให้การได้ยินของคุณบกพร่องได้"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"คำเตือน\nคุณฟังสัญญาณเสียงดังเกินระดับที่ปลอดภัยเมื่อฟังผ่านหูฟังสำหรับ 1 สัปดาห์แล้ว\n\nการฟังที่เกินขีดจำกัดนี้จะทำให้การได้ยินของคุณบกพร่องอย่างถาวรได้"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"คำเตือน\nคุณฟังสัญญาณเสียงดังเกินระดับที่ปลอดภัยเมื่อฟังผ่านหูฟังสำหรับ 1 สัปดาห์ไป 5 เท่าแล้ว\n\nระบบได้ลดระดับเสียงลงเพื่อปกป้องการได้ยินของคุณ"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"ระดับที่คุณฟังสื่ออาจทำให้การได้ยินบกพร่องเมื่อฟังไปในระยะยาว\n\nการเล่นสื่อในระดับนี้ต่อไปเป็นเวลานานๆ อาจทำให้การได้ยินของคุณบกพร่องได้"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"คำเตือน\nขณะนี้คุณฟังเนื้อหาเสียงดังซึ่งเล่นในระดับที่ไม่ปลอดภัย\n\nการฟังเสียงดังระดับนี้ต่อไปจะทำให้การได้ยินของคุณบกพร่องอย่างถาวรได้"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"ต้องการฟังเสียงดังต่อไปไหม\n\nเสียงของหูฟังอยู่ในระดับที่ดังเป็นระยะเวลานานกว่าที่แนะนำ ซึ่งอาจทำให้เกิดความเสียหายต่อระบบการได้ยินของคุณ"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"การตรวจจับเสียงดัง\n\nเสียงของหูฟังอยู่ในระดับที่ดังกว่าที่แนะนำ ซึ่งอาจทำให้เกิดความเสียหายต่อระบบการได้ยินของคุณ"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ใช้ทางลัดการช่วยเหลือพิเศษไหม"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"เมื่อทางลัดเปิดอยู่ การกดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มนาน 3 วินาทีจะเริ่มฟีเจอร์การช่วยเหลือพิเศษ"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"เปิดใช้ทางลัดสำหรับฟีเจอร์การช่วยเหลือพิเศษใช่ไหม"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"ยกเลิกการหยุดชั่วคราว"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"ไม่มีแอปงาน"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"ไม่มีแอปส่วนตัว"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"เปิด <xliff:g id="APP">%s</xliff:g> งานไหม"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"เปิดใน <xliff:g id="APP">%s</xliff:g> ส่วนตัวไหม"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"เปิดใน <xliff:g id="APP">%s</xliff:g> งานไหม"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"โทรออกจากแอปงานไหม"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"เปลี่ยนไปใช้แอปงานไหม"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"องค์กรอนุญาตให้คุณโทรออกได้จากแอปงานเท่านั้น"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"องค์กรอนุญาตให้คุณส่งข้อความได้จากแอปงานเท่านั้น"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ใช้เบราว์เซอร์ส่วนตัว"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ใช้เบราว์เซอร์งาน"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"โทร"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"เปลี่ยน"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN ปลดล็อกเครือข่ายที่ใช้กับ SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN ปลดล็อกเครือข่ายย่อยที่ใช้กับ SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN ปลดล็อกองค์กรที่ใช้กับ SIM"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 7e4bbe4..0a1b9a0 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Alisin"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Lakasan ang volume nang lagpas sa inirerekomendang antas?\n\nMaaaring mapinsala ng pakikinig sa malakas na volume sa loob ng mahahabang panahon ang iyong pandinig."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Babala,\nLumagpas ka na sa dami ng malalakas na signal ng tunog na ligtas na mapapakinggan ng isang tao sa isang linggo gamit ang headphones.\n\nPermanenteng makakapinsala sa iyong pandinig ang paglagpas sa limitasyong ito."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Babala,\nLumagpas ka na sa 5 beses ng dami ng malalakas na signal ng tunog na ligtas na mapapakinggan ng isang tao sa isang linggo gamit ang headphones.\n\nHininaan ang volume para protektahan ang iyong pandinig."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Puwedeng magresulta sa pinsala sa pandinig ang level ng pakikinig mo sa media kapag nagtagal pa ito nang mahabang panahon.\n\nPosibleng makapinsala sa iyong pandinig ang patuloy na pagpe-play sa level na ito sa loob ng mahabang panahon."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Babala,\nKasalukuyan kang nakikinig sa malakas na content na pine-play sa hindi ligtas na level.\n\nPosibleng permanenteng makapinsala sa iyong pandinig ang patuloy na pakikinig nang ganito kalakas."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Magpatuloy sa pakikinig nang may malakas na volume?\n\nNaging malakas ang volume nang mas matagal na sa inirerekomenda, at posible nitong mapinsala ang pandinig mo"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Naka-detect ng malakas na tunog\n\nMas malakas ang volume kaysa sa inirerekomenda, at posible nitong mapinsala ang pandinig mo"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Gagamitin ang Shortcut sa Accessibility?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kapag naka-on ang shortcut, magsisimula ang isang feature ng pagiging naa-access kapag pinindot ang parehong button ng volume."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"I-on ang shortcut para sa mga feature ng pagiging naa-access?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"I-unpause"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Walang app para sa trabaho"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Walang personal na app"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Buksan ang <xliff:g id="APP">%s</xliff:g> na para sa trabaho?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Buksan sa personal na <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Buksan sa <xliff:g id="APP">%s</xliff:g> na para sa trabaho?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Tumawag mula sa app para sa trabaho?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Lumipat sa app para sa trabaho?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Pinapayagan ka lang ng iyong organisasyon na tumawag mula sa mga app para sa trabaho"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Pinapayagan ka lang ng iyong organisasyon na magpadala ng mga mensahe mula sa mga app para sa trabaho"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Gamitin ang personal na browser"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Gamitin ang browser sa trabaho"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Tumawag"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Lumipat"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN para sa pag-unlock ng network ng SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN para sa pag-unlock ng subset ng network ng SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN para sa pangkumpanyang pag-unlock ng SIM"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index cc2d3f8..f522856 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Kaldır"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Ses seviyesi önerilen düzeyin üzerine yükseltilsin mi?\n\nUzun süre yüksek ses seviyesinde dinlemek işitme duyunuza zarar verebilir."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Uyarı,\nBir kullanıcının, bir hafta içinde kulaklıkla güvenle dinleyebileceği yüksek ses sinyali seviyesini aştınız.\n\nBu sınırın üzerine çıkılması, işitme duyunuzda kalıcı hasarlara neden olur."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Uyarı,\nBir kullanıcının, bir hafta içinde kulaklıkla güvenle dinleyebileceği yüksek ses sinyali seviyesini 5 kat aştınız.\n\nİşitme duyunuzu korumak için ses seviyesi düşürüldü."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Medyaları dinlediğiniz seviye, uzun süre bu şekilde devam ederse işitme duyusuna zarar verebilir.\n\nUzun süre bu seviyede dinlemeye devam ederseniz işitme duyunuz zarar görebilir."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Uyarı,\nŞu anda güvenli olmayan bir seviyede çalan içeriği yüksek sesle dinliyorsunuz.\n\nBu kadar yüksek sesle dinlemeye devam ederseniz işitme duyunuzda kalıcı hasar meydana gelebilir."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Yüksek sesle dinlemeye devam edilsin mi?\n\nKulaklığın sesi önerilenden daha uzun süre yüksek düzeyde kaldı ve bu durum işitme kaybına neden olabilir"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Yüksek ses algılandı\n\nKulaklığın ses düzeyi önerilenden yüksek. Bu durum işitme kaybına neden olabilir"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Erişilebilirlik Kısayolu Kullanılsın mı?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Kısayol açıkken ses düğmelerinin ikisini birden 3 saniyeliğine basılı tutmanız bir erişilebilirlik özelliğini başlatır."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Erişilebilirlik özellikleri için kısayol açılsın mı?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Devam ettir"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"İş uygulaması yok"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Kişisel uygulama yok"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"İş uygulaması (<xliff:g id="APP">%s</xliff:g>) açılsın mı?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Kişisel uygulamada (<xliff:g id="APP">%s</xliff:g>) açılsın mı?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"İş uygulamasında (<xliff:g id="APP">%s</xliff:g>) açılsın mı?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"İş uygulamasından telefon edilsin mi?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"İş uygulamasına geçilsin mi?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Kuruluşunuz yalnızca iş uygulamalarından telefon etmenize izin veriyor"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Kuruluşunuz yalnızca iş uygulamalarından mesaj göndermenize izin veriyor"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Kişisel tarayıcıyı kullan"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"İş tarayıcısını kullan"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Telefon et"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Geçiş yap"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM ağ kilidi açma PIN kodu"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM ağ alt kümesi kilidini açma PIN kodu"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM kurumsal kilidi açma PIN kodu"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index dd28672..b5d4bb7 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1684,10 +1684,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Вилучити"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Збільшити гучність понад рекомендований рівень?\n\nЯкщо слухати надто гучну музику тривалий час, можна пошкодити слух."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Попередження.\nВи перевищили кількість гучних звукових сигналів, які протягом тижня можна безпечно слухати через навушники.\n\nПеревищення цього ліміту може назавжди пошкодити ваш слух."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Попередження.\nВи вп’ятеро перевищили кількість гучних звукових сигналів, які протягом тижня можна безпечно слухати через навушники.\n\nГучність знижено, щоб уберегти ваш слух."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Якщо довго слухати медіаконтент на цьому рівні гучності, можливі пошкодження слуху.\n\nЯкщо ви не знизите гучність, через деякий час ваш слух може погіршитись."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Попередження.\nНаразі ви слухаєте контент із небезпечним рівнем гучності.\n\nЯкщо надалі слухати так гучно, це може назавжди пошкодити ваш слух."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Слухати далі на високій гучності?\n\nАудіо в навушниках відтворювалося з високою гучністю довше, ніж рекомендується. Через це ваш слух може погіршитись."</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Виявлено гучний звук\n\nРівень гучності навушників вищий за рекомендований. Через це ваш слух може погіршитись."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Використовувати швидке ввімкнення?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Якщо цей засіб увімкнено, ви можете активувати спеціальні можливості, утримуючи обидві кнопки гучності протягом трьох секунд."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Увімкнути засіб спеціальних можливостей?"</string>
@@ -2166,14 +2164,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Увімкнути знову"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Немає робочих додатків"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Немає особистих додатків"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Відкрити робочий додаток <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Відкрити в особистому додатку <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Відкрити в робочому додатку <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Телефонувати з робочого додатка?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Перейти в робочий додаток?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Ваша організація дозволяє телефонувати лише з робочих додатків"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Ваша організація дозволяє надсилати повідомлення лише з робочих додатків"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Використати особистий веб-переглядач"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Використати робочий веб-переглядач"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Телефонувати"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Перейти"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN-код розблокування мережі SIM-карти"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"PIN-код розблокування підгрупи мереж SIM-карти"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"PIN-код розблокування корпоративної SIM-карти"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index f08404b..ea41d9d 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"ہٹائیں"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"والیوم کو تجویز کردہ سطح سے زیادہ کریں؟\n\nزیادہ وقت تک اونچی آواز میں سننے سے آپ کی سماعت کو نقصان پہنچ سکتا ہے۔"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"وارننگ،\nآپ بلند آواز کے سگنلز کی حد سے تجاوز کر چکے ہیں جنہیں ایک ہفتے میں کوئی ہیڈ فونز پر محفوظ طریقے سے سن سکتا ہے۔\n\nاس حد سے تجاوز کرنے سے آپ کی سماعت کو مستقل طور پر نقصان پہنچے گا۔"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"وارننگ،\nآپ بلند آواز کے سگنلز کی حد سے 5 گنا تجاوز کر چکے ہیں جنہیں ایک ہفتے میں کوئی ہیڈ فونز پر محفوظ طریقے سے سن سکتا ہے۔\n\nآپ کی سماعت کی حفاظت کے لیے والیوم کو کم کر دیا گیا ہے۔"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"جس سطح پر آپ میڈیا کو سن رہے ہیں اس پر طویل عرصے تک برقرار رہنے کے نتیجے میں سماعت کو نقصان پہنچ سکتا ہے۔\n\nاس سطح پر طویل عرصے تک چلانے سے آپ کی سماعت کو نقصان پہنچ سکتا ہے۔"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"وارننگ،\nآپ فی الحال غیر محفوظ سطح پر چلائے گئے مواد کو بلند آواز میں سن رہے ہیں۔\n\nاس بلند آواز کو مسلسل سننے سے آپ کی سماعت کو مستقل طور پر نقصان پہنچے گا۔"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"اونچی آواز میں سننا جاری رکھیں؟\n\nہیڈ فون کا والیوم تجویز کردہ وقت سے زیادہ دیر تک بلند رہا ہے، جو آپ کی سماعت کو نقصان پہنچا سکتا ہے"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"تیز آواز کا پتہ چلا\n\nہیڈ فون کا والیوم تجویز کردہ سے زیادہ بلند رہا ہے، جو آپ کی سماعت کو نقصان پہنچا سکتا ہے"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"ایکسیسبیلٹی شارٹ کٹ استعمال کریں؟"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"شارٹ کٹ آن ہونے پر، 3 سیکنڈ تک دونوں والیوم بٹنز کو دبانے سے ایک ایکسیسبیلٹی خصوصیت شروع ہو جائے گی۔"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"ایکسیسبیلٹی خصوصیات کے لیے شارٹ کٹ آن کریں؟"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"غیر موقوف کریں"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"کوئی ورک ایپ نہیں"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"کوئی ذاتی ایپ نہیں"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"دفتری <xliff:g id="APP">%s</xliff:g> کھولیں؟"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"ذاتی <xliff:g id="APP">%s</xliff:g> میں کھولیں؟"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"دفتری <xliff:g id="APP">%s</xliff:g> میں کھولیں؟"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"ورک ایپ سے کال کریں؟"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"ورک ایپ پر سوئچ کریں؟"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"آپ کی تنظیم آپ کو صرف ورک ایپس سے کالز کرنے کی اجازت دیتی ہے"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"آپ کی تنظیم آپ کو صرف ورک ایپس سے پیغامات بھیجنے کی اجازت دیتی ہے"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"ذاتی براؤزر استعمال کریں"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"ورک براؤزر استعمال کریں"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"کال کریں"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"سوئچ کریں"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"‏SIM نیٹ ورک غیر مقفل کرنے کا PIN"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"‏SIM نیٹ ورک سب سیٹ کو غیر مقفل کرنے کا PIN"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"‏SIM کارپوریٹ کو غیر مقفل کرنے کا PIN"</string>
@@ -2330,7 +2331,7 @@
     <string name="concurrent_display_notification_power_save_content" msgid="2198116070583851493">"‏Dual Screen دستیاب نہیں ہے کیونکہ بیٹری سیور آن ہے۔ آپ اسے ترتیبات میں آف کر سکتے ہیں۔"</string>
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"ترتیبات پر جائیں"</string>
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"آف کریں"</string>
-    <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> میں کنفیگر کیا گیا"</string>
+    <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"‫<xliff:g id="DEVICE_NAME">%s</xliff:g> کنفیگر کیا گیا"</string>
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"کی بورڈ لے آؤٹ <xliff:g id="LAYOUT_1">%s</xliff:g> پر سیٹ ہے۔ تبدیل کرنے کیلئے تھپتھپائیں۔"</string>
     <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"کی بورڈ لے آؤٹ <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g> پر سیٹ ہے۔ تبدیل کرنے کیلئے تھپتھپائیں۔"</string>
     <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"کی بورڈ لے آؤٹ <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g> پر سیٹ ہے۔ تبدیل کرنے کیلئے تھپتھپائیں۔"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 291b856..154402e 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Olib tashlash"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Tovush balandligi tavsiya etilgan darajadan ham yuqori qilinsinmi?\n\nUzoq vaqt davomida baland ovozda tinglash eshitish qobiliyatingizga salbiy ta’sir ko‘rsatishi mumkin."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Ogohlantirish\nQuloqlik orqali bir hafta ichida xavfsiz tinglash mumkin boʻlgan baland ovozli signallar miqdoridan oshib ketdingiz.\n\nBu chegaradan oshib ketish eshitish qobiliyatingizni butunlay buzadi."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Ogohlantirish\nQuloqlik orqali bir hafta ichida xavfsiz tinglash mumkin boʻlgan baland ovozli signallar miqdoridan 5 baravar oshib ketdingiz.\n\nEshitish qobiliyatingizni himoya qilish uchun tovush balandligi pasaytirildi."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Uzoq vaqt davomida bunday balandlikda media fayllarni tinglash eshitish qobiliyatingiz buzilishiga olib kelishi mumkin.\n\nUzoq vaqt davomida bu darajada ijroni davom ettirish eshitishingizga zarar yetkazishi mumkin."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Ogohlantirish\nHozir xavfli darajada baland ovozli kontentni tinglayapsiz.\n\nBu baland tovushda tinglashda davom etsangiz, eshitish qobiliyatingiz butunlay buziladi."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Baland tovushda tinglayapsizmi?\n\nQuloqlik tavsiya etilganidan uzoqroq vaqt baland tovushda ishlamoqda va eshitishga zarar yetkazishi mumkin"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Baland tovush aniqlandi\n\nQuloqlik tavsiya etilganidan uzoqroq vaqt baland tovushda ishlamoqda va eshitishga zarar yetkazishi mumkin"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Tezkor ishga tushirishdan foydalanilsinmi?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Qulayliklar funksiyasidan foydalanish uchun u yoniqligida ikkala tovush tugmasini 3 soniya bosib turing."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Qulayliklar uchun tezkor tugma yoqilsinmi?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Davom ettirish"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Ishga oid ilovalar topilmadi"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Shaxsiy ilovalar topilmadi"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Ishga oid <xliff:g id="APP">%s</xliff:g> ochilsinmi?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"<xliff:g id="APP">%s</xliff:g> shaxsiy profilda ochilsinmi?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"<xliff:g id="APP">%s</xliff:g> ish profilida ochilsinmi?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Ishga oid ilova orqali chaqirilsinmi?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Ishga oid ilovaga almashtirilsinmi?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Tashkilotingiz faqat ishga oid ilovalar orqali chaqiruvga ruxsat beradi"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Tashkilotingiz faqat ishga oid ilovalar orqali xabarlar yuborishga ruxsat beradi"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Shaxsiy brauzerdan foydalanish"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Ishga oid brauzerdan foydalanish"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Chaqiruv"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Almashish"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM kartaning tarmoqdagi qulfini ochish uchun PIN kod"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM karta tarmoq qismini qulfdan chiqarish uchun PIN kod"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Korporativ SIM kartalar qulfini ochish uchun PIN kod"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 696e874..628f02a 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -702,7 +702,7 @@
     <skip />
     <string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Không thể tạo mẫu khuôn mặt của bạn. Hãy thử lại."</string>
     <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Đã phát hiện thấy kính râm. Toàn bộ khuôn mặt của bạn phải được trông thấy rõ ràng."</string>
-    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Phát hiện khuôn mặt bị che. Bạn phải cho thấy toàn bộ khuôn mặt."</string>
+    <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Khuôn mặt bị che. Bạn phải cho thấy toàn bộ khuôn mặt."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="5085202213036026288">"Không thể xác minh khuôn mặt. Phần cứng không có sẵn."</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Xóa"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Bạn tăng âm lượng lên quá mức khuyên dùng?\n\nViệc nghe ở mức âm lượng cao trong thời gian dài có thể gây tổn thương thính giác của bạn."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Cảnh báo,\nBạn đã vượt quá số lần nghe tín hiệu âm thanh lớn mà một người có thể nghe an toàn qua tai nghe trong một tuần.\n\nNếu vượt quá giới hạn này, thính lực của bạn sẽ bị tổn thương vĩnh viễn."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Cảnh báo,\nBạn đã vượt quá 5 lần nghe tín hiệu âm thanh lớn mà một người có thể nghe an toàn qua tai nghe trong một tuần.\n\nÂm lượng đã được giảm xuống để bảo vệ thính lực của bạn."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Mức âm lượng bạn đang nghe nội dung nghe nhìn có thể gây tổn thương thính lực khi duy trì trong thời gian dài.\n\nNếu bạn tiếp tục phát ở mức âm lượng này trong thời gian dài, thì thính lực của bạn có thể bị tổn thương."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Cảnh báo,\nBạn đang nghe nội dung ở mức âm lượng không an toàn.\n\nNếu bạn tiếp tục nghe ở mức âm lượng lớn như vậy, thì thính lực của bạn sẽ bị tổn thương vĩnh viễn."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Tiếp tục nghe ở mức âm lượng cao?\n\nBạn đã dùng tai nghe ở mức âm lượng cao lâu hơn khoảng thời gian khuyến nghị, điều này có thể gây tổn hại đến thính giác của bạn"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Đã phát hiện âm thanh lớn\n\nBạn đã dùng tai nghe ở mức âm lượng cao hơn khuyến nghị, điều này có thể gây tổn hại đến thính giác của bạn"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Sử dụng phím tắt Hỗ trợ tiếp cận?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Khi phím tắt này đang bật, thao tác nhấn cả hai nút âm lượng trong 3 giây sẽ mở tính năng hỗ trợ tiếp cận."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Bật phím tắt cho các tính năng hỗ trợ tiếp cận?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Bỏ tạm dừng"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Không có ứng dụng công việc"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Không có ứng dụng cá nhân"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Mở <xliff:g id="APP">%s</xliff:g> công việc?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Mở trong <xliff:g id="APP">%s</xliff:g> cá nhân?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Mở trong <xliff:g id="APP">%s</xliff:g> công việc?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Gọi bằng ứng dụng công việc?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Chuyển sang ứng dụng công việc?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Tổ chức của bạn chỉ cho phép bạn gọi điện bằng ứng dụng công việc"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Tổ chức của bạn chỉ cho phép bạn gửi tin nhắn bằng ứng dụng công việc"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Dùng trình duyệt cá nhân"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Dùng trình duyệt công việc"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Gọi"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Chuyển"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Mã PIN mở khóa mạng SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Mã PIN mở khóa tập con của mạng SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Mã PIN mở khóa SIM corporate"</string>
@@ -2333,7 +2334,7 @@
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Đã định cấu hình <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Đã thiết lập bố cục bàn phím thành <xliff:g id="LAYOUT_1">%s</xliff:g>. Hãy nhấn để thay đổi."</string>
     <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Đã thiết lập bố cục bàn phím thành <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Hãy nhấn để thay đổi."</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Đã thiết lập bố cục bàn phím thành <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Hãy nhấn để thay đổi."</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Đã đặt bố cục là <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Nhấn để đổi."</string>
     <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Đã thiết lập bố cục bàn phím thành <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Hãy nhấn để thay đổi."</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Đã định cấu hình bàn phím vật lý"</string>
     <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Nhấn để xem bàn phím"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 4518899..3272694 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -686,7 +686,7 @@
     <string name="face_acquired_too_right" msgid="6245286514593540859">"请将手机向左移动"</string>
     <string name="face_acquired_too_left" msgid="9201762240918405486">"请将手机向右移动"</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"请直视您的设备。"</string>
-    <string name="face_acquired_not_detected" msgid="1057966913397548150">"看不到人脸,请将手机举到与眼睛齐平的位置。"</string>
+    <string name="face_acquired_not_detected" msgid="1057966913397548150">"看不到您的脸,请将手机举到与眼睛齐平的位置。"</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"摄像头过于晃动。请将手机拿稳。"</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"请重新注册您的面孔。"</string>
     <string name="face_acquired_too_different" msgid="2520389515612972889">"无法识别人脸,请重试。"</string>
@@ -724,7 +724,7 @@
     <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"使用人脸解锁或屏幕锁定凭据验证身份,才能继续操作"</string>
   <string-array name="face_error_vendor">
   </string-array>
-    <string name="face_error_vendor_unknown" msgid="7387005932083302070">"出了点问题。请重试。"</string>
+    <string name="face_error_vendor_unknown" msgid="7387005932083302070">"出了点问题,请重试。"</string>
     <string name="face_icon_content_description" msgid="465030547475916280">"面孔图标"</string>
     <string name="permlab_readSyncSettings" msgid="6250532864893156277">"读取同步设置"</string>
     <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"允许该应用读取某个帐号的同步设置。例如,此权限可确定“联系人”应用是否与某个帐号同步。"</string>
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"删除"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要将音量调高到建议的音量以上吗?\n\n长时间保持高音量可能会损伤听力。"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"警告!\n您在一周内使用头戴式耳机收听的高分贝音频量已超出安全范围限值。\n\n继续超限收听会导致您的听力永久受损。"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"警告!\n您在一周内使用头戴式耳机收听的高分贝音频量已超出安全范围限值的 5 倍。\n\n为保护您的听力,系统已调低音量。"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"长时间以当前音量收听媒体可能会导致听力受损。\n\n如果您继续以这样的音量长时间播放,则可能会损害您的听力。"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"警告!\n当前的内容播放音量已超出安全范围限值。\n\n继续以这样的音量收听会导致您的听力永久受损。"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"继续以较高的音量聆听?\n\n耳机音量保持较高的时间超过了建议时长,可能会损害您的听力"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"检测到较高音量\n\n耳机音量水平超过了建议值,可能会损害您的听力"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"要使用无障碍快捷方式吗?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"启用这项快捷方式后,同时按下两个音量按钮 3 秒钟即可启动无障碍功能。"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"要开启无障碍功能快捷方式吗?"</string>
@@ -1939,7 +1937,7 @@
     <string name="user_creation_adding" msgid="7305185499667958364">"允许<xliff:g id="APP">%1$s</xliff:g>使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 创建新用户吗?"</string>
     <string name="supervised_user_creation_label" msgid="6884904353827427515">"添加受监管用户"</string>
     <string name="language_selection_title" msgid="52674936078683285">"添加语言"</string>
-    <string name="country_selection_title" msgid="5221495687299014379">"区域偏好设置"</string>
+    <string name="country_selection_title" msgid="5221495687299014379">"地区偏好设置"</string>
     <string name="search_language_hint" msgid="7004225294308793583">"输入语言名称"</string>
     <string name="language_picker_section_suggested" msgid="6556199184638990447">"建议语言"</string>
     <string name="language_picker_regions_section_suggested" msgid="6080131515268225316">"推荐地区"</string>
@@ -1986,7 +1984,7 @@
     <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"点按即可查看文件"</string>
     <string name="pin_target" msgid="8036028973110156895">"置顶"</string>
     <string name="pin_specific_target" msgid="7824671240625957415">"将<xliff:g id="LABEL">%1$s</xliff:g>置顶"</string>
-    <string name="unpin_target" msgid="3963318576590204447">"取消固定"</string>
+    <string name="unpin_target" msgid="3963318576590204447">"取消置顶"</string>
     <string name="unpin_specific_target" msgid="3859828252160908146">"取消置顶<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="app_info" msgid="6113278084877079851">"应用信息"</string>
     <string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"取消暂停"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"没有支持该内容的工作应用"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"没有支持该内容的个人应用"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"打开工作 <xliff:g id="APP">%s</xliff:g>?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"在个人 <xliff:g id="APP">%s</xliff:g> 中打开?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"在工作 <xliff:g id="APP">%s</xliff:g> 中打开?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"通过工作应用拨打电话?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"切换到工作应用?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"贵组织仅允许您通过工作应用拨打电话"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"贵组织仅允许您通过工作应用发送消息"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"使用个人浏览器"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"使用工作浏览器"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"拨打电话"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"切换"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM 网络解锁 PIN 码"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM 网络子集解锁 PIN 码"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM 企业解锁 PIN 码"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 09e17c1..997f963 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"移除"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要調高音量 (比建議的音量更大聲) 嗎?\n\n長時間聆聽高分貝音量可能會導致你的聽力受損。"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"警告:\n你於一週內使用耳機聆聽的高分貝音訊量已超過安全範圍\n\n繼續此行為將導致聽力永久受損。"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"警告:\n你於一週內使用耳機聆聽的高分貝音訊量已超過安全範圍 5 倍。\n\n為保護你的聽力,系統已調低音量。"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"目前的媒體播放音量在長時間聆聽下可能會損害聽力。\n\n如繼續以此音量播放內容,長時間可能導致聽力受損。"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"警告:\n目前的內容播放音量已超過安全聆聽範圍。\n\n繼續聆聽此音量將導致聽力永久受損。"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"要繼續以高音量聆聽嗎?\n\n你以高音量使用耳機的時間已超過建議範圍,可能會導致聽力受損"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"系統偵測到巨響\n\n耳機音量已有一段時間超過建議水平,可能會導致聽力受損"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"要使用無障礙功能快速鍵嗎?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"啟用快速鍵後,同時按住音量按鈕 3 秒便可啟用無障礙功能。"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"要開啟無障礙功能捷徑嗎?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"取消暫停"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"沒有適用的工作應用程式"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"沒有適用的個人應用程式"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"要開啟「<xliff:g id="APP">%s</xliff:g>」嗎?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"要在個人「<xliff:g id="APP">%s</xliff:g>」中開啟嗎?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"要在工作「<xliff:g id="APP">%s</xliff:g>」中開啟嗎?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"要透過工作應用程式打電話嗎?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"要切換至工作應用程式嗎?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"你的機構只允許你透過工作應用程式打電話"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"你的機構只允許你透過工作應用程式傳送訊息"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"使用個人瀏覽器"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"使用工作瀏覽器"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"打電話"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"切換"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM 網絡解鎖 PIN"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM 網絡子集解鎖 PIN"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM 公司解鎖 PIN"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 19cfe5d..ea04067 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"移除"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"要調高音量,比建議的音量更大聲嗎?\n\n長時間聆聽高分貝音量可能會使你的聽力受損。"</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"警告:\n你在一週內使用耳罩式耳機聆聽的高分貝音訊量已超過安全範圍。\n\n繼續這個行為將導致聽力永久受損。"</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"警告:\n你在一週內使用耳罩式耳機聆聽的高分貝音訊量已超過安全範圍 5 倍。\n\n為了保護你的聽力,系統已調低音量。"</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"目前的媒體播放音量在長時間聆聽下可能會損害聽力。\n\n如果繼續以這個音量播放內容,長時間可能導致聽力受損。"</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"警告:\n目前的內容播放音量已超過安全聆聽範圍。\n\n繼續聆聽這個音量將導致聽力永久受損。"</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"要繼續以高音量聆聽嗎?\n\n耳罩式耳機以高音量播放已超過建議時間,可能會傷害聽力"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"偵測到過大音量\n\n耳罩式耳機的音量比建議音量高,可能會傷害聽力"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"要使用無障礙捷徑嗎?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"啟用捷徑功能,只要同時按下兩個音量鍵 3 秒,就能啟動無障礙功能。"</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"要開啟無障礙功能快速鍵嗎?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"解除暫停"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"沒有適用的工作應用程式"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"沒有適用的個人應用程式"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"要開啟工作用「<xliff:g id="APP">%s</xliff:g>」嗎?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"要在個人用「<xliff:g id="APP">%s</xliff:g>」中開啟嗎?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"要在工作用「<xliff:g id="APP">%s</xliff:g>」中開啟嗎?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"要透過工作應用程式撥號嗎?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"要切換到工作應用程式嗎?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"貴機構僅允許透過工作應用程式撥打電話"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"貴機構僅允許透過工作應用程式傳送訊息"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"使用個人瀏覽器"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"使用工作瀏覽器"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"撥號"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"切換"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"SIM 卡網路解鎖 PIN 碼"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"SIM 卡網路子集解鎖 PIN 碼"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"SIM 卡企業解鎖 PIN 碼"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index c2bc59c..b2ef74a 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1682,10 +1682,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Susa"</string>
     <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Khuphukisa ivolumu ngaphezu kweleveli enconyiwe?\n\nUkulalela ngevolumu ephezulu izikhathi ezide kungahle kulimaze ukuzwa kwakho."</string>
-    <string name="csd_dose_reached_warning" product="default" msgid="1032473160590983236">"Isexwayiso,\nUsuweqe inani lamasignali omsindo omkhulu umuntu angakwazi ukuwalalela ngokuphepha ngeviki ngama-headphone.\n\nUkweqa lo mkhawulo kuzolimaza ngokuphelele ukuzwa kwakho."</string>
-    <string name="csd_dose_repeat_warning" product="default" msgid="6765471037071089401">"Isexwayiso,\nUsuweqe iinani lamasignali womsindo ophezulu izikhathi ezi-5 umuntu angakwazi ukuwalalela ngokuphephile ngeviki ngama-headphone.\n\nIvolumu yehlisiwe ukuze kuvikelwe ukuzwa kwakho."</string>
-    <string name="csd_entering_RS2_warning" product="default" msgid="3699509945325496807">"Izinga olalela ngalo imidiya lingaholela ekulimaleni kokuzwa uma kugcinwa isikhathi eside.\n\nUkuqhubeka nokudlala kuleli zinga isikhathi eside kungalimaza ukuzwa kwakho."</string>
-    <string name="csd_momentary_exposure_warning" product="default" msgid="7861896191081176454">"Isexwayiso,\nOkwamanje ulalele okuqukethwe okuphezulu okudlalwayo ezingeni elingaphephile.\n\nUkuqhubeka ulalele lo msindo omkhulu kuzolimaza ukuzwa kwakho unomphela."</string>
+    <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"Qhubeka ulalele ngevolumu ephezulu?\n\nIvolumu ye-headphones ibiphezulu isikhathi eside kunokunconywa, okungalimaza ukuzwa kwakho"</string>
+    <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Kutholwe umsindo omkhulu\n\nIvolumu yama-headphone ibe phezulu kunokunconyiwe, okungalimaza ukuzwa kwakho"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Sebenzisa isinqamuleli sokufinyelela?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Uma isinqamuleli sivuliwe, ukucindezela zombili izinkinobho zevolumu amasekhondi angu-3 kuzoqalisa isici sokufinyelela."</string>
     <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Vula isinqamuleli sezici zokufinyeleleka?"</string>
@@ -2164,14 +2162,17 @@
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Qhubekisa"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Awekho ama-app womsebenzi"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Awekho ama-app womuntu siqu"</string>
-    <!-- no translation found for miniresolver_open_work (6286176185835401931) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_personal (807427577794490375) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (941341494673509916) -->
-    <skip />
+    <string name="miniresolver_open_work" msgid="6286176185835401931">"Vula i-<xliff:g id="APP">%s</xliff:g> yomsebenzi?"</string>
+    <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Vula ku-<xliff:g id="APP">%s</xliff:g> yomuntu siqu?"</string>
+    <string name="miniresolver_open_in_work" msgid="941341494673509916">"Vula ku-<xliff:g id="APP">%s</xliff:g> yomsebenzi?"</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Fona nge-app yasemsebenzini?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Shintshela ku-app yasemsebenzini?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Inhlangano yakho ikuvumela kuphela ukuthi wenze amakholi ngama-app asemsebenzini"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Inhlangano yakho ikuvumela ukuthumela imilayezo kusuka kuma-app omsebenzi kuphela"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Sebenzisa isiphequluli somuntu siqu"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Sebenzisa isiphequluli somsebenzi"</string>
+    <string name="miniresolver_call" msgid="6386870060423480765">"Fona"</string>
+    <string name="miniresolver_switch" msgid="8011924662117617451">"Shintsha"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"Iphinikhodi yokuvula inethiwekhi ye-SIM"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY" msgid="7164399703751688214">"Iphinikhodi yokuvula yesethi engaphansi yenethiwekhi ye-SIM"</string>
     <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY" msgid="4447629474818217364">"Iphinikhodi yokuvula yenkampani ye-SIM"</string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 1bbe8ee..b7d088b 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1618,7 +1618,8 @@
             {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and above, starting a foreground
             service with this type will require permission
             {@link android.Manifest.permission#FOREGROUND_SERVICE_PHONE_CALL} and
-            {@link android.Manifest.permission#MANAGE_OWN_CALLS}.
+            {@link android.Manifest.permission#MANAGE_OWN_CALLS} or holding the default
+            {@link android.app.role.RoleManager#ROLE_DIALER dialer role}.
         -->
         <flag name="phoneCall" value="0x04" />
         <!-- GPS, map, navigation location update.
@@ -1796,12 +1797,6 @@
     -->
     <attr name="attributionTags" format="string" />
 
-    <!-- Default value <code>true</code> allows an installer to enable update
-         ownership enforcement for this package via {@link
-         android.content.pm.PackageInstaller.SessionParams#setRequestUpdateOwnership}
-         during initial installation. This overrides the installer's use of {@link
-         android.content.pm.PackageInstaller.SessionParams#setRequestUpdateOwnership}.
-    -->
     <attr name="allowUpdateOwnership" format="boolean" />
 
     <!-- The <code>manifest</code> tag is the root of an
@@ -1841,7 +1836,6 @@
         <attr name="isSplitRequired" />
         <attr name="requiredSplitTypes" />
         <attr name="splitTypes" />
-        <attr name="allowUpdateOwnership" />
     </declare-styleable>
 
     <!-- The <code>application</code> tag describes application-level components
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index a99ba15..5b0dd30 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -72,9 +72,9 @@
     <item name="secondary_content_alpha_material_dark" format="float" type="dimen">.7</item>
     <item name="secondary_content_alpha_material_light" format="float" type="dimen">0.60</item>
 
-    <item name="highlight_alpha_material_light" format="float" type="dimen">0.5</item>
-    <item name="highlight_alpha_material_dark" format="float" type="dimen">0.5</item>
-    <item name="highlight_alpha_material_colored" format="float" type="dimen">0.10</item>
+    <item name="highlight_alpha_material_light" format="float" type="dimen">0.20</item>
+    <item name="highlight_alpha_material_dark" format="float" type="dimen">0.20</item>
+    <item name="highlight_alpha_material_colored" format="float" type="dimen">0.20</item>
 
     <!-- Primary & accent colors -->
     <eat-comment />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 23e3139..00f8db0 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3718,6 +3718,10 @@
          magnification settings and adjust the default magnification capability.  -->
     <bool name="config_magnification_area">true</bool>
 
+    <!-- The default value for always on magnification feature flag if the remote feature
+         flag does not exist -->
+    <bool name="config_magnification_always_on_enabled">true</bool>
+
     <!-- If true, the display will be shifted around in ambient mode. -->
     <bool name="config_enableBurnInProtection">false</bool>
 
@@ -5177,10 +5181,11 @@
         <item>0,0,1.0,0,1</item>
         <item>1,1,1.0,0,1</item>
         <item>1,1,1.0,.4,1</item>
+        <item>1,1,1.0,.15,15</item>
     </string-array>
 
     <!-- The integer index of the selected option in config_udfps_touch_detection_options -->
-    <integer name="config_selected_udfps_touch_detection">2</integer>
+    <integer name="config_selected_udfps_touch_detection">3</integer>
 
     <!-- An array of arrays of side fingerprint sensor properties relative to each display.
          Note: this value is temporary and is expected to be queried directly
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index bc0af12..24da59a 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -874,6 +874,7 @@
     <dimen name="autofill_elevation">32dp</dimen>
     <dimen name="autofill_save_inner_padding">16dp</dimen>
     <dimen name="autofill_save_icon_size">32dp</dimen>
+    <dimen name="autofill_save_icon_max_height">56dp</dimen>
     <dimen name="autofill_save_title_start_padding">8dp</dimen>
     <dimen name="autofill_save_scroll_view_top_margin">16dp</dimen>
     <dimen name="autofill_save_button_bar_padding">16dp</dimen>
@@ -882,19 +883,18 @@
     <!-- Max height of the the autofill save custom subtitle as a fraction of the screen width/height -->
     <dimen name="autofill_save_custom_subtitle_max_height">20%</dimen>
 
-    <!-- Max (absolute) dimensions (both width and height) of autofill service icon on autofill save affordance.
-      NOTE: the actual displayed size might is actually smaller than this and is hardcoded in the
-      autofill_save.xml layout; this dimension is just used to avoid a crash in the UI (if the icon provided
-      by the autofill service metadata is bigger than these dimentionsit will not be displayed).
-    -->
-    <dimen name="autofill_save_icon_max_size">300dp</dimen>
-
     <!-- Maximum number of datasets that are visible in the UX picker without scrolling -->
     <integer name="autofill_max_visible_datasets">3</integer>
 
-    <!-- Size of an icon in the Autolfill fill dialog -->
+    <!-- Size of an icon in the Autofill fill dialog -->
     <dimen name="autofill_dialog_icon_size">32dp</dimen>
 
+    <!-- The max height of an icon in the Autofill fill dialog. -->
+    <dimen name="autofill_dialog_icon_max_height">56dp</dimen>
+
+    <!-- The max width of the Autofill fill dialog. -->
+    <dimen name="autofill_dialog_max_width">640dp</dimen>
+
     <!-- Size of a slice shortcut view -->
     <dimen name="slice_shortcut_size">56dp</dimen>
     <!-- Size of action icons in a slice -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index faaa2e8..fb3acbe 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -861,10 +861,10 @@
     <!-- "Switch" is a verb; it means to change user profile by tapping another user profile name. -->
     <string name="managed_profile_label">Switch to work profile</string>
 
-    <!-- "Switch" is a verb; it means to change user profile by tapping another user profile name. -->
+    <!-- "Switch" is a verb; it means to change user profile by switching to an app in the personal profile. -->
     <string name="user_owner_app_label">Switch to personal <xliff:g id="app_name" example="Gmail">%1$s</xliff:g></string>
 
-    <!-- "Switch" is a verb; it means to change user profile by tapping another user profile name. -->
+    <!-- "Switch" is a verb; it means to change user profile by switching to an app in the work profile. -->
     <string name="managed_profile_app_label">Switch to work <xliff:g id="app_name" example="Gmail">%1$s</xliff:g></string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
@@ -5392,11 +5392,11 @@
     <string name="app_streaming_blocked_message" product="tablet">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g> at this time. Try on your tablet instead.</string>
     <!-- Message shown when an app is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
     <string name="app_streaming_blocked_message" product="default">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g> at this time. Try on your phone instead.</string>
-    <!-- Message shown when the fingerprint permission is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
+    <!-- Message shown when an app being streamed to another device requests authentication such as via the biometrics API, and the user needs to complete the on their device. [CHAR LIMIT=NONE] -->
     <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv">This app is requesting additional security. Try on your Android TV device instead.</string>
-    <!-- Message shown when the fingerprint permission is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
+    <!-- Message shown when an app being streamed to another device requests authentication such as via the biometrics API, and the user needs to complete the on their device. [CHAR LIMIT=NONE] -->
     <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet">This app is requesting additional security. Try on your tablet instead.</string>
-    <!-- Message shown when the fingerprint permission is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
+    <!-- Message shown when an app being streamed to another device requests authentication such as via the biometrics API, and the user needs to complete the on their device. [CHAR LIMIT=NONE] -->
     <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default">This app is requesting additional security. Try on your phone instead.</string>
     <!-- Message shown when the settings is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
     <string name="app_streaming_blocked_message_for_settings_dialog" product="tv">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g>. Try on your Android TV device instead.</string>
@@ -5410,6 +5410,9 @@
     <!-- Title for button to see application detail in app store which it came from - it may allow user to update to newer version. [CHAR LIMIT=50] -->
     <string name="deprecated_target_sdk_app_store">Check for update</string>
 
+    <!-- Message displayed in dialog when app is 32 bit on a 64 bit system. [CHAR LIMIT=NONE] -->
+    <string name="deprecated_abi_message">This app isn\'t compatible with the latest version of Android. Check for an update or contact the app\'s developer.</string>
+
     <!-- Notification title shown when new SMS/MMS is received while the device is locked [CHAR LIMIT=NONE] -->
     <string name="new_sms_notification_title">You have new messages</string>
     <!-- Notification content shown when new SMS/MMS is received while the device is locked [CHAR LIMIT=NONE] -->
@@ -5907,10 +5910,24 @@
     <string name="miniresolver_open_in_personal">Open in personal <xliff:g id="app" example="YouTube">%s</xliff:g>?</string>
     <!-- Dialog title. User must choose between opening content in a cross-profile app or same-profile browser. [CHAR LIMIT=NONE] -->
     <string name="miniresolver_open_in_work">Open in work <xliff:g id="app" example="YouTube">%s</xliff:g>?</string>
+    <!-- Dialog title. User must place the phone call in the other profile, or cancel. [CHAR LIMIT=NONE] -->
+    <string name="miniresolver_call_in_work">Call from work app?</string>
+    <!-- Dialog title. User much choose between opening content in a cross-profile app or cancelling. [CHAR LIMIT=NONE] -->
+    <string name="miniresolver_switch_to_work">Switch to work app?</string>
+    <!-- Dialog text.  Shown when the user is unable to make a phone call 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_call_information">Your organization only allows you to make calls from work apps</string>
+    <!-- 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>
     <!-- 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] -->
     <string name="miniresolver_use_work_browser">Use work browser</string>
+    <!-- Button option. Action to place a phone call. [CHAR LIMIT=NONE] -->
+    <string name="miniresolver_call">Call</string>
+    <!-- Button option. Action to open an app in the work profile. [CHAR LIMIT=NONE] -->
+    <string name="miniresolver_switch">Switch</string>
 
     <!-- Icc depersonalization related strings -->
     <!-- Label text for PIN entry widget on SIM Network Depersonalization panel [CHAR LIMIT=none] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e08f085..6ab671a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1577,6 +1577,14 @@
   <java-symbol type="string" name="miniresolver_open_work" />
   <java-symbol type="string" name="miniresolver_use_personal_browser" />
   <java-symbol type="string" name="miniresolver_use_work_browser" />
+  <java-symbol type="string" name="miniresolver_call_in_work" />
+  <java-symbol type="string" name="miniresolver_switch_to_work" />
+  <java-symbol type="string" name="miniresolver_call" />
+  <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="id" name="miniresolver_info_section" />
+  <java-symbol type="id" name="miniresolver_info_section_text" />
   <java-symbol type="id" name="button_open" />
   <java-symbol type="id" name="use_same_profile_browser" />
 
@@ -3148,6 +3156,8 @@
   <java-symbol type="string" name="deprecated_target_sdk_message" />
   <java-symbol type="string" name="deprecated_target_sdk_app_store" />
 
+  <java-symbol type="string" name="deprecated_abi_message" />
+
   <!-- New SMS notification while phone is locked. -->
   <java-symbol type="string" name="new_sms_notification_title" />
   <java-symbol type="string" name="new_sms_notification_content" />
@@ -3652,8 +3662,8 @@
   <java-symbol type="dimen" name="autofill_dataset_picker_max_width"/>
   <java-symbol type="dimen" name="autofill_dataset_picker_max_height"/>
   <java-symbol type="dimen" name="autofill_save_custom_subtitle_max_height"/>
-  <java-symbol type="dimen" name="autofill_save_icon_max_size"/>
   <java-symbol type="integer" name="autofill_max_visible_datasets" />
+  <java-symbol type="dimen" name="autofill_dialog_max_width" />
 
   <java-symbol type="style" name="Theme.DeviceDefault.Autofill" />
   <java-symbol type="style" name="Theme.DeviceDefault.Light.Autofill" />
@@ -4528,6 +4538,7 @@
   <java-symbol type="string" name="dismiss_action" />
 
   <java-symbol type="bool" name="config_magnification_area" />
+  <java-symbol type="bool" name="config_magnification_always_on_enabled" />
 
   <java-symbol type="bool" name="config_trackerAppNeedsPermissions"/>
   <!-- FullScreenMagnification thumbnail -->
@@ -5009,7 +5020,7 @@
 
   <java-symbol type="bool" name="config_batteryStatsResetOnUnplugHighBatteryLevel" />
   <java-symbol type="bool" name="config_batteryStatsResetOnUnplugAfterSignificantCharge" />
-  
+
   <java-symbol name="materialColorOnSecondaryFixedVariant" type="attr"/>
   <java-symbol name="materialColorOnTertiaryFixedVariant" type="attr"/>
   <java-symbol name="materialColorSurfaceContainerLowest" type="attr"/>
@@ -5120,4 +5131,5 @@
   <java-symbol type="style" name="ThemeOverlay.DeviceDefault.Dark.ActionBar.Accent" />
 
   <java-symbol type="drawable" name="focus_event_pressed_key_background" />
+  <java-symbol type="string" name="lockscreen_too_many_failed_attempts_countdown" />
 </resources>
diff --git a/core/res/res/xml/irq_device_map.xml b/core/res/res/xml/irq_device_map.xml
index 8b3667e..2f894b9 100644
--- a/core/res/res/xml/irq_device_map.xml
+++ b/core/res/res/xml/irq_device_map.xml
@@ -28,6 +28,8 @@
             - Wifi: Use this to denote network traffic that uses the wifi transport.
             - Sound_trigger: Use this to denote sound phrase detection, like the ones supported by
         SoundTriggerManager.
+            - Sensor: Use this to denote wakeups due to sensor events.
+            - Cellular_data: Use this to denote network traffic on the cellular transport.
 
         The overlay should use tags <device> and <subsystem> to describe this mapping in the
         following way:
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 4cccf8e..c1deba3 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -78,6 +78,7 @@
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
     <uses-permission android:name="android.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG" />
     <uses-permission android:name="android.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG" />
+    <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index c5b00c9..eba7f58 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -33,6 +33,8 @@
 import static android.app.Notification.EXTRA_PEOPLE_LIST;
 import static android.app.Notification.EXTRA_PICTURE;
 import static android.app.Notification.EXTRA_PICTURE_ICON;
+import static android.app.Notification.EXTRA_SUMMARY_TEXT;
+import static android.app.Notification.EXTRA_TITLE;
 import static android.app.Notification.MessagingStyle.Message.KEY_DATA_URI;
 import static android.app.Notification.MessagingStyle.Message.KEY_SENDER_PERSON;
 import static android.app.Notification.MessagingStyle.Message.KEY_TEXT;
@@ -76,6 +78,7 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.SystemProperties;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.SpannableStringBuilder;
@@ -111,6 +114,9 @@
     @Before
     public void setUp() {
         mContext = InstrumentationRegistry.getContext();
+        // TODO(b/169435530): remove this flag set once resolved.
+        SystemProperties.set("persist.sysui.notification.builder_extras_override",
+                Boolean.toString(false));
     }
 
     @Test
@@ -1481,6 +1487,107 @@
         Assert.assertEquals(actionWithFreeformRemoteInput, remoteInputActionPair.second);
     }
 
+    // Ensures that extras in a Notification Builder can be updated.
+    @Test
+    public void testExtras_cachedExtrasOverwrittenByUserProvided() {
+        // Sets the flag to new state.
+        // TODO(b/169435530): remove this set value once resolved.
+        SystemProperties.set("persist.sysui.notification.builder_extras_override",
+                Boolean.toString(true));
+        Bundle extras = new Bundle();
+        extras.putCharSequence(EXTRA_TITLE, "test title");
+        extras.putCharSequence(EXTRA_SUMMARY_TEXT, "summary text");
+
+        Notification.Builder builder = new Notification.Builder(mContext, "test id")
+                .addExtras(extras);
+
+        Notification notification = builder.build();
+        assertThat(notification.extras.getCharSequence(EXTRA_TITLE).toString()).isEqualTo(
+                "test title");
+        assertThat(notification.extras.getCharSequence(EXTRA_SUMMARY_TEXT).toString()).isEqualTo(
+                "summary text");
+
+        extras.putCharSequence(EXTRA_TITLE, "new title");
+        builder.addExtras(extras);
+        notification = builder.build();
+        assertThat(notification.extras.getCharSequence(EXTRA_TITLE).toString()).isEqualTo(
+                "new title");
+        assertThat(notification.extras.getCharSequence(EXTRA_SUMMARY_TEXT).toString()).isEqualTo(
+                "summary text");
+    }
+
+    // Ensures that extras in a Notification Builder can be updated by an extender.
+    @Test
+    public void testExtras_cachedExtrasOverwrittenByExtender() {
+        // Sets the flag to new state.
+        // TODO(b/169435530): remove this set value once resolved.
+        SystemProperties.set("persist.sysui.notification.builder_extras_override",
+                Boolean.toString(true));
+        Notification.CarExtender extender = new Notification.CarExtender().setColor(1234);
+
+        Notification notification = new Notification.Builder(mContext, "test id")
+                .extend(extender).build();
+
+        extender.setColor(5678);
+
+        Notification.Builder.recoverBuilder(mContext, notification).extend(extender).build();
+
+        Notification.CarExtender recoveredExtender = new Notification.CarExtender(notification);
+        assertThat(recoveredExtender.getColor()).isEqualTo(5678);
+    }
+
+    // Validates pre-flag flip behavior, that extras in a Notification Builder cannot be updated.
+    // TODO(b/169435530): remove this test once resolved.
+    @Test
+    public void testExtras_cachedExtrasOverwrittenByUserProvidedOld() {
+        // Sets the flag to old state.
+        SystemProperties.set("persist.sysui.notification.builder_extras_override",
+                Boolean.toString(false));
+
+        Bundle extras = new Bundle();
+        extras.putCharSequence(EXTRA_TITLE, "test title");
+        extras.putCharSequence(EXTRA_SUMMARY_TEXT, "summary text");
+
+        Notification.Builder builder = new Notification.Builder(mContext, "test id")
+                .addExtras(extras);
+
+        Notification notification = builder.build();
+        assertThat(notification.extras.getCharSequence(EXTRA_TITLE).toString()).isEqualTo(
+                "test title");
+        assertThat(notification.extras.getCharSequence(EXTRA_SUMMARY_TEXT).toString()).isEqualTo(
+                "summary text");
+
+        extras.putCharSequence(EXTRA_TITLE, "new title");
+        builder.addExtras(extras);
+        notification = builder.build();
+        assertThat(notification.extras.getCharSequence(EXTRA_TITLE).toString()).isEqualTo(
+                "test title");
+        assertThat(notification.extras.getCharSequence(EXTRA_SUMMARY_TEXT).toString()).isEqualTo(
+                "summary text");
+    }
+
+    // Validates pre-flag flip behavior, that extras in a Notification Builder cannot be updated
+    // by an extender.
+    // TODO(b/169435530): remove this test once resolved.
+    @Test
+    public void testExtras_cachedExtrasOverwrittenByExtenderOld() {
+        // Sets the flag to old state.
+        SystemProperties.set("persist.sysui.notification.builder_extras_override",
+                Boolean.toString(false));
+
+        Notification.CarExtender extender = new Notification.CarExtender().setColor(1234);
+
+        Notification notification = new Notification.Builder(mContext, "test id")
+                .extend(extender).build();
+
+        extender.setColor(5678);
+
+        Notification.Builder.recoverBuilder(mContext, notification).extend(extender).build();
+
+        Notification.CarExtender recoveredExtender = new Notification.CarExtender(notification);
+        assertThat(recoveredExtender.getColor()).isEqualTo(1234);
+    }
+
     private void assertValid(Notification.Colors c) {
         // Assert that all colors are populated
         assertThat(c.getBackgroundColor()).isNotEqualTo(Notification.COLOR_INVALID);
diff --git a/core/tests/coretests/src/android/app/backup/BackupManagerMonitorWrapperTest.java b/core/tests/coretests/src/android/app/backup/BackupManagerMonitorWrapperTest.java
new file mode 100644
index 0000000..1f5e0cf
--- /dev/null
+++ b/core/tests/coretests/src/android/app/backup/BackupManagerMonitorWrapperTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.backup;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.os.Bundle;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class BackupManagerMonitorWrapperTest {
+    @Mock
+    private BackupManagerMonitor mMonitor;
+    private BackupManagerMonitorWrapper mMonitorWrapper;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testOnEvent_propagatesToMonitor() throws Exception {
+        mMonitorWrapper = new BackupManagerMonitorWrapper(mMonitor);
+        Bundle eventBundle = new Bundle();
+
+        mMonitorWrapper.onEvent(eventBundle);
+
+        verify(mMonitor, times(/* wantedNumberOfInvocations */ 1)).onEvent(eq(eventBundle));
+    }
+
+    @Test
+    public void testOnEvent_nullMonitor_eventIsIgnored() throws Exception {
+        mMonitorWrapper = new BackupManagerMonitorWrapper(/* monitor */ null);
+
+        mMonitorWrapper.onEvent(new Bundle());
+
+        verify(mMonitor, never()).onEvent(any());
+    }
+}
diff --git a/core/tests/coretests/src/android/content/res/FontScaleConverterActivityTest.java b/core/tests/coretests/src/android/content/res/FontScaleConverterActivityTest.java
index c6bb07b..b2e42ba 100644
--- a/core/tests/coretests/src/android/content/res/FontScaleConverterActivityTest.java
+++ b/core/tests/coretests/src/android/content/res/FontScaleConverterActivityTest.java
@@ -26,6 +26,7 @@
 import android.compat.testing.PlatformCompatChangeRule;
 import android.os.Bundle;
 import android.platform.test.annotations.IwTest;
+import android.platform.test.annotations.PlatinumTest;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
 import android.util.PollingCheck;
@@ -45,12 +46,12 @@
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.junit.After;
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestRule;
 import org.junit.runner.RunWith;
 
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
 /**
@@ -67,24 +68,12 @@
     @Rule
     public TestRule compatChangeRule = new PlatformCompatChangeRule();
 
-    private float mOriginalFontScale = Float.MIN_VALUE;
-
-    @Before
-    public void setup() {
-        mOriginalFontScale = Settings.System.getFloat(
-            InstrumentationRegistry.getInstrumentation().getContext().getContentResolver(),
-            Settings.System.FONT_SCALE,
-            Float.MIN_VALUE
-        );
-    }
-
     @After
     public void teardown() {
-        if (mOriginalFontScale != Float.MIN_VALUE) {
-            setSystemFontScale(mOriginalFontScale);
-        }
+        restoreSystemFontScaleToDefault();
     }
 
+    @PlatinumTest(focusArea = "accessibility")
     @IwTest(focusArea = "accessibility")
     @Test
     public void testFontsScaleNonLinearly() {
@@ -116,6 +105,7 @@
         )));
     }
 
+    @PlatinumTest(focusArea = "accessibility")
     @IwTest(focusArea = "accessibility")
     @Test
     public void testOnConfigurationChanged_doesNotCrash() {
@@ -130,6 +120,7 @@
         });
     }
 
+    @PlatinumTest(focusArea = "accessibility")
     @IwTest(focusArea = "accessibility")
     @Test
     public void testUpdateConfiguration_doesNotCrash() {
@@ -141,7 +132,7 @@
         });
     }
 
-    private static void setSystemFontScale(float fontScale) {
+    private void setSystemFontScale(float fontScale) {
         ShellIdentityUtils.invokeWithShellPermissions(() -> {
             Settings.System.putFloat(
                     InstrumentationRegistry.getInstrumentation().getContext().getContentResolver(),
@@ -150,13 +141,43 @@
             );
         });
 
-        PollingCheck.waitFor(/* timeout= */ 5000, () ->
-                InstrumentationRegistry
+        PollingCheck.waitFor(/* timeout= */ 5000, () -> {
+            AtomicBoolean isActivityAtCorrectScale = new AtomicBoolean(false);
+            rule.getScenario().onActivity(activity ->
+                    isActivityAtCorrectScale.set(
+                            activity.getResources()
+                                .getConfiguration()
+                                .fontScale == fontScale
+                    )
+            );
+            return isActivityAtCorrectScale.get() && InstrumentationRegistry
                     .getInstrumentation()
                     .getContext()
                     .getResources()
                     .getConfiguration()
-                    .fontScale == fontScale
+                    .fontScale == fontScale;
+        });
+    }
+
+    private static void restoreSystemFontScaleToDefault() {
+        ShellIdentityUtils.invokeWithShellPermissions(() -> {
+            // TODO(b/279083734): would use Settings.System.resetToDefaults() if it existed
+            Settings.System.putString(
+                    InstrumentationRegistry.getInstrumentation()
+                            .getContext()
+                            .getContentResolver(),
+                    Settings.System.FONT_SCALE,
+                    null,
+                    /* overrideableByRestore= */ true);
+        });
+
+        PollingCheck.waitFor(
+                /* timeout= */ 5000,
+                () -> InstrumentationRegistry.getInstrumentation()
+                                        .getContext()
+                                        .getResources()
+                                        .getConfiguration()
+                                        .fontScale == 1
         );
     }
 
diff --git a/core/tests/coretests/src/android/content/res/TEST_MAPPING b/core/tests/coretests/src/android/content/res/TEST_MAPPING
index ab14950..4ea6e40 100644
--- a/core/tests/coretests/src/android/content/res/TEST_MAPPING
+++ b/core/tests/coretests/src/android/content/res/TEST_MAPPING
@@ -39,18 +39,5 @@
         }
       ]
     }
-  ],
-  "ironwood-postsubmit": [
-    {
-      "name": "FrameworksCoreTests",
-      "options":[
-        {
-            "include-annotation": "android.platform.test.annotations.IwTest"
-        },
-        {
-            "exclude-annotation": "org.junit.Ignore"
-        }
-      ]
-    }
   ]
 }
diff --git a/core/tests/coretests/src/android/view/InsetsSourceTest.java b/core/tests/coretests/src/android/view/InsetsSourceTest.java
index 55680ab..9595332 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceTest.java
@@ -229,20 +229,36 @@
 
     @Test
     public void testGetIndex() {
-        for (int index = 0; index < 2048; index++) {
-            for (int type = FIRST; type <= LAST; type = type << 1) {
-                final int id = InsetsSource.createId(null, index, type);
-                assertEquals(index, InsetsSource.getIndex(id));
+        // Here doesn't iterate all the owners, or the test cannot be done before timeout.
+        for (int owner = 0; owner < 100; owner++) {
+            for (int index = 0; index < 2048; index++) {
+                for (int type = FIRST; type <= LAST; type = type << 1) {
+                    final int id = InsetsSource.createId(owner, index, type);
+                    final int indexFromId = InsetsSource.getIndex(id);
+                    assertEquals("index and indexFromId must be the same. id=" + id
+                            + ", owner=" + owner
+                            + ", index=" + index
+                            + ", type=" + type
+                            + ", indexFromId=" + indexFromId + ".", index, indexFromId);
+                }
             }
         }
     }
 
     @Test
     public void testGetType() {
-        for (int index = 0; index < 2048; index++) {
-            for (int type = FIRST; type <= LAST; type = type << 1) {
-                final int id = InsetsSource.createId(null, index, type);
-                assertEquals(type, InsetsSource.getType(id));
+        // Here doesn't iterate all the owners, or the test cannot be done before timeout.
+        for (int owner = 0; owner < 100; owner++) {
+            for (int index = 0; index < 2048; index++) {
+                for (int type = FIRST; type <= LAST; type = type << 1) {
+                    final int id = InsetsSource.createId(owner, index, type);
+                    final int typeFromId = InsetsSource.getType(id);
+                    assertEquals("type and typeFromId must be the same. id=" + id
+                            + ", owner=" + owner
+                            + ", index=" + index
+                            + ", type=" + type
+                            + ", typeFromId=" + typeFromId + ".", type, typeFromId);
+                }
             }
         }
     }
diff --git a/core/tests/coretests/src/android/view/SurfaceControlRegistryTests.java b/core/tests/coretests/src/android/view/SurfaceControlRegistryTests.java
new file mode 100644
index 0000000..d10ba7c
--- /dev/null
+++ b/core/tests/coretests/src/android/view/SurfaceControlRegistryTests.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import static android.Manifest.permission.READ_FRAME_BUFFER;
+import static android.content.pm.PackageManager.PERMISSION_DENIED;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.PrintWriter;
+import java.util.WeakHashMap;
+
+/**
+ * Class for testing {@link SurfaceControlRegistry}.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksCoreTests:android.view.SurfaceControlRegistryTests
+ */
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class SurfaceControlRegistryTests {
+
+    @BeforeClass
+    public static void setUpOnce() {
+        SurfaceControlRegistry.createProcessInstance(getInstrumentation().getTargetContext());
+    }
+
+    @AfterClass
+    public static void tearDownOnce() {
+        SurfaceControlRegistry.destroyProcessInstance();
+    }
+
+    @Test
+    public void testRequiresPermissionToCreateProcessInstance() {
+        try {
+            Context ctx = mock(Context.class);
+            doReturn(PERMISSION_DENIED).when(ctx).checkSelfPermission(eq(READ_FRAME_BUFFER));
+            SurfaceControlRegistry.createProcessInstance(ctx);
+            fail("Expected SecurityException due to missing permission");
+        } catch (SecurityException se) {
+            // Expected failure
+        } catch (Exception e) {
+            fail("Unexpected exception: " + e);
+        }
+    }
+
+    @Test
+    public void testCreateReleaseSurfaceControl() {
+        int hash0 = SurfaceControlRegistry.getProcessInstance().hashCode();
+        SurfaceControl sc = buildTestSurface();
+        assertNotEquals(hash0, SurfaceControlRegistry.getProcessInstance().hashCode());
+        sc.release();
+        assertEquals(hash0, SurfaceControlRegistry.getProcessInstance().hashCode());
+    }
+
+    @Test
+    public void testCreateReleaseMultipleSurfaceControls() {
+        int hash0 = SurfaceControlRegistry.getProcessInstance().hashCode();
+        SurfaceControl sc1 = buildTestSurface();
+        int hash1 = SurfaceControlRegistry.getProcessInstance().hashCode();
+        assertNotEquals(hash0, hash1);
+        SurfaceControl sc2 = buildTestSurface();
+        int hash1_2 = SurfaceControlRegistry.getProcessInstance().hashCode();
+        assertNotEquals(hash0, hash1_2);
+        assertNotEquals(hash1, hash1_2);
+        // Release in inverse order to verify hashes still differ
+        sc1.release();
+        int hash2 = SurfaceControlRegistry.getProcessInstance().hashCode();
+        assertNotEquals(hash0, hash2);
+        sc2.release();
+        assertEquals(hash0, SurfaceControlRegistry.getProcessInstance().hashCode());
+    }
+
+    @Test
+    public void testThresholds() {
+        SurfaceControlRegistry registry = SurfaceControlRegistry.getProcessInstance();
+        TestReporter reporter = new TestReporter();
+        registry.setReportingThresholds(4 /* max */, 2 /* reset */, reporter);
+
+        // Exceed the threshold ensure the callback is made
+        SurfaceControl sc1 = buildTestSurface();
+        SurfaceControl sc2 = buildTestSurface();
+        SurfaceControl sc3 = buildTestSurface();
+        SurfaceControl sc4 = buildTestSurface();
+        reporter.assertMaxThresholdExceededCallCount(1);
+        reporter.assertLastReportedSetEquals(sc1, sc2, sc3, sc4);
+
+        // Create a few more, ensure we don't report again for the time being
+        SurfaceControl sc5 = buildTestSurface();
+        SurfaceControl sc6 = buildTestSurface();
+        reporter.assertMaxThresholdExceededCallCount(1);
+        reporter.assertLastReportedSetEquals(sc1, sc2, sc3, sc4);
+
+        // Release down to the reset threshold
+        sc1.release();
+        sc2.release();
+        sc3.release();
+        sc4.release();
+
+        // Create a few more to hit the max threshold again
+        SurfaceControl sc7 = buildTestSurface();
+        SurfaceControl sc8 = buildTestSurface();
+        reporter.assertMaxThresholdExceededCallCount(2);
+        reporter.assertLastReportedSetEquals(sc5, sc6, sc7, sc8);
+    }
+
+    private SurfaceControl buildTestSurface() {
+        return new SurfaceControl.Builder()
+                .setContainerLayer()
+                .setName("SurfaceControlRegistryTests")
+                .setCallsite("SurfaceControlRegistryTests")
+                .build();
+    }
+
+    private static class TestReporter implements SurfaceControlRegistry.Reporter {
+        WeakHashMap<SurfaceControl, Long> lastSurfaceControls = new WeakHashMap<>();
+        int callCount = 0;
+
+        @Override
+        public void onMaxLayersExceeded(WeakHashMap<SurfaceControl, Long> surfaceControls,
+                int limit, PrintWriter pw) {
+            lastSurfaceControls.clear();
+            lastSurfaceControls.putAll(surfaceControls);
+            callCount++;
+        }
+
+        public void assertMaxThresholdExceededCallCount(int count) {
+            assertTrue("Expected " + count + " got " + callCount, count == callCount);
+        }
+
+        public void assertLastReportedSetEquals(SurfaceControl... surfaces) {
+            WeakHashMap<SurfaceControl, Long> last = new WeakHashMap<>(lastSurfaceControls);
+            for (int i = 0; i < surfaces.length; i++) {
+                last.remove(surfaces[i]);
+            }
+            if (!last.isEmpty()) {
+                fail("Sets differ");
+            }
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/widget/RemoteViewsTest.java b/core/tests/coretests/src/android/widget/RemoteViewsTest.java
index 963014e..b42a4bd 100644
--- a/core/tests/coretests/src/android/widget/RemoteViewsTest.java
+++ b/core/tests/coretests/src/android/widget/RemoteViewsTest.java
@@ -22,7 +22,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.spy;
@@ -34,9 +33,6 @@
 import android.appwidget.AppWidgetHostView;
 import android.content.Context;
 import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -62,6 +58,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.function.Consumer;
@@ -91,19 +88,6 @@
     }
 
     @Test
-    public void clone_doesNotCopyBitmap() {
-        RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test);
-        Bitmap bitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
-
-        original.setImageViewBitmap(R.id.image, bitmap);
-        RemoteViews clone = original.clone();
-        View inflated = clone.apply(mContext, mContainer);
-
-        Drawable drawable = ((ImageView) inflated.findViewById(R.id.image)).getDrawable();
-        assertSame(bitmap, ((BitmapDrawable)drawable).getBitmap());
-    }
-
-    @Test
     public void clone_originalCanStillBeApplied() {
         RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test);
 
@@ -733,6 +717,30 @@
     }
 
     @Test
+    public void visitUris_nestedViews() {
+        final RemoteViews outer = new RemoteViews(mPackage, R.layout.remote_views_test);
+
+        final RemoteViews inner = new RemoteViews(mPackage, 33);
+        final Uri imageUriI = Uri.parse("content://inner/image");
+        final Icon icon1 = Icon.createWithContentUri("content://inner/icon1");
+        final Icon icon2 = Icon.createWithContentUri("content://inner/icon2");
+        final Icon icon3 = Icon.createWithContentUri("content://inner/icon3");
+        final Icon icon4 = Icon.createWithContentUri("content://inner/icon4");
+        inner.setImageViewUri(R.id.image, imageUriI);
+        inner.setTextViewCompoundDrawables(R.id.text, icon1, icon2, icon3, icon4);
+
+        outer.addView(R.id.layout, inner);
+
+        Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
+        outer.visitUris(visitor);
+        verify(visitor, times(1)).accept(eq(imageUriI));
+        verify(visitor, times(1)).accept(eq(icon1.getUri()));
+        verify(visitor, times(1)).accept(eq(icon2.getUri()));
+        verify(visitor, times(1)).accept(eq(icon3.getUri()));
+        verify(visitor, times(1)).accept(eq(icon4.getUri()));
+    }
+
+    @Test
     public void visitUris_separateOrientation() {
         final RemoteViews landscape = new RemoteViews(mPackage, R.layout.remote_views_test);
         final Uri imageUriL = Uri.parse("content://landscape/image");
@@ -767,4 +775,43 @@
         verify(visitor, times(1)).accept(eq(icon3P.getUri()));
         verify(visitor, times(1)).accept(eq(icon4P.getUri()));
     }
+
+    @Test
+    public void visitUris_sizedViews() {
+        final RemoteViews large = new RemoteViews(mPackage, R.layout.remote_views_test);
+        final Uri imageUriL = Uri.parse("content://large/image");
+        final Icon icon1L = Icon.createWithContentUri("content://large/icon1");
+        final Icon icon2L = Icon.createWithContentUri("content://large/icon2");
+        final Icon icon3L = Icon.createWithContentUri("content://large/icon3");
+        final Icon icon4L = Icon.createWithContentUri("content://large/icon4");
+        large.setImageViewUri(R.id.image, imageUriL);
+        large.setTextViewCompoundDrawables(R.id.text, icon1L, icon2L, icon3L, icon4L);
+
+        final RemoteViews small = new RemoteViews(mPackage, 33);
+        final Uri imageUriS = Uri.parse("content://small/image");
+        final Icon icon1S = Icon.createWithContentUri("content://small/icon1");
+        final Icon icon2S = Icon.createWithContentUri("content://small/icon2");
+        final Icon icon3S = Icon.createWithContentUri("content://small/icon3");
+        final Icon icon4S = Icon.createWithContentUri("content://small/icon4");
+        small.setImageViewUri(R.id.image, imageUriS);
+        small.setTextViewCompoundDrawables(R.id.text, icon1S, icon2S, icon3S, icon4S);
+
+        HashMap<SizeF, RemoteViews> sizedViews = new HashMap<>();
+        sizedViews.put(new SizeF(300, 300), large);
+        sizedViews.put(new SizeF(100, 100), small);
+        RemoteViews views = new RemoteViews(sizedViews);
+
+        Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
+        views.visitUris(visitor);
+        verify(visitor, times(1)).accept(eq(imageUriL));
+        verify(visitor, times(1)).accept(eq(icon1L.getUri()));
+        verify(visitor, times(1)).accept(eq(icon2L.getUri()));
+        verify(visitor, times(1)).accept(eq(icon3L.getUri()));
+        verify(visitor, times(1)).accept(eq(icon4L.getUri()));
+        verify(visitor, times(1)).accept(eq(imageUriS));
+        verify(visitor, times(1)).accept(eq(icon1S.getUri()));
+        verify(visitor, times(1)).accept(eq(icon2S.getUri()));
+        verify(visitor, times(1)).accept(eq(icon3S.getUri()));
+        verify(visitor, times(1)).accept(eq(icon4S.getUri()));
+    }
 }
diff --git a/core/tests/coretests/src/android/window/SnapshotDrawerUtilsTest.java b/core/tests/coretests/src/android/window/SnapshotDrawerUtilsTest.java
index 281d677..6764ac8 100644
--- a/core/tests/coretests/src/android/window/SnapshotDrawerUtilsTest.java
+++ b/core/tests/coretests/src/android/window/SnapshotDrawerUtilsTest.java
@@ -88,6 +88,7 @@
                 1, HardwareBuffer.USAGE_CPU_READ_RARELY);
         return new TaskSnapshot(
                 System.currentTimeMillis(),
+                0 /* captureTime */,
                 new ComponentName("", ""), buffer,
                 ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
                 Surface.ROTATION_0, taskSize, contentInsets, new Rect() /* letterboxInsets */,
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index cde100c..8e772a2 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -173,4 +173,25 @@
         waitForIdle();
         verify(mCallback2).onBackStarted(any(BackEvent.class));
     }
+
+    @Test
+    public void onUnregisterWhileBackInProgress_callOnBackCancelled() throws RemoteException {
+        ArgumentCaptor<OnBackInvokedCallbackInfo> captor =
+                ArgumentCaptor.forClass(OnBackInvokedCallbackInfo.class);
+
+        mDispatcher.registerOnBackInvokedCallback(
+                OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCallback1);
+
+        verify(mWindowSession).setOnBackInvokedCallbackInfo(
+                Mockito.eq(mWindow),
+                captor.capture());
+        IOnBackInvokedCallback iOnBackInvokedCallback = captor.getValue().getCallback();
+        iOnBackInvokedCallback.onBackStarted(mBackEvent);
+        waitForIdle();
+        verify(mCallback1).onBackStarted(any(BackEvent.class));
+
+        mDispatcher.unregisterOnBackInvokedCallback(mCallback1);
+        verify(mCallback1).onBackCancelled();
+        verifyNoMoreInteractions(mCallback1);
+    }
 }
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index ead5fd4..a044602 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -525,6 +525,8 @@
         <permission name="android.permission.USE_ATTESTATION_VERIFICATION_SERVICE" />
         <!-- Permission required for GTS test - GtsCredentialsTestCases -->
         <permission name="android.permission.LAUNCH_CREDENTIAL_SELECTOR"/>
+        <!-- Permission required for CTS test IntentRedirectionTest -->
+        <permission name="android.permission.QUERY_CLONED_APPS"/>
     </privapp-permissions>
 
     <privapp-permissions package="com.android.statementservice">
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 92c0dab..e4defcf 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1135,6 +1135,12 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimation.java"
     },
+    "-1060529098": {
+      "message": "  Skipping post-transition snapshot for task %d",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
+      "at": "com\/android\/server\/wm\/Transition.java"
+    },
     "-1060365734": {
       "message": "Attempted to add QS dialog window with bad token %s.  Aborting.",
       "level": "WARN",
@@ -1675,6 +1681,12 @@
       "group": "WM_DEBUG_CONFIGURATION",
       "at": "com\/android\/server\/am\/ActivityManagerService.java"
     },
+    "-584061725": {
+      "message": "Content Recording: Accept session updating same display %d with granted consent, with an existing session %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecordingController.java"
+    },
     "-583031528": {
       "message": "%s",
       "level": "INFO",
@@ -2059,6 +2071,12 @@
       "group": "WM_DEBUG_CONFIGURATION",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "-233530384": {
+      "message": "Content Recording: Incoming session on display %d can't be set since it is already null; the corresponding VirtualDisplay must have already been removed.",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecordingController.java"
+    },
     "-230587670": {
       "message": "SyncGroup %d:  Unfinished container: %s",
       "level": "VERBOSE",
@@ -2161,6 +2179,12 @@
       "group": "WM_DEBUG_BACK_PREVIEW",
       "at": "com\/android\/server\/wm\/TaskFragment.java"
     },
+    "-125383273": {
+      "message": "Content Recording: waiting to record, so do nothing",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecorder.java"
+    },
     "-124316973": {
       "message": "Translucent=%s Floating=%s ShowWallpaper=%s Disable=%s",
       "level": "VERBOSE",
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index 9ed3d9c..9cde187 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -144,6 +144,32 @@
     public @interface DumpFlags {
     }
 
+
+    /**
+     * Trims all Skia caches.
+     * @hide
+     */
+    public static final int CACHE_TRIM_ALL = 0;
+    /**
+     * Trims Skia font caches.
+     * @hide
+     */
+    public static final int CACHE_TRIM_FONT = 1;
+    /**
+     * Trims Skia resource caches.
+     * @hide
+     */
+    public static final int CACHE_TRIM_RESOURCES = 2;
+
+    /** @hide */
+    @IntDef(prefix = {"CACHE_TRIM_"}, value = {
+            CACHE_TRIM_ALL,
+            CACHE_TRIM_FONT,
+            CACHE_TRIM_RESOURCES
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CacheTrimLevel {}
+
     /**
      * Name of the file that holds the shaders cache.
      */
@@ -1131,6 +1157,20 @@
         nTrimMemory(level);
     }
 
+    /**
+     * Invoke this when all font caches should be flushed. This can cause jank on next render
+     * commands so use it only after expensive font allocation operations which would
+     * allocate large amount of temporary memory.
+     *
+     * @param level Hint about which caches to trim. See {@link #CACHE_TRIM_ALL},
+     *              {@link #CACHE_TRIM_FONT}, {@link #CACHE_TRIM_RESOURCES}
+     *
+     * @hide
+     */
+    public static void trimCaches(@CacheTrimLevel int level) {
+        nTrimCaches(level);
+    }
+
     /** @hide */
     public static void overrideProperty(@NonNull String name, @NonNull String value) {
         if (name == null || value == null) {
@@ -1497,6 +1537,8 @@
 
     private static native void nTrimMemory(int level);
 
+    private static native void nTrimCaches(int level);
+
     private static native void nOverrideProperty(String name, String value);
 
     private static native void nFence(long nativeProxy);
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 4d0a058..641a2ae 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -1013,7 +1013,8 @@
         }
         p.setShader(shader);
         p.setColorFilter(null);
-        p.setColor(color);
+        // Alpha is handled by the shader (and color is a no-op because there's a shader)
+        p.setColor(0xFF000000);
         return properties;
     }
 
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
index 658d92c..96190c4b 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
@@ -31,12 +31,14 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.window.extensions.WindowExtensions;
 import androidx.window.extensions.core.util.function.Consumer;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.ArrayUtils;
 
+import java.util.Objects;
 import java.util.concurrent.Executor;
 
 /**
@@ -51,6 +53,7 @@
 public class WindowAreaComponentImpl implements WindowAreaComponent,
         DeviceStateManager.DeviceStateCallback {
 
+    private static final int INVALID_DISPLAY_ADDRESS = -1;
     private final Object mLock = new Object();
 
     @NonNull
@@ -69,8 +72,7 @@
     private final int mConcurrentDisplayState;
     @NonNull
     private final int[] mFoldedDeviceStates;
-    @NonNull
-    private long mRearDisplayAddress = 0;
+    private long mRearDisplayAddress = INVALID_DISPLAY_ADDRESS;
     @WindowAreaSessionState
     private int mRearDisplaySessionStatus = WindowAreaComponent.SESSION_STATE_INACTIVE;
 
@@ -109,10 +111,7 @@
                 R.integer.config_deviceStateConcurrentRearDisplay);
 
         mDeviceStateManager.registerCallback(mExecutor, this);
-        if (mConcurrentDisplayState != INVALID_DEVICE_STATE) {
-            mRearDisplayAddress = Long.parseLong(context.getResources().getString(
-                    R.string.config_rearDisplayPhysicalAddress));
-        }
+        mRearDisplayAddress = getRearDisplayAddress(context);
     }
 
     /**
@@ -220,6 +219,44 @@
     }
 
     /**
+     * Returns the{@link DisplayMetrics} associated with the rear facing display. If the rear facing
+     * display was not found in the display list, but we have already computed the
+     * {@link DisplayMetrics} for that display, we return the cached value. If no display has been
+     * found, then we return an empty {@link DisplayMetrics} value.
+     *
+     * TODO(b/267563768): Update with guidance from Display team for missing displays.
+     *
+     * @since {@link WindowExtensions#VENDOR_API_LEVEL_3}
+     */
+    @Override
+    public DisplayMetrics getRearDisplayMetrics() {
+        DisplayMetrics metrics = null;
+
+        // DISPLAY_CATEGORY_REAR displays are only available when you are in the concurrent
+        // display state, so we have to look through all displays to match the address
+        Display[] displays = mDisplayManager.getDisplays(
+                DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED);
+        for (int i = 0; i < displays.length; i++) {
+            DisplayAddress.Physical address =
+                    (DisplayAddress.Physical) displays[i].getAddress();
+            if (mRearDisplayAddress == address.getPhysicalDisplayId()) {
+                metrics = new DisplayMetrics();
+                displays[i].getRealMetrics(metrics);
+                break;
+            }
+        }
+
+        synchronized (mLock) {
+            // Update the rear display metrics with our latest value if one was received
+            if (metrics != null) {
+                mRearDisplayMetrics = metrics;
+            }
+
+            return Objects.requireNonNullElseGet(mRearDisplayMetrics, DisplayMetrics::new);
+        }
+    }
+
+    /**
      * Adds a listener interested in receiving updates on the RearDisplayPresentationStatus
      * of the device. Because this is being called from the OEM provided
      * extensions, the result of the listener will be posted on the executor
@@ -260,8 +297,8 @@
                 return;
             }
             @WindowAreaStatus int currentStatus = getCurrentRearDisplayPresentationModeStatus();
-            DisplayMetrics metrics =
-                    currentStatus == STATUS_UNSUPPORTED ? null : getRearDisplayMetrics();
+            DisplayMetrics metrics = currentStatus == STATUS_UNSUPPORTED ? new DisplayMetrics()
+                    : getRearDisplayMetrics();
             consumer.accept(
                     new RearDisplayPresentationStatus(currentStatus, metrics));
         }
@@ -342,11 +379,22 @@
                             mRearDisplayPresentationController);
             DeviceStateRequest concurrentDisplayStateRequest = DeviceStateRequest.newBuilder(
                     mConcurrentDisplayState).build();
-            mDeviceStateManager.requestState(
-                    concurrentDisplayStateRequest,
-                    mExecutor,
-                    deviceStateCallback
-            );
+
+            try {
+                mDeviceStateManager.requestState(
+                        concurrentDisplayStateRequest,
+                        mExecutor,
+                        deviceStateCallback
+                );
+            } catch (SecurityException e) {
+                // If a SecurityException occurs when invoking DeviceStateManager#requestState
+                // (e.g. if the caller is not in the foreground, or if it does not have the required
+                // permissions), we should first clean up our local state before re-throwing the
+                // SecurityException to the caller. Otherwise, subsequent attempts to
+                // startRearDisplayPresentationSession will always fail.
+                mRearDisplayPresentationController = null;
+                throw e;
+            }
         }
     }
 
@@ -480,37 +528,10 @@
         }
     }
 
-    /**
-     * Returns the{@link DisplayMetrics} associated with the rear facing display. If the rear facing
-     * display was not found in the display list, but we have already computed the
-     * {@link DisplayMetrics} for that display, we return the cached value.
-     *
-     * TODO(b/267563768): Update with guidance from Display team for missing displays.
-     *
-     * @throws IllegalArgumentException if the display is not found and there is no cached
-     * {@link DisplayMetrics} for this display.
-     */
-    @GuardedBy("mLock")
-    private DisplayMetrics getRearDisplayMetrics() {
-        Display[] displays = mDisplayManager.getDisplays(
-                DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED);
-        for (int i = 0; i < displays.length; i++) {
-            DisplayAddress.Physical address =
-                    (DisplayAddress.Physical) displays[i].getAddress();
-            if (mRearDisplayAddress == address.getPhysicalDisplayId()) {
-                if (mRearDisplayMetrics == null) {
-                    mRearDisplayMetrics = new DisplayMetrics();
-                }
-                displays[i].getRealMetrics(mRearDisplayMetrics);
-                return mRearDisplayMetrics;
-            }
-        }
-        if (mRearDisplayMetrics != null) {
-            return mRearDisplayMetrics;
-        } else {
-            throw new IllegalArgumentException(
-                    "No display found with the provided display address");
-        }
+    private long getRearDisplayAddress(Context context) {
+        String address = context.getResources().getString(
+                R.string.config_rearDisplayPhysicalAddress);
+        return address.isEmpty() ? INVALID_DISPLAY_ADDRESS : Long.parseLong(address);
     }
 
     @GuardedBy("mLock")
diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_move_left.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_move_left.xml
deleted file mode 100644
index 3e0011c..0000000
--- a/libs/WindowManager/Shell/res/drawable/pip_ic_move_left.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24">
-    <path
-        android:fillColor="@color/tv_pip_menu_focus_border"
-        android:pathData="M14,7l-5,5 5,5V7z"/>
-</vector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_move_right.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_move_right.xml
deleted file mode 100644
index f6b3c72..0000000
--- a/libs/WindowManager/Shell/res/drawable/pip_ic_move_right.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24">
-    <path
-        android:fillColor="@color/tv_pip_menu_focus_border"
-        android:pathData="M10,17l5,-5 -5,-5v10z"/>
-</vector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_move_up.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_move_up.xml
deleted file mode 100644
index 1a34462..0000000
--- a/libs/WindowManager/Shell/res/drawable/pip_ic_move_up.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24">
-    <path
-        android:fillColor="@color/tv_pip_menu_focus_border"
-        android:pathData="M7,14l5,-5 5,5H7z"/>
-</vector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/reachability_ui_layout.xml b/libs/WindowManager/Shell/res/layout/reachability_ui_layout.xml
index 49491a7..69b339a 100644
--- a/libs/WindowManager/Shell/res/layout/reachability_ui_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/reachability_ui_layout.xml
@@ -20,47 +20,48 @@
     android:focusable="false"
     android:focusableInTouchMode="false"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:theme="@style/ReachabilityEduHandLayout">
 
     <androidx.appcompat.widget.AppCompatTextView
-        style="@style/ReachabilityEduHandLayout"
         android:text="@string/letterbox_reachability_reposition_text"
         app:drawableTopCompat="@drawable/reachability_education_ic_right_hand"
         android:layout_gravity="center_horizontal|top"
         android:layout_marginTop="@dimen/letterbox_reachability_education_dialog_margin"
         android:id="@+id/reachability_move_up_button"
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
+        android:layout_height="wrap_content"
+        android:visibility="invisible"/>
 
     <androidx.appcompat.widget.AppCompatTextView
-        style="@style/ReachabilityEduHandLayout"
         android:text="@string/letterbox_reachability_reposition_text"
         app:drawableTopCompat="@drawable/reachability_education_ic_right_hand"
         android:layout_gravity="center_vertical|right"
         android:layout_marginTop="@dimen/letterbox_reachability_education_dialog_margin"
         android:id="@+id/reachability_move_right_button"
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
+        android:layout_height="wrap_content"
+        android:visibility="invisible"/>
 
 
     <androidx.appcompat.widget.AppCompatTextView
-        style="@style/ReachabilityEduHandLayout"
         android:text="@string/letterbox_reachability_reposition_text"
         app:drawableTopCompat="@drawable/reachability_education_ic_left_hand"
         android:layout_gravity="center_vertical|left"
         android:layout_marginTop="@dimen/letterbox_reachability_education_dialog_margin"
         android:id="@+id/reachability_move_left_button"
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
+        android:layout_height="wrap_content"
+        android:visibility="invisible"/>
 
     <androidx.appcompat.widget.AppCompatTextView
-        style="@style/ReachabilityEduHandLayout"
         android:text="@string/letterbox_reachability_reposition_text"
         app:drawableTopCompat="@drawable/reachability_education_ic_right_hand"
         android:layout_gravity="center_horizontal|bottom"
         android:layout_marginTop="@dimen/letterbox_reachability_education_dialog_margin"
         android:id="@+id/reachability_move_down_button"
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content"/>
+        android:layout_height="wrap_content"
+        android:visibility="invisible"/>
 
 </com.android.wm.shell.compatui.ReachabilityEduLayout>
diff --git a/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml b/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml
index ab64f9e..82a358c 100644
--- a/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml
@@ -104,9 +104,7 @@
         android:layout_centerHorizontal="true"
         android:layout_alignParentTop="true"
         android:alpha="0"
-        android:contentDescription="@string/a11y_action_pip_move_up"
-        android:elevation="@dimen/pip_menu_arrow_elevation"
-        android:src="@drawable/pip_ic_move_up" />
+        android:contentDescription="@string/a11y_action_pip_move_up"/>
 
     <ImageView
         android:id="@+id/tv_pip_menu_arrow_right"
@@ -115,9 +113,7 @@
         android:layout_centerVertical="true"
         android:layout_alignParentRight="true"
         android:alpha="0"
-        android:contentDescription="@string/a11y_action_pip_move_right"
-        android:elevation="@dimen/pip_menu_arrow_elevation"
-        android:src="@drawable/pip_ic_move_right" />
+        android:contentDescription="@string/a11y_action_pip_move_right"/>
 
     <ImageView
         android:id="@+id/tv_pip_menu_arrow_down"
@@ -126,9 +122,7 @@
         android:layout_centerHorizontal="true"
         android:layout_alignParentBottom="true"
         android:alpha="0"
-        android:contentDescription="@string/a11y_action_pip_move_down"
-        android:elevation="@dimen/pip_menu_arrow_elevation"
-        android:src="@drawable/pip_ic_move_down" />
+        android:contentDescription="@string/a11y_action_pip_move_down"/>
 
     <ImageView
         android:id="@+id/tv_pip_menu_arrow_left"
@@ -137,7 +131,5 @@
         android:layout_centerVertical="true"
         android:layout_alignParentLeft="true"
         android:alpha="0"
-        android:contentDescription="@string/a11y_action_pip_move_left"
-        android:elevation="@dimen/pip_menu_arrow_elevation"
-        android:src="@drawable/pip_ic_move_left" />
+        android:contentDescription="@string/a11y_action_pip_move_left"/>
 </RelativeLayout>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index 7814b7d..6d19e55 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -79,7 +79,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle ignorée."</string>
-    <string name="restart_button_description" msgid="6712141648865547958">"Touchez pour redémarrer cette application afin d\'obtenir un meilleur affichage."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Pour obtenir un meilleur affichage, touchez pour redémarrer cette application."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problèmes d\'appareil photo?\nTouchez pour réajuster"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu?\nTouchez pour rétablir"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo? Touchez pour ignorer."</string>
diff --git a/libs/WindowManager/Shell/res/values-night/styles.xml b/libs/WindowManager/Shell/res/values-night/styles.xml
index 758c99d..4871f7a 100644
--- a/libs/WindowManager/Shell/res/values-night/styles.xml
+++ b/libs/WindowManager/Shell/res/values-night/styles.xml
@@ -17,12 +17,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <style name="ReachabilityEduHandLayout">
+    <style name="ReachabilityEduHandLayout" parent="Theme.AppCompat">
         <item name="android:focusable">false</item>
         <item name="android:focusableInTouchMode">false</item>
         <item name="android:background">@android:color/transparent</item>
-        <item name="android:contentDescription">@string/restart_button_description</item>
-        <item name="android:visibility">invisible</item>
         <item name="android:lineSpacingExtra">-1sp</item>
         <item name="android:textSize">12sp</item>
         <item name="android:textAlignment">center</item>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index ed0cdb6..04ee540 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -79,7 +79,7 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Balão"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerir"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão ignorado."</string>
-    <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar esta app e ficar com uma melhor visão."</string>
+    <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar esta app e ver melhor."</string>
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmara?\nToque aqui para reajustar"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Não foi corrigido?\nToque para reverter"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nenhum problema com a câmara? Toque para ignorar."</string>
diff --git a/libs/WindowManager/Shell/res/values-tvdpi/dimen.xml b/libs/WindowManager/Shell/res/values-tvdpi/dimen.xml
index adbf656..fd82563 100644
--- a/libs/WindowManager/Shell/res/values-tvdpi/dimen.xml
+++ b/libs/WindowManager/Shell/res/values-tvdpi/dimen.xml
@@ -33,8 +33,8 @@
     <!-- outer space minus border width -->
     <dimen name="pip_menu_outer_space_frame">20dp</dimen>
 
-    <dimen name="pip_menu_arrow_size">24dp</dimen>
-    <dimen name="pip_menu_arrow_elevation">5dp</dimen>
+    <dimen name="pip_menu_arrow_size">12dp</dimen>
+    <dimen name="pip_menu_arrow_elevation">1dp</dimen>
 
     <dimen name="pip_menu_elevation_no_menu">1dp</dimen>
     <dimen name="pip_menu_elevation_move_menu">7dp</dimen>
diff --git a/libs/WindowManager/Shell/res/values/colors_tv.xml b/libs/WindowManager/Shell/res/values/colors_tv.xml
index e6933ca..5f7fb12 100644
--- a/libs/WindowManager/Shell/res/values/colors_tv.xml
+++ b/libs/WindowManager/Shell/res/values/colors_tv.xml
@@ -27,6 +27,10 @@
     <color name="tv_pip_menu_focus_border">#E8EAED</color>
     <color name="tv_pip_menu_dim_layer">#990E0E0F</color>
     <color name="tv_pip_menu_background">#1E232C</color>
+    <!-- Normally, the arrow color would be the same as the focus border color. But due to
+        optical illusion that looks too dark on the screen. That's why we define a separate
+        (lighter) arrow color. -->
+    <color name="tv_pip_menu_arrow_color">#F1F3F4</color>
 
     <color name="tv_pip_edu_text">#99D2E3FC</color>
     <color name="tv_pip_edu_text_home_icon">#D2E3FC</color>
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index 2b38888..8635c56 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -151,12 +151,10 @@
         </item>
     </style>
 
-    <style name="ReachabilityEduHandLayout">
+    <style name="ReachabilityEduHandLayout" parent="Theme.AppCompat.Light">
         <item name="android:focusable">false</item>
         <item name="android:focusableInTouchMode">false</item>
         <item name="android:background">@android:color/transparent</item>
-        <item name="android:contentDescription">@string/restart_button_description</item>
-        <item name="android:visibility">invisible</item>
         <item name="android:lineSpacingExtra">-1sp</item>
         <item name="android:textSize">12sp</item>
         <item name="android:textAlignment">center</item>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TEST_MAPPING b/libs/WindowManager/Shell/src/com/android/wm/shell/TEST_MAPPING
deleted file mode 100644
index 8dd1369..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/TEST_MAPPING
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "ironwood-postsubmit": [
-    {
-      "name": "WMShellFlickerTests",
-      "options": [
-        {
-          "include-annotation": "android.platform.test.annotations.IwTest"
-        },
-        {
-          "exclude-annotation": "org.junit.Ignore"
-        }
-      ]
-    }
-  ]
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
index 59f120d..4d87c95 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
@@ -61,6 +61,9 @@
     @VisibleForTesting
     final ActivityEmbeddingAnimationSpec mAnimationSpec;
 
+    @Nullable
+    private Animator mActiveAnimator;
+
     ActivityEmbeddingAnimationRunner(@NonNull Context context,
             @NonNull ActivityEmbeddingController controller) {
         mController = controller;
@@ -75,8 +78,10 @@
         // applied to make sure the surface is ready.
         final List<Consumer<SurfaceControl.Transaction>> postStartTransactionCallbacks =
                 new ArrayList<>();
-        final Animator animator = createAnimator(info, startTransaction, finishTransaction,
+        final Animator animator = createAnimator(info, startTransaction,
+                finishTransaction,
                 () -> mController.onAnimationFinished(transition), postStartTransactionCallbacks);
+        mActiveAnimator = animator;
 
         // Start the animation.
         if (!postStartTransactionCallbacks.isEmpty()) {
@@ -98,6 +103,17 @@
         }
     }
 
+    void cancelAnimationFromMerge() {
+        if (mActiveAnimator == null) {
+            Log.e(TAG,
+                    "No active ActivityEmbedding animator running but mergeAnimation is "
+                            + "trying to cancel one."
+            );
+            return;
+        }
+        mActiveAnimator.end();
+    }
+
     /**
      * Sets transition animation scale settings value.
      * @param scale The setting value of transition animation scale.
@@ -153,6 +169,7 @@
                     adapter.onAnimationEnd(t);
                 }
                 t.apply();
+                mActiveAnimator = null;
                 animationFinishCallback.run();
             }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
index bfbddbb..7b37d59 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingController.java
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.activityembedding;
 
+import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
 import static android.window.TransitionInfo.FLAG_FILLS_TASK;
 import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
 
@@ -111,6 +112,11 @@
         if (containsNonEmbeddedChange && !handleNonEmbeddedChanges(changes)) {
             return false;
         }
+        final TransitionInfo.AnimationOptions options = info.getAnimationOptions();
+        if (options != null && options.getType() == ANIM_SCENE_TRANSITION) {
+            // Scene-transition will be handled by app side.
+            return false;
+        }
 
         // Start ActivityEmbedding animation.
         mTransitionCallbacks.put(transition, finishCallback);
@@ -118,6 +124,13 @@
         return true;
     }
 
+    @Override
+    public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
+            @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        mAnimationRunner.cancelAnimationFromMerge();
+    }
+
     private boolean handleNonEmbeddedChanges(List<TransitionInfo.Change> changes) {
         final Rect nonClosingEmbeddedArea = new Rect();
         for (int i = changes.size() - 1; i >= 0; i--) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java
index 53a438e..c980906 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimation.java
@@ -54,10 +54,42 @@
     void setTriggerBack(boolean triggerBack);
 
     /**
-     * Sets the threshold values that defining edge swipe behavior.
-     * @param progressThreshold the max threshold to keep linear progressing back animation.
+     * Sets the threshold values that define edge swipe behavior.<br>
+     * <br>
+     * <h1>How does {@code nonLinearFactor} work?</h1>
+     * <pre>
+     *     screen              screen              screen
+     *     width               width               width
+     *    |——————|            |————————————|      |————————————————————|
+     *           A     B                   A                   B  C    A
+     *  1 +——————+—————+    1 +————————————+    1 +————————————+———————+
+     *    |     /      |      |          —/|      |            | —————/|
+     *    |    /       |      |        —/  |      |           ——/      |
+     *    |   /        |      |      —/    |      |        ——/ |       |
+     *    |  /         |      |    —/      |      |     ——/    |       |
+     *    | /          |      |  —/        |      |  ——/       |       |
+     *    |/           |      |—/          |      |—/          |       |
+     *  0 +————————————+    0 +————————————+    0 +————————————+———————+
+     *                 B                   B                   B
+     * </pre>
+     * Three devices with different widths (smaller, equal, and wider) relative to the progress
+     * threshold are shown in the graphs.<br>
+     * - A is the width of the screen<br>
+     * - B is the progress threshold (horizontal swipe distance where progress is linear)<br>
+     * - C equals B + (A - B) * nonLinearFactor<br>
+     * <br>
+     * If A is less than or equal to B, {@code progress} for the swipe distance between:<br>
+     * - [0, A] will scale linearly between [0, 1].<br>
+     * If A is greater than B, {@code progress} for swipe distance between:<br>
+     * - [0, B] will scale linearly between [0, B / C]<br>
+     * - (B, A] will scale non-linearly and reach 1.
+     *
+     * @param linearDistance up to this distance progress continues linearly. B in the graph above.
+     * @param maxDistance distance at which the progress will be 1f. A in the graph above.
+     * @param nonLinearFactor This value is used to calculate the target if the screen is wider
+     *                        than the progress threshold.
      */
-    void setSwipeThresholds(float progressThreshold);
+    void setSwipeThresholds(float linearDistance, float maxDistance, float nonLinearFactor);
 
     /**
      * Sets the system bar listener to control the system bar color.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index 6d879b8..bb543f2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -301,9 +301,12 @@
         }
 
         @Override
-        public void setSwipeThresholds(float progressThreshold) {
+        public void setSwipeThresholds(
+                float linearDistance,
+                float maxDistance,
+                float nonLinearFactor) {
             mShellExecutor.execute(() -> BackAnimationController.this.setSwipeThresholds(
-                    progressThreshold));
+                    linearDistance, maxDistance, nonLinearFactor));
         }
 
         @Override
@@ -509,7 +512,7 @@
                 // Constraints - absolute values
                 float minVelocity = mFlingAnimationUtils.getMinVelocityPxPerSecond();
                 float maxVelocity = mFlingAnimationUtils.getHighVelocityPxPerSecond();
-                float maxX = mTouchTracker.getMaxX(); // px
+                float maxX = mTouchTracker.getMaxDistance(); // px
                 float maxFlingDistance = maxX * MAX_FLING_PROGRESS; // px
 
                 // Current state
@@ -605,8 +608,11 @@
         mTouchTracker.setTriggerBack(triggerBack);
     }
 
-    private void setSwipeThresholds(float progressThreshold) {
-        mTouchTracker.setProgressThreshold(progressThreshold);
+    private void setSwipeThresholds(
+            float linearDistance,
+            float maxDistance,
+            float nonLinearFactor) {
+        mTouchTracker.setProgressThresholds(linearDistance, maxDistance, nonLinearFactor);
     }
 
     private void invokeOrCancelBack() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java
index 7a00f5b..a0ada39 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java
@@ -28,11 +28,13 @@
  * Helper class to record the touch location for gesture and generate back events.
  */
 class TouchTracker {
-    private static final String PREDICTIVE_BACK_PROGRESS_THRESHOLD_PROP =
-            "persist.wm.debug.predictive_back_progress_threshold";
-    private static final int PROGRESS_THRESHOLD = SystemProperties
-            .getInt(PREDICTIVE_BACK_PROGRESS_THRESHOLD_PROP, -1);
-    private float mProgressThreshold;
+    private static final String PREDICTIVE_BACK_LINEAR_DISTANCE_PROP =
+            "persist.wm.debug.predictive_back_linear_distance";
+    private static final int LINEAR_DISTANCE = SystemProperties
+            .getInt(PREDICTIVE_BACK_LINEAR_DISTANCE_PROP, -1);
+    private float mLinearDistance = LINEAR_DISTANCE;
+    private float mMaxDistance;
+    private float mNonLinearFactor;
     /**
      * Location of the latest touch event
      */
@@ -125,17 +127,42 @@
         // the location everytime back is restarted after being cancelled.
         float startX = mTriggerBack ? mInitTouchX : mStartThresholdX;
         float deltaX = Math.abs(startX - touchX);
-        float maxX = getMaxX();
-        maxX = maxX == 0 ? 1 : maxX;
-        return MathUtils.constrain(deltaX / maxX, 0, 1);
+        float linearDistance = mLinearDistance;
+        float maxDistance = getMaxDistance();
+        maxDistance = maxDistance == 0 ? 1 : maxDistance;
+        float progress;
+        if (linearDistance < maxDistance) {
+            // Up to linearDistance it behaves linearly, then slowly reaches 1f.
+
+            // maxDistance is composed of linearDistance + nonLinearDistance
+            float nonLinearDistance = maxDistance - linearDistance;
+            float initialTarget = linearDistance + nonLinearDistance * mNonLinearFactor;
+
+            boolean isLinear = deltaX <= linearDistance;
+            if (isLinear) {
+                progress = deltaX / initialTarget;
+            } else {
+                float nonLinearDeltaX = deltaX - linearDistance;
+                float nonLinearProgress = nonLinearDeltaX / nonLinearDistance;
+                float currentTarget = MathUtils.lerp(
+                        /* start = */ initialTarget,
+                        /* stop = */ maxDistance,
+                        /* amount = */ nonLinearProgress);
+                progress = deltaX / currentTarget;
+            }
+        } else {
+            // Always linear behavior.
+            progress = deltaX / maxDistance;
+        }
+        return MathUtils.constrain(progress, 0, 1);
     }
 
     /**
-     * Maximum X value (in pixels).
+     * Maximum distance in pixels.
      * Progress is considered to be completed (1f) when this limit is exceeded.
      */
-    float getMaxX() {
-        return PROGRESS_THRESHOLD >= 0 ? PROGRESS_THRESHOLD : mProgressThreshold;
+    float getMaxDistance() {
+        return mMaxDistance;
     }
 
     BackMotionEvent createProgressEvent(float progress) {
@@ -149,7 +176,14 @@
                 /* departingAnimationTarget = */ null);
     }
 
-    public void setProgressThreshold(float progressThreshold) {
-        mProgressThreshold = progressThreshold;
+    public void setProgressThresholds(float linearDistance, float maxDistance,
+            float nonLinearFactor) {
+        if (LINEAR_DISTANCE >= 0) {
+            mLinearDistance = LINEAR_DISTANCE;
+        } else {
+            mLinearDistance = linearDistance;
+        }
+        mMaxDistance = maxDistance;
+        mNonLinearFactor = nonLinearFactor;
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index adc0c9c..9fcd207 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -46,6 +46,7 @@
 import android.graphics.Paint;
 import android.graphics.Picture;
 import android.graphics.PointF;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.drawable.ShapeDrawable;
 import android.os.RemoteException;
@@ -479,13 +480,18 @@
     void applyThemeAttrs() {
         final TypedArray ta = mContext.obtainStyledAttributes(new int[]{
                 android.R.attr.dialogCornerRadius,
-                com.android.internal.R.attr.materialColorSurfaceBright});
+                com.android.internal.R.attr.materialColorSurfaceBright,
+                com.android.internal.R.attr.materialColorSurfaceContainerHigh});
         boolean supportsRoundedCorners = ScreenDecorationsUtils.supportsRoundedCornersOnWindows(
                 mContext.getResources());
         mCornerRadius = supportsRoundedCorners ? ta.getDimensionPixelSize(0, 0) : 0;
         mBackgroundColorFloating = ta.getColor(1, Color.WHITE);
         mExpandedViewContainer.setBackgroundColor(mBackgroundColorFloating);
+        final int manageMenuBg = ta.getColor(2, Color.WHITE);
         ta.recycle();
+        if (mManageButton != null) {
+            mManageButton.getBackground().setColorFilter(manageMenuBg, PorterDuff.Mode.SRC_IN);
+        }
 
         if (mTaskView != null) {
             mTaskView.setCornerRadius(mCornerRadius);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index e7ec7aa..68fea41 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -38,8 +38,10 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.graphics.Color;
 import android.graphics.Outline;
 import android.graphics.PointF;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.drawable.ColorDrawable;
@@ -1203,6 +1205,12 @@
                 R.layout.bubble_manage_menu, this, false);
         mManageMenu.setVisibility(View.INVISIBLE);
 
+        final TypedArray ta = mContext.obtainStyledAttributes(new int[]{
+                com.android.internal.R.attr.materialColorSurfaceBright});
+        final int menuBackgroundColor = ta.getColor(0, Color.WHITE);
+        ta.recycle();
+        mManageMenu.getBackground().setColorFilter(menuBackgroundColor, PorterDuff.Mode.SRC_IN);
+
         PhysicsAnimator.getInstance(mManageMenu).setDefaultSpringConfig(mManageSpringConfig);
 
         mManageMenu.setOutlineProvider(new ViewOutlineProvider() {
@@ -1338,7 +1346,7 @@
 
     // Recreates & shows the education views. Call when a theme/config change happens.
     private void updateUserEdu() {
-        if (isStackEduVisible()) {
+        if (isStackEduVisible() && !mStackEduView.isHiding()) {
             removeView(mStackEduView);
             mStackEduView = new StackEducationView(mContext, mPositioner, mBubbleController);
             addView(mStackEduView);
@@ -1784,13 +1792,17 @@
             // We're expanded while the last bubble is being removed. Let the scrim animate away
             // and then remove our views (removing the icon view triggers the removal of the
             // bubble window so do that at the end of the animation so we see the scrim animate).
+            BadgedImageView iconView = bubble.getIconView();
             showScrim(false, () -> {
                 mRemovingLastBubbleWhileExpanded = false;
                 bubble.cleanupExpandedView();
-                mBubbleContainer.removeView(bubble.getIconView());
+                if (iconView != null) {
+                    mBubbleContainer.removeView(iconView);
+                }
                 bubble.cleanupViews(); // cleans up the icon view
                 updateExpandedView(); // resets state for no expanded bubble
             });
+            logBubbleEvent(bubble, FrameworkStatsLog.BUBBLE_UICHANGED__ACTION__DISMISSED);
             return;
         }
         // Remove it from the views
@@ -1816,6 +1828,7 @@
         // If a bubble is suppressed, it is not attached to the container. Clean it up.
         if (bubble.isSuppressed()) {
             bubble.cleanupViews();
+            logBubbleEvent(bubble, FrameworkStatsLog.BUBBLE_UICHANGED__ACTION__DISMISSED);
         } else {
             Log.d(TAG, "was asked to remove Bubble, but didn't find the view! " + bubble);
         }
@@ -2505,6 +2518,7 @@
             mExpandedAnimationController.expandFromStack(() -> {
                 updatePointerPosition(false /* forIme */);
                 afterExpandedViewAnimation();
+                mExpandedViewContainer.setVisibility(VISIBLE);
                 mExpandedViewAnimationController.animateForImeVisibilityChange(visible);
             } /* after */);
             return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt
index 627273f..d0598cd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt
@@ -37,8 +37,7 @@
     context: Context,
     positioner: BubblePositioner,
     controller: BubbleController
-)
-    : LinearLayout(context) {
+) : LinearLayout(context) {
 
     private val TAG = if (BubbleDebugConfig.TAG_WITH_CLASS_NAME) "BubbleStackEducationView"
         else BubbleDebugConfig.TAG_BUBBLES
@@ -53,7 +52,8 @@
     private val titleTextView by lazy { findViewById<TextView>(R.id.stack_education_title) }
     private val descTextView by lazy { findViewById<TextView>(R.id.stack_education_description) }
 
-    private var isHiding = false
+    var isHiding = false
+        private set
 
     init {
         LayoutInflater.from(context).inflate(R.layout.bubble_stack_user_education, this)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
index ac6e4c2..53683c6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
@@ -54,14 +54,6 @@
         DevicePostureController.OnDevicePostureChangedListener,
         DisplayController.OnDisplaysChangedListener {
     /**
-     * When {@code true}, floating windows like PiP would auto move to the position
-     * specified by {@link #PREFER_TOP_HALF_IN_TABLETOP} when in tabletop mode.
-     */
-    private static final boolean ENABLE_MOVE_FLOATING_WINDOW_IN_TABLETOP =
-            SystemProperties.getBoolean(
-                    "persist.wm.debug.enable_move_floating_window_in_tabletop", true);
-
-    /**
      * Prefer the {@link #PREFERRED_TABLETOP_HALF_TOP} if this flag is enabled,
      * {@link #PREFERRED_TABLETOP_HALF_BOTTOM} otherwise.
      * See also {@link #getPreferredHalfInTabletopMode()}.
@@ -162,14 +154,6 @@
         }
     }
 
-    /**
-     * @return {@code true} if floating windows like PiP would auto move to the position
-     * specified by {@link #getPreferredHalfInTabletopMode()} when in tabletop mode.
-     */
-    public boolean enableMoveFloatingWindowInTabletop() {
-        return ENABLE_MOVE_FLOATING_WINDOW_IN_TABLETOP;
-    }
-
     /** @return Preferred half for floating windows like PiP when in tabletop mode. */
     @PreferredTabletopHalf
     public int getPreferredHalfInTabletopMode() {
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 56616cb..a9ccdf6 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
@@ -22,6 +22,8 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 
+import static com.android.wm.shell.common.split.SplitScreenConstants.FADE_DURATION;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
@@ -51,6 +53,8 @@
 import com.android.wm.shell.common.ScreenshotUtils;
 import com.android.wm.shell.common.SurfaceUtils;
 
+import java.util.function.Consumer;
+
 /**
  * Handles split decor like showing resizing hint for a specific split.
  */
@@ -58,7 +62,6 @@
     private static final String TAG = SplitDecorManager.class.getSimpleName();
     private static final String RESIZING_BACKGROUND_SURFACE_NAME = "ResizingBackground";
     private static final String GAP_BACKGROUND_SURFACE_NAME = "GapBackground";
-    private static final long FADE_DURATION = 133;
 
     private final IconProvider mIconProvider;
     private final SurfaceSession mSurfaceSession;
@@ -251,7 +254,7 @@
     }
 
     /** Stops showing resizing hint. */
-    public void onResized(SurfaceControl.Transaction t, Runnable animFinishedCallback) {
+    public void onResized(SurfaceControl.Transaction t, Consumer<Boolean> animFinishedCallback) {
         if (mScreenshotAnimator != null && mScreenshotAnimator.isRunning()) {
             mScreenshotAnimator.cancel();
         }
@@ -261,6 +264,7 @@
 
             final SurfaceControl.Transaction animT = new SurfaceControl.Transaction();
             mScreenshotAnimator = ValueAnimator.ofFloat(1, 0);
+            mScreenshotAnimator.setDuration(FADE_DURATION);
             mScreenshotAnimator.addUpdateListener(valueAnimator -> {
                 final float progress = (float) valueAnimator.getAnimatedValue();
                 animT.setAlpha(mScreenshot, progress);
@@ -281,7 +285,7 @@
                     mScreenshot = null;
 
                     if (mRunningAnimationCount == 0 && animFinishedCallback != null) {
-                        animFinishedCallback.run();
+                        animFinishedCallback.accept(true);
                     }
                 }
             });
@@ -289,6 +293,9 @@
         }
 
         if (mResizingIconView == null) {
+            if (mRunningAnimationCount == 0 && animFinishedCallback != null) {
+                animFinishedCallback.accept(false);
+            }
             return;
         }
 
@@ -307,18 +314,21 @@
                         releaseDecor(finishT);
                         finishT.apply();
                         finishT.close();
+                        if (mRunningAnimationCount == 0 && animFinishedCallback != null) {
+                            animFinishedCallback.accept(true);
+                        }
                     }
                 });
                 return;
             }
         }
         if (mShown) {
-            fadeOutDecor(animFinishedCallback);
+            fadeOutDecor(()-> animFinishedCallback.accept(true));
         } else {
             // Decor surface is hidden so release it directly.
             releaseDecor(t);
             if (mRunningAnimationCount == 0 && animFinishedCallback != null) {
-                animFinishedCallback.run();
+                animFinishedCallback.accept(false);
             }
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 2832c55..ab8e7e6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -709,7 +709,8 @@
         return context.getSystemService(WindowManager.class)
                 .getMaximumWindowMetrics()
                 .getWindowInsets()
-                .getInsets(WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout())
+                .getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()
+                        | WindowInsets.Type.displayCutout())
                 .toRect();
     }
 
@@ -717,6 +718,10 @@
         return bounds.width() > bounds.height();
     }
 
+    public boolean isDensityChanged(int densityDpi) {
+        return mDensity != densityDpi;
+    }
+
     /**
      * Return if this layout is landscape.
      */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java
index 0bcafe5..ef93a33 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java
@@ -43,6 +43,11 @@
      */
     public static final int SPLIT_POSITION_BOTTOM_OR_RIGHT = 1;
 
+    /**
+     * Duration used for every split fade-in or fade-out.
+     */
+    public static final int FADE_DURATION = 133;
+
     @IntDef(prefix = {"SPLIT_POSITION_"}, value = {
             SPLIT_POSITION_UNDEFINED,
             SPLIT_POSITION_TOP_OR_LEFT,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java
index 042721c9..0289da9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java
@@ -78,8 +78,15 @@
         return taskInfo != null ? getPackageName(taskInfo.baseIntent) : null;
     }
 
-    /** Returns true if they are the same package. */
-    public static boolean samePackage(String packageName1, String packageName2) {
-        return packageName1 != null && packageName1.equals(packageName2);
+    /** Retrieve user id from a taskId */
+    public static int getUserId(int taskId, ShellTaskOrganizer taskOrganizer) {
+        final ActivityManager.RunningTaskInfo taskInfo = taskOrganizer.getRunningTaskInfo(taskId);
+        return taskInfo != null ? taskInfo.userId : -1;
+    }
+
+    /** Returns true if package names and user ids match. */
+    public static boolean samePackage(String packageName1, String packageName2,
+            int userId1, int userId2) {
+        return (packageName1 != null && packageName1.equals(packageName2)) && (userId1 == userId2);
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 28368ef..5a9c25f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -77,6 +77,8 @@
 import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
 import com.android.wm.shell.pip.PipUiEventLogger;
 import com.android.wm.shell.pip.phone.PipTouchHandler;
+import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
+import com.android.wm.shell.keyguard.KeyguardTransitions;
 import com.android.wm.shell.recents.RecentTasks;
 import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.recents.RecentsTransitionHandler;
@@ -562,6 +564,28 @@
     }
 
     //
+    // Keyguard transitions (optional feature)
+    //
+
+    @WMSingleton
+    @Provides
+    static KeyguardTransitionHandler provideKeyguardTransitionHandler(
+            ShellInit shellInit,
+            Transitions transitions,
+            @ShellMainThread Handler mainHandler,
+            @ShellMainThread ShellExecutor mainExecutor) {
+        return new KeyguardTransitionHandler(
+                    shellInit, transitions, mainHandler, mainExecutor);
+    }
+
+    @WMSingleton
+    @Provides
+    static KeyguardTransitions provideKeyguardTransitions(
+            KeyguardTransitionHandler handler) {
+        return handler.asKeyguardTransitions();
+    }
+
+    //
     // Display areas
     //
 
@@ -708,10 +732,11 @@
 
     @WMSingleton
     @Provides
-    static ShellController provideShellController(ShellInit shellInit,
+    static ShellController provideShellController(Context context,
+            ShellInit shellInit,
             ShellCommandHandler shellCommandHandler,
             @ShellMainThread ShellExecutor mainExecutor) {
-        return new ShellController(shellInit, shellCommandHandler, mainExecutor);
+        return new ShellController(context, shellInit, shellCommandHandler, mainExecutor);
     }
 
     //
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index f3130d3..4980e49 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -60,6 +60,7 @@
 import com.android.wm.shell.freeform.FreeformTaskListener;
 import com.android.wm.shell.freeform.FreeformTaskTransitionHandler;
 import com.android.wm.shell.freeform.FreeformTaskTransitionObserver;
+import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
 import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
 import com.android.wm.shell.onehanded.OneHandedController;
 import com.android.wm.shell.pip.Pip;
@@ -200,6 +201,7 @@
             ShellTaskOrganizer taskOrganizer,
             DisplayController displayController,
             SyncTransactionQueue syncQueue,
+            Transitions transitions,
             Optional<DesktopModeController> desktopModeController,
             Optional<DesktopTasksController> desktopTasksController,
             Optional<SplitScreenController> splitScreenController) {
@@ -211,6 +213,7 @@
                     taskOrganizer,
                     displayController,
                     syncQueue,
+                    transitions,
                     desktopModeController,
                     desktopTasksController,
                     splitScreenController);
@@ -532,9 +535,10 @@
             Optional<SplitScreenController> splitScreenOptional,
             Optional<PipTouchHandler> pipTouchHandlerOptional,
             Optional<RecentsTransitionHandler> recentsTransitionHandler,
+            KeyguardTransitionHandler keyguardTransitionHandler,
             Transitions transitions) {
         return new DefaultMixedHandler(shellInit, transitions, splitScreenOptional,
-                pipTouchHandlerOptional, recentsTransitionHandler);
+                pipTouchHandlerOptional, recentsTransitionHandler, keyguardTransitionHandler);
     }
 
     @WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
index df94b41..fb08c87 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
@@ -266,6 +266,7 @@
         final boolean isShortcut = description.hasMimeType(MIMETYPE_APPLICATION_SHORTCUT);
         final Bundle opts = intent.hasExtra(EXTRA_ACTIVITY_OPTIONS)
                 ? intent.getBundleExtra(EXTRA_ACTIVITY_OPTIONS) : new Bundle();
+        final UserHandle user = intent.getParcelableExtra(EXTRA_USER);
 
         if (isTask) {
             final int taskId = intent.getIntExtra(EXTRA_TASK_ID, INVALID_TASK_ID);
@@ -273,14 +274,14 @@
         } else if (isShortcut) {
             final String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
             final String id = intent.getStringExtra(EXTRA_SHORTCUT_ID);
-            final UserHandle user = intent.getParcelableExtra(EXTRA_USER);
             mStarter.startShortcut(packageName, id, position, opts, user);
         } else {
             final PendingIntent launchIntent = intent.getParcelableExtra(EXTRA_PENDING_INTENT);
             // Put BAL flags to avoid activity start aborted.
             opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, true);
             opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION, true);
-            mStarter.startIntent(launchIntent, null /* fillIntent */, position, opts);
+            mStarter.startIntent(launchIntent, user.getIdentifier(), null /* fillIntent */,
+                    position, opts);
         }
     }
 
@@ -334,8 +335,8 @@
         void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options);
         void startShortcut(String packageName, String shortcutId, @SplitPosition int position,
                 @Nullable Bundle options, UserHandle user);
-        void startIntent(PendingIntent intent, Intent fillInIntent, @SplitPosition int position,
-                @Nullable Bundle options);
+        void startIntent(PendingIntent intent, int userId, Intent fillInIntent,
+                @SplitPosition int position, @Nullable Bundle options);
         void enterSplitScreen(int taskId, boolean leftOrTop);
 
         /**
@@ -379,8 +380,8 @@
         }
 
         @Override
-        public void startIntent(PendingIntent intent, @Nullable Intent fillInIntent, int position,
-                @Nullable Bundle options) {
+        public void startIntent(PendingIntent intent, int userId, @Nullable Intent fillInIntent,
+                int position, @Nullable Bundle options) {
             try {
                 intent.send(mContext, 0, fillInIntent, null, null, null, options);
             } catch (PendingIntent.CanceledException e) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
new file mode 100644
index 0000000..658359e
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.keyguard;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
+import static android.view.WindowManager.TRANSIT_CLOSE;
+import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
+import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
+import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
+import static android.view.WindowManager.TRANSIT_NONE;
+import static android.view.WindowManager.TRANSIT_OPEN;
+import static android.view.WindowManager.TRANSIT_SLEEP;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
+import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
+import static android.window.TransitionInfo.FLAG_OCCLUDES_KEYGUARD;
+
+import static com.android.wm.shell.util.TransitionUtil.isOpeningType;
+import static com.android.wm.shell.util.TransitionUtil.isClosingType;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.RemoteException;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.view.SurfaceControl;
+import android.window.IRemoteTransition;
+import android.window.IRemoteTransitionFinishedCallback;
+import android.window.TransitionInfo;
+import android.window.TransitionRequestInfo;
+import android.window.WindowContainerTransaction;
+
+import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.annotations.ExternalThread;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
+import com.android.wm.shell.sysui.ShellInit;
+import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.transition.Transitions.TransitionFinishCallback;
+
+import java.util.Map;
+
+/**
+ * The handler for Keyguard enter/exit and occlude/unocclude animations.
+ *
+ * <p>This takes the highest priority.
+ */
+public class KeyguardTransitionHandler implements Transitions.TransitionHandler {
+    private static final String TAG = "KeyguardTransition";
+
+    private final Transitions mTransitions;
+    private final Handler mMainHandler;
+    private final ShellExecutor mMainExecutor;
+
+    private final Map<IBinder, IRemoteTransition> mStartedTransitions = new ArrayMap<>();
+
+    /**
+     * Local IRemoteTransition implementations registered by the keyguard service.
+     * @see KeyguardTransitions
+     */
+    private IRemoteTransition mExitTransition = null;
+    private IRemoteTransition mOccludeTransition = null;
+    private IRemoteTransition mOccludeByDreamTransition = null;
+    private IRemoteTransition mUnoccludeTransition = null;
+
+    public KeyguardTransitionHandler(
+            @NonNull ShellInit shellInit,
+            @NonNull Transitions transitions,
+            @NonNull Handler mainHandler,
+            @NonNull ShellExecutor mainExecutor) {
+        mTransitions = transitions;
+        mMainHandler = mainHandler;
+        mMainExecutor = mainExecutor;
+        shellInit.addInitCallback(this::onInit, this);
+    }
+
+    private void onInit() {
+        mTransitions.addHandler(this);
+    }
+
+    /**
+     * Interface for SystemUI implementations to set custom Keyguard exit/occlude handlers.
+     */
+    @ExternalThread
+    public KeyguardTransitions asKeyguardTransitions() {
+        return new KeyguardTransitionsImpl();
+    }
+
+    public static boolean handles(TransitionInfo info) {
+        return (info.getFlags() & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0
+                || (info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0
+                || info.getType() == TRANSIT_KEYGUARD_OCCLUDE
+                || info.getType() == TRANSIT_KEYGUARD_UNOCCLUDE;
+    }
+
+    @Override
+    public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction startTransaction,
+            @NonNull SurfaceControl.Transaction finishTransaction,
+            @NonNull TransitionFinishCallback finishCallback) {
+        if (!handles(info)) {
+            return false;
+        }
+
+        boolean hasOpeningOcclude = false;
+        boolean hasClosingOcclude = false;
+        boolean hasOpeningDream = false;
+        boolean hasClosingApp = false;
+
+        // Check for occluding/dream/closing apps
+        for (int i = info.getChanges().size() - 1; i >= 0; i--) {
+            final TransitionInfo.Change change = info.getChanges().get(i);
+            if ((change.getFlags() & TransitionInfo.FLAG_IS_WALLPAPER) != 0) {
+                continue;
+            } else if (isOpeningType(change.getMode())) {
+                hasOpeningOcclude |= change.hasFlags(FLAG_OCCLUDES_KEYGUARD);
+                hasOpeningDream |= (change.getTaskInfo() != null
+                        && change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_DREAM);
+            } else if (isClosingType(change.getMode())) {
+                hasClosingOcclude |= change.hasFlags(FLAG_OCCLUDES_KEYGUARD);
+                hasClosingApp = true;
+            }
+        }
+
+        // Choose a transition applicable for the changes and keyguard state.
+        if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0) {
+            return startAnimation(mExitTransition,
+                    "going-away",
+                    transition, info, startTransaction, finishTransaction, finishCallback);
+        }
+        if (hasOpeningOcclude || info.getType() == TRANSIT_KEYGUARD_OCCLUDE) {
+            if (hasClosingOcclude) {
+                // Transitions between apps on top of the keyguard can use the default handler.
+                // WM sends a final occlude status update after the transition is finished.
+                return false;
+            }
+            if (hasOpeningDream) {
+                return startAnimation(mOccludeByDreamTransition,
+                        "occlude-by-dream",
+                        transition, info, startTransaction, finishTransaction, finishCallback);
+            } else {
+                return startAnimation(mOccludeTransition,
+                        "occlude",
+                        transition, info, startTransaction, finishTransaction, finishCallback);
+            }
+        } else if (hasClosingApp || info.getType() == TRANSIT_KEYGUARD_UNOCCLUDE) {
+             return startAnimation(mUnoccludeTransition,
+                    "unocclude",
+                    transition, info, startTransaction, finishTransaction, finishCallback);
+        } else {
+            Log.wtf(TAG, "Failed to play: " + info);
+            return false;
+        }
+    }
+
+    private boolean startAnimation(IRemoteTransition remoteHandler, String description,
+            @NonNull IBinder transition, @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction startTransaction,
+            @NonNull SurfaceControl.Transaction finishTransaction,
+            @NonNull TransitionFinishCallback finishCallback) {
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
+                "start keyguard %s transition, info = %s", description, info);
+
+        try {
+            remoteHandler.startAnimation(transition, info, startTransaction,
+                    new IRemoteTransitionFinishedCallback.Stub() {
+                        @Override
+                        public void onTransitionFinished(
+                                WindowContainerTransaction wct, SurfaceControl.Transaction sct) {
+                            mMainExecutor.execute(() -> {
+                                finishCallback.onTransitionFinished(wct, null);
+                            });
+                        }
+                    });
+            mStartedTransitions.put(transition, remoteHandler);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "RemoteException thrown from local IRemoteTransition", e);
+            return false;
+        }
+        startTransaction.clear();
+        return true;
+    }
+
+    @Override
+    public void mergeAnimation(@NonNull IBinder nextTransition, @NonNull TransitionInfo nextInfo,
+            @NonNull SurfaceControl.Transaction nextT, @NonNull IBinder currentTransition,
+            @NonNull TransitionFinishCallback nextFinishCallback) {
+        final IRemoteTransition playing = mStartedTransitions.get(currentTransition);
+
+        if (playing == null) {
+            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, 
+                    "unknown keyguard transition %s", currentTransition);
+            return;
+        }
+
+        if (nextInfo.getType() == TRANSIT_SLEEP) {
+            // An empty SLEEP transition comes in as a signal to abort transitions whenever a sleep
+            // token is held. In cases where keyguard is showing, we are running the animation for
+            // the device sleeping/waking, so it's best to ignore this and keep playing anyway.
+            return;
+        } else {
+            finishAnimationImmediately(currentTransition);
+        }
+    }
+
+    @Override
+    public void onTransitionConsumed(IBinder transition, boolean aborted,
+            SurfaceControl.Transaction finishTransaction) {
+        finishAnimationImmediately(transition);
+    }
+
+    @Nullable
+    @Override
+    public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
+            @NonNull TransitionRequestInfo request) {
+        return null;
+    }
+
+    private void finishAnimationImmediately(IBinder transition) {
+        final IRemoteTransition playing = mStartedTransitions.get(transition);
+
+        if (playing != null) {
+            final IBinder fakeTransition = new Binder();
+            final TransitionInfo fakeInfo = new TransitionInfo(TRANSIT_SLEEP, 0x0);
+            final SurfaceControl.Transaction fakeT = new SurfaceControl.Transaction();
+            final FakeFinishCallback fakeFinishCb = new FakeFinishCallback();
+            try {
+                playing.mergeAnimation(fakeTransition, fakeInfo, fakeT, transition, fakeFinishCb);
+            } catch (RemoteException e) {
+                // There is no good reason for this to happen because the player is a local object
+                // implementing an AIDL interface.
+                Log.wtf(TAG, "RemoteException thrown from KeyguardService transition", e);
+            }
+        }
+    }
+
+    private static class FakeFinishCallback extends IRemoteTransitionFinishedCallback.Stub {
+        @Override
+        public void onTransitionFinished(
+                WindowContainerTransaction wct, SurfaceControl.Transaction t) {
+            return;
+        }
+    }
+
+    @ExternalThread
+    private final class KeyguardTransitionsImpl implements KeyguardTransitions {
+        @Override
+        public void register(
+                IRemoteTransition exitTransition,
+                IRemoteTransition occludeTransition,
+                IRemoteTransition occludeByDreamTransition,
+                IRemoteTransition unoccludeTransition) {
+            mMainExecutor.execute(() -> {
+                mExitTransition = exitTransition;
+                mOccludeTransition = occludeTransition;
+                mOccludeByDreamTransition = occludeByDreamTransition;
+                mUnoccludeTransition = unoccludeTransition;
+            });
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitions.java
new file mode 100644
index 0000000..b4b327f
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitions.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.keyguard;
+
+import android.annotation.NonNull;
+import android.window.IRemoteTransition;
+
+import com.android.wm.shell.common.annotations.ExternalThread;
+
+/**
+ * Interface exposed to SystemUI Keyguard to register handlers for running
+ * animations on keyguard visibility changes.
+ *
+ * TODO(b/274954192): Merge the occludeTransition and occludeByDream handlers and just let the
+ * keyguard handler make the decision on which version it wants to play.
+ */
+@ExternalThread
+public interface KeyguardTransitions {
+    /**
+     * Registers a set of remote transitions for Keyguard.
+     */
+    default void register(
+            @NonNull IRemoteTransition unlockTransition,
+            @NonNull IRemoteTransition occludeTransition,
+            @NonNull IRemoteTransition occludeByDreamTransition,
+            @NonNull IRemoteTransition unoccludeTransition) {}
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
index 78de5f3..3906599 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
@@ -57,27 +57,35 @@
             in Rect destinationBounds, in SurfaceControl overlay) = 2;
 
     /**
+     * Notifies the swiping Activity to PiP onto home transition is aborted
+     *
+     * @param taskId the Task id that the Activity and overlay are currently in.
+     * @param componentName ComponentName represents the Activity
+     */
+    oneway void abortSwipePipToHome(int taskId, in ComponentName componentName) = 3;
+
+    /**
      * Sets listener to get pinned stack animation callbacks.
      */
-    oneway void setPipAnimationListener(IPipAnimationListener listener) = 3;
+    oneway void setPipAnimationListener(IPipAnimationListener listener) = 4;
 
     /**
      * Sets the shelf height and visibility.
      */
-    oneway void setShelfHeight(boolean visible, int shelfHeight) = 4;
+    oneway void setShelfHeight(boolean visible, int shelfHeight) = 5;
 
     /**
      * Sets the next pip animation type to be the alpha animation.
      */
-    oneway void setPipAnimationTypeToAlpha() = 5;
+    oneway void setPipAnimationTypeToAlpha() = 6;
 
     /**
      * Sets the height and visibility of the Launcher keep clear area.
      */
-    oneway void setLauncherKeepClearAreaHeight(boolean visible, int height) = 6;
+    oneway void setLauncherKeepClearAreaHeight(boolean visible, int height) = 7;
 
     /**
      * Sets the app icon size in pixel used by Launcher
      */
-     oneway void setLauncherAppIconSize(int iconSizePx) = 7;
+    oneway void setLauncherAppIconSize(int iconSizePx) = 8;
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index bbfeb90..57cc28d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -328,6 +328,8 @@
         private PipSurfaceTransactionHelper mSurfaceTransactionHelper;
         private @TransitionDirection int mTransitionDirection;
         protected PipContentOverlay mContentOverlay;
+        // Flag to avoid double-end
+        private boolean mHasRequestedEnd;
 
         private PipTransitionAnimator(TaskInfo taskInfo, SurfaceControl leash,
                 @AnimationType int animationType,
@@ -357,6 +359,7 @@
 
         @Override
         public void onAnimationUpdate(ValueAnimator animation) {
+            if (mHasRequestedEnd) return;
             applySurfaceControlTransaction(mLeash,
                     mSurfaceControlTransactionFactory.getTransaction(),
                     animation.getAnimatedFraction());
@@ -364,6 +367,8 @@
 
         @Override
         public void onAnimationEnd(Animator animation) {
+            if (mHasRequestedEnd) return;
+            mHasRequestedEnd = true;
             mCurrentValue = mEndValue;
             final SurfaceControl.Transaction tx =
                     mSurfaceControlTransactionFactory.getTransaction();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java
index 9fa57ca..c701b95 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java
@@ -206,6 +206,7 @@
             tx.show(mLeash);
             tx.setLayer(mLeash, Integer.MAX_VALUE);
             tx.setBuffer(mLeash, mBitmap.getHardwareBuffer());
+            tx.setAlpha(mLeash, 0f);
             tx.reparent(mLeash, parentLeash);
             tx.apply();
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java
index 65a12d6..2590cab 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java
@@ -252,13 +252,16 @@
     // It can be removed when min_sdk of the app is set to 31 or greater.
     @SuppressLint("NewApi")
     private List<RemoteAction> getMediaActions() {
-        if (mMediaController == null || mMediaController.getPlaybackState() == null) {
+        // Cache the PlaybackState since it's a Binder call.
+        final PlaybackState playbackState;
+        if (mMediaController == null
+                || (playbackState = mMediaController.getPlaybackState()) == null) {
             return Collections.emptyList();
         }
 
         ArrayList<RemoteAction> mediaActions = new ArrayList<>();
-        boolean isPlaying = mMediaController.getPlaybackState().isActive();
-        long actions = mMediaController.getPlaybackState().getActions();
+        boolean isPlaying = playbackState.isActive();
+        long actions = playbackState.getActions();
 
         // Prev action
         mPrevAction.setEnabled((actions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 8709eab..db7c3fc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -64,7 +64,6 @@
 import android.graphics.Rect;
 import android.os.RemoteException;
 import android.os.SystemProperties;
-import android.util.Log;
 import android.view.Choreographer;
 import android.view.Display;
 import android.view.Surface;
@@ -109,7 +108,6 @@
 public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
         DisplayController.OnDisplaysChangedListener, ShellTaskOrganizer.FocusListener {
     private static final String TAG = PipTaskOrganizer.class.getSimpleName();
-    private static final boolean DEBUG = false;
 
     /**
      * The fixed start delay in ms when fading out the content overlay from bounds animation.
@@ -464,13 +462,29 @@
             // to the actual Task surface now.
             // PipTransition is responsible to fade it out and cleanup when finishing the enter PIP
             // transition.
-            final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+            final SurfaceControl.Transaction t = mSurfaceControlTransactionFactory.getTransaction();
             mTaskOrganizer.reparentChildSurfaceToTask(taskId, overlay, t);
             t.setLayer(overlay, Integer.MAX_VALUE);
             t.apply();
         }
     }
 
+    /**
+     * Callback when launcher aborts swipe-pip-to-home operation.
+     */
+    public void abortSwipePipToHome(int taskId, ComponentName componentName) {
+        if (!mPipTransitionState.getInSwipePipToHomeTransition()) {
+            return;
+        }
+        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                "Abort swipe-pip-to-home for %s", componentName);
+        sendOnPipTransitionCancelled(TRANSITION_DIRECTION_TO_PIP);
+        // Cleanup internal states
+        mPipTransitionState.setInSwipePipToHomeTransition(false);
+        mPictureInPictureParams = null;
+        mPipTransitionState.setTransitionState(PipTransitionState.UNDEFINED);
+    }
+
     public ActivityManager.RunningTaskInfo getTaskInfo() {
         return mTaskInfo;
     }
@@ -1045,7 +1059,8 @@
     void onExitPipFinished(TaskInfo info) {
         if (mLeash == null) {
             // TODO(239461594): Remove once the double call to onExitPipFinished() is fixed
-            Log.w(TAG, "Warning, onExitPipFinished() called multiple times in the same sessino");
+            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "Warning, onExitPipFinished() called multiple times in the same session");
             return;
         }
 
@@ -1134,15 +1149,13 @@
                 && (mPipTransitionState.getTransitionState() != PipTransitionState.ENTERED_PIP);
         if ((mPipTransitionState.getInSwipePipToHomeTransition()
                 || waitForFixedRotationOnEnteringPip) && fromRotation) {
-            if (DEBUG) {
-                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
-                        "%s: Skip onMovementBoundsChanged on rotation change"
-                                + " InSwipePipToHomeTransition=%b"
-                                + " mWaitForFixedRotation=%b"
-                                + " getTransitionState=%d", TAG,
-                        mPipTransitionState.getInSwipePipToHomeTransition(), mWaitForFixedRotation,
-                        mPipTransitionState.getTransitionState());
-            }
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Skip onMovementBoundsChanged on rotation change"
+                            + " InSwipePipToHomeTransition=%b"
+                            + " mWaitForFixedRotation=%b"
+                            + " getTransitionState=%d", TAG,
+                    mPipTransitionState.getInSwipePipToHomeTransition(), mWaitForFixedRotation,
+                    mPipTransitionState.getTransitionState());
             return;
         }
         final PipAnimationController.PipTransitionAnimator animator =
@@ -1437,8 +1450,9 @@
         }
 
         if (mLeash == null || !mLeash.isValid()) {
-            Log.e(TAG, String.format("scheduleFinishResizePip with null leash! mState=%d",
-                  mPipTransitionState.getTransitionState()));
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: scheduleFinishResizePip with null leash! mState=%d",
+                    TAG, mPipTransitionState.getTransitionState());
             return;
         }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 9677728..dc0a294 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -26,6 +26,7 @@
 import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_PIP;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.transitTypeToString;
 import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
 
@@ -52,6 +53,7 @@
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
+import android.window.TaskSnapshot;
 import android.window.TransitionInfo;
 import android.window.TransitionRequestInfo;
 import android.window.WindowContainerToken;
@@ -92,6 +94,8 @@
     private final Rect mExitDestinationBounds = new Rect();
     @Nullable
     private IBinder mExitTransition;
+    @Nullable
+    private IBinder mMoveToBackTransition;
     private IBinder mRequestedEnterTransition;
     private WindowContainerToken mRequestedEnterTask;
     /** The Task window that is currently in PIP windowing mode. */
@@ -171,9 +175,10 @@
 
         // Exiting PIP.
         final int type = info.getType();
-        if (transition.equals(mExitTransition)) {
+        if (transition.equals(mExitTransition) || transition.equals(mMoveToBackTransition)) {
             mExitDestinationBounds.setEmpty();
             mExitTransition = null;
+            mMoveToBackTransition = null;
             mHasFadeOut = false;
             if (mFinishCallback != null) {
                 callFinishCallback(null /* wct */);
@@ -201,6 +206,8 @@
                     startExitToSplitAnimation(info, startTransaction, finishTransaction,
                             finishCallback, pipTaskInfo);
                     break;
+                case TRANSIT_TO_BACK:
+                    // pass through here is intended
                 case TRANSIT_REMOVE_PIP:
                     removePipImmediately(info, startTransaction, finishTransaction, finishCallback,
                             pipTaskInfo);
@@ -243,11 +250,6 @@
                     finishTransaction);
         }
 
-        // Fade in the fadeout PIP when the fixed rotation is finished.
-        if (mPipTransitionState.isInPip() && !mInFixedRotation && mHasFadeOut) {
-            fadeExistingPip(true /* show */);
-        }
-
         return false;
     }
 
@@ -273,6 +275,15 @@
             WindowContainerTransaction wct = new WindowContainerTransaction();
             augmentRequest(transition, request, wct);
             return wct;
+        } else if (request.getType() == TRANSIT_TO_BACK && request.getTriggerTask() != null
+                && request.getTriggerTask().getWindowingMode() == WINDOWING_MODE_PINNED) {
+            // if we receive a TRANSIT_TO_BACK type of request while in PiP
+            mMoveToBackTransition = transition;
+            // update the transition state to avoid {@link PipTaskOrganizer#onTaskVanished()} calls
+            mPipTransitionState.setTransitionState(PipTransitionState.EXITING_PIP);
+
+            // return an empty WindowContainerTransaction so that we don't check other handlers
+            return new WindowContainerTransaction();
         } else {
             return null;
         }
@@ -865,6 +876,14 @@
                 } else {
                     animator.setColorContentOverlay(mContext);
                 }
+            } else {
+                final TaskSnapshot snapshot = PipUtils.getTaskSnapshot(
+                        taskInfo.launchIntoPipHostTaskId, false /* isLowResolution */);
+                if (snapshot != null) {
+                    // use the task snapshot during the animation, this is for
+                    // launch-into-pip aka. content-pip use case.
+                    animator.setSnapshotContentOverlay(snapshot, sourceHintRect);
+                }
             }
         } else if (enterAnimationType == ANIM_TYPE_ALPHA) {
             animator = mPipAnimationController.getAnimator(taskInfo, leash, destinationBounds,
@@ -1015,6 +1034,16 @@
         mPipOrganizer.onExitPipFinished(prevPipTaskChange.getTaskInfo());
     }
 
+    @Override
+    public boolean syncPipSurfaceState(@NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction startTransaction,
+            @NonNull SurfaceControl.Transaction finishTransaction) {
+        final TransitionInfo.Change pipChange = findCurrentPipTaskChange(info);
+        if (pipChange == null) return false;
+        updatePipForUnhandledTransition(pipChange, startTransaction, finishTransaction);
+        return true;
+    }
+
     private void updatePipForUnhandledTransition(@NonNull TransitionInfo.Change pipChange,
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction) {
@@ -1025,10 +1054,18 @@
         final boolean isInPip = mPipTransitionState.isInPip();
         mSurfaceTransactionHelper
                 .crop(startTransaction, leash, destBounds)
-                .round(startTransaction, leash, isInPip);
+                .round(startTransaction, leash, isInPip)
+                .shadow(startTransaction, leash, isInPip);
         mSurfaceTransactionHelper
                 .crop(finishTransaction, leash, destBounds)
-                .round(finishTransaction, leash, isInPip);
+                .round(finishTransaction, leash, isInPip)
+                .shadow(finishTransaction, leash, isInPip);
+        // Make sure the PiP keeps invisible if it was faded out. If it needs to fade in, that will
+        // be handled by onFixedRotationFinished().
+        if (isInPip && mHasFadeOut) {
+            startTransaction.setAlpha(leash, 0f);
+            finishTransaction.setAlpha(leash, 0f);
+        }
     }
 
     /** Hides and shows the existing PIP during fixed rotation transition of other activities. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
index 949d6f5..2fff0e4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
@@ -240,6 +240,18 @@
             @NonNull final Transitions.TransitionFinishCallback finishCallback) {
     }
 
+    /**
+     * Applies the proper surface states (rounded corners/shadows) to pip surfaces in `info`.
+     * This is intended to be used when PiP is part of another animation but isn't, itself,
+     * animating (eg. unlocking).
+     * @return `true` if there was a pip in `info`.
+     */
+    public boolean syncPipSurfaceState(@NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction startTransaction,
+            @NonNull SurfaceControl.Transaction finishTransaction) {
+        return false;
+    }
+
     /** End the currently-playing PiP animation. */
     public void end() {
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java
index ed8dc7de..fc674a8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java
@@ -65,9 +65,18 @@
         }
         Rect pipBounds = new Rect(startingBounds);
 
-        // move PiP towards corner if user hasn't moved it manually or the flag is on
-        if (mKeepClearAreaGravityEnabled
-                || (!pipBoundsState.hasUserMovedPip() && !pipBoundsState.hasUserResizedPip())) {
+        boolean shouldApplyGravity = false;
+        // if PiP is outside of screen insets, reposition using gravity
+        if (!insets.contains(pipBounds)) {
+            shouldApplyGravity = true;
+        }
+        // if user has not interacted with PiP, reposition using gravity
+        if (!pipBoundsState.hasUserMovedPip() && !pipBoundsState.hasUserResizedPip()) {
+            shouldApplyGravity = true;
+        }
+
+        // apply gravity that will position PiP in bottom left or bottom right corner within insets
+        if (mKeepClearAreaGravityEnabled || shouldApplyGravity) {
             float snapFraction = pipBoundsAlgorithm.getSnapFraction(startingBounds);
             int verticalGravity = Gravity.BOTTOM;
             int horizontalGravity;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index f8e1435..6a861ce 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -677,7 +677,6 @@
                 });
 
         mTabletopModeController.registerOnTabletopModeChangedListener((isInTabletopMode) -> {
-            if (!mTabletopModeController.enableMoveFloatingWindowInTabletop()) return;
             final String tag = "tabletop-mode";
             if (!isInTabletopMode) {
                 mPipBoundsState.removeNamedUnrestrictedKeepClearArea(tag);
@@ -946,10 +945,15 @@
                     mPipBoundsState.getDisplayBounds().right,
                     mPipBoundsState.getDisplayBounds().bottom);
             mPipBoundsState.addNamedUnrestrictedKeepClearArea(LAUNCHER_KEEP_CLEAR_AREA_TAG, rect);
+            updatePipPositionForKeepClearAreas();
         } else {
             mPipBoundsState.removeNamedUnrestrictedKeepClearArea(LAUNCHER_KEEP_CLEAR_AREA_TAG);
+            // postpone moving in response to hide of Launcher in case there's another change
+            mMainExecutor.removeCallbacks(mMovePipInResponseToKeepClearAreasChangeCallback);
+            mMainExecutor.executeDelayed(
+                    mMovePipInResponseToKeepClearAreasChangeCallback,
+                    PIP_KEEP_CLEAR_AREAS_DELAY);
         }
-        updatePipPositionForKeepClearAreas();
     }
 
     private void setLauncherAppIconSize(int iconSizePx) {
@@ -1012,6 +1016,10 @@
         mPipTaskOrganizer.stopSwipePipToHome(taskId, componentName, destinationBounds, overlay);
     }
 
+    private void abortSwipePipToHome(int taskId, ComponentName componentName) {
+        mPipTaskOrganizer.abortSwipePipToHome(taskId, componentName);
+    }
+
     private String getTransitionTag(int direction) {
         switch (direction) {
             case TRANSITION_DIRECTION_TO_PIP:
@@ -1308,6 +1316,12 @@
         }
 
         @Override
+        public void abortSwipePipToHome(int taskId, ComponentName componentName) {
+            executeRemoteCallWithTaskPermission(mController, "abortSwipePipToHome",
+                    (controller) -> controller.abortSwipePipToHome(taskId, componentName));
+        }
+
+        @Override
         public void setShelfHeight(boolean visible, int height) {
             executeRemoteCallWithTaskPermission(mController, "setShelfHeight",
                     (controller) -> controller.setShelfHeight(visible, height));
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
index d076418..613791c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
@@ -31,12 +31,19 @@
 import static com.android.wm.shell.pip.tv.TvPipMenuController.MODE_NO_MENU;
 
 import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Outline;
+import android.graphics.Path;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.PathShape;
 import android.os.Handler;
 import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
@@ -91,6 +98,8 @@
     private final ImageView mArrowLeft;
     private final TvWindowMenuActionButton mA11yDoneButton;
 
+    private final int mArrowElevation;
+
     private @TvPipMenuController.TvPipMenuMode int mCurrentMenuMode = MODE_NO_MENU;
     private final Rect mCurrentPipBounds = new Rect();
     private int mCurrentPipGravity;
@@ -131,21 +140,70 @@
         mArrowLeft = findViewById(R.id.tv_pip_menu_arrow_left);
         mA11yDoneButton = findViewById(R.id.tv_pip_menu_done_button);
 
-        mResizeAnimationDuration = context.getResources().getInteger(
-                R.integer.config_pipResizeAnimationDuration);
-        mPipMenuFadeAnimationDuration = context.getResources()
-                .getInteger(R.integer.tv_window_menu_fade_animation_duration);
+        final Resources res = context.getResources();
+        mResizeAnimationDuration = res.getInteger(R.integer.config_pipResizeAnimationDuration);
+        mPipMenuFadeAnimationDuration =
+                res.getInteger(R.integer.tv_window_menu_fade_animation_duration);
+        mPipMenuOuterSpace = res.getDimensionPixelSize(R.dimen.pip_menu_outer_space);
+        mPipMenuBorderWidth = res.getDimensionPixelSize(R.dimen.pip_menu_border_width);
+        mArrowElevation = res.getDimensionPixelSize(R.dimen.pip_menu_arrow_elevation);
 
-        mPipMenuOuterSpace = context.getResources()
-                .getDimensionPixelSize(R.dimen.pip_menu_outer_space);
-        mPipMenuBorderWidth = context.getResources()
-                .getDimensionPixelSize(R.dimen.pip_menu_border_width);
+        initMoveArrows();
 
         mEduTextDrawer = new TvPipMenuEduTextDrawer(mContext, mainHandler, this);
         mEduTextContainer = (ViewGroup) findViewById(R.id.tv_pip_menu_edu_text_container);
         mEduTextContainer.addView(mEduTextDrawer);
     }
 
+    private void initMoveArrows() {
+        final int arrowSize =
+                mContext.getResources().getDimensionPixelSize(R.dimen.pip_menu_arrow_size);
+        final Path arrowPath = createArrowPath(arrowSize);
+
+        final ShapeDrawable arrowDrawable = new ShapeDrawable();
+        arrowDrawable.setShape(new PathShape(arrowPath, arrowSize, arrowSize));
+        arrowDrawable.setTint(mContext.getResources().getColor(R.color.tv_pip_menu_arrow_color));
+
+        final ViewOutlineProvider arrowOutlineProvider = new ViewOutlineProvider() {
+            @Override
+            public void getOutline(View view, Outline outline) {
+                outline.setPath(createArrowPath(view.getMeasuredHeight()));
+            }
+        };
+
+        initArrow(mArrowRight, arrowOutlineProvider, arrowDrawable, 0);
+        initArrow(mArrowDown, arrowOutlineProvider, arrowDrawable, 90);
+        initArrow(mArrowLeft, arrowOutlineProvider, arrowDrawable, 180);
+        initArrow(mArrowUp, arrowOutlineProvider, arrowDrawable, 270);
+    }
+
+    /**
+     * Creates a Path for a movement arrow in the MODE_MOVE_MENU. The resulting Path is a simple
+     * right-pointing triangle with its tip in the center of a size x size square:
+     *  _ _ _ _ _
+     * |*        |
+     * |* *      |
+     * |*   *    |
+     * |* *      |
+     * |* _ _ _ _|
+     *
+     */
+    private Path createArrowPath(int size) {
+        final Path triangle = new Path();
+        triangle.lineTo(0, size);
+        triangle.lineTo(size / 2, size / 2);
+        triangle.close();
+        return triangle;
+    }
+
+    private void initArrow(View v, ViewOutlineProvider arrowOutlineProvider, Drawable arrowDrawable,
+            int rotation) {
+        v.setOutlineProvider(arrowOutlineProvider);
+        v.setBackground(arrowDrawable);
+        v.setRotation(rotation);
+        v.setElevation(mArrowElevation);
+    }
+
     void onPipTransitionToTargetBoundsStarted(Rect targetBounds) {
         if (targetBounds == null) {
             return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
index ef5e501..2a61445 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
@@ -42,7 +42,8 @@
             "ShellBackPreview"),
     WM_SHELL_RECENT_TASKS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
             Consts.TAG_WM_SHELL),
-    WM_SHELL_PICTURE_IN_PICTURE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+    // TODO(b/282232877): turn logToLogcat to false.
+    WM_SHELL_PICTURE_IN_PICTURE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
             Consts.TAG_WM_SHELL),
     WM_SHELL_SPLIT_SCREEN(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
             Consts.TAG_WM_SPLIT_SCREEN),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index 5c9709c..f35eda6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -371,7 +371,8 @@
      * Find the background task that match the given component.
      */
     @Nullable
-    public ActivityManager.RecentTaskInfo findTaskInBackground(ComponentName componentName) {
+    public ActivityManager.RecentTaskInfo findTaskInBackground(ComponentName componentName,
+            int userId) {
         if (componentName == null) {
             return null;
         }
@@ -383,7 +384,7 @@
             if (task.isVisible) {
                 continue;
             }
-            if (componentName.equals(task.baseIntent.getComponent())) {
+            if (componentName.equals(task.baseIntent.getComponent()) && userId == task.userId) {
                 return task;
             }
         }
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 387d390..c286959 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
@@ -264,21 +264,18 @@
         void cancel(String reason) {
             // restoring (to-home = false) involves submitting more WM changes, so by default, use
             // toHome = true when canceling.
-            cancel(true /* toHome */, reason);
+            cancel(true /* toHome */, false /* withScreenshots */, reason);
         }
 
-        void cancel(boolean toHome, String reason) {
+        void cancel(boolean toHome, boolean withScreenshots, String reason) {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
                     "[%d] RecentsController.cancel: toHome=%b reason=%s",
                     mInstanceId, toHome, reason);
             if (mListener != null) {
-                try {
-                    ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
-                            "[%d] RecentsController.cancel: calling onAnimationCanceled",
-                            mInstanceId);
-                    mListener.onAnimationCanceled(null, null);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Error canceling recents animation", e);
+                if (withScreenshots) {
+                    sendCancelWithSnapshots();
+                } else {
+                    sendCancel(null, null);
                 }
             }
             if (mFinishCB != null) {
@@ -300,24 +297,34 @@
                 snapshots = new TaskSnapshot[mPausingTasks.size()];
                 try {
                     for (int i = 0; i < mPausingTasks.size(); ++i) {
+                        TaskState state = mPausingTasks.get(0);
                         snapshots[i] = ActivityTaskManager.getService().takeTaskSnapshot(
-                                mPausingTasks.get(0).mTaskInfo.taskId);
+                                state.mTaskInfo.taskId, true /* updateCache */);
                     }
                 } catch (RemoteException e) {
                     taskIds = null;
                     snapshots = null;
                 }
             }
+            return sendCancel(taskIds, snapshots);
+        }
+
+        /**
+         * Sends a cancel message to the recents animation.
+         */
+        private boolean sendCancel(@Nullable int[] taskIds,
+                @Nullable TaskSnapshot[] taskSnapshots) {
             try {
+                final String cancelDetails = taskSnapshots != null ? " with snapshots" : "";
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
-                        "[%d] RecentsController.cancel: calling onAnimationCanceled with snapshots",
-                        mInstanceId);
-                mListener.onAnimationCanceled(taskIds, snapshots);
+                        "[%d] RecentsController.cancel: calling onAnimationCanceled %s",
+                        mInstanceId, cancelDetails);
+                mListener.onAnimationCanceled(taskIds, taskSnapshots);
+                return true;
             } catch (RemoteException e) {
                 Slog.e(TAG, "Error canceling recents animation", e);
                 return false;
             }
-            return true;
         }
 
         void cleanUp() {
@@ -519,7 +526,7 @@
                     // Finish recents animation if the display is changed, so the default
                     // transition handler can play the animation such as rotation effect.
                     if (change.hasFlags(TransitionInfo.FLAG_IS_DISPLAY)) {
-                        cancel(mWillFinishToHome, "display change");
+                        cancel(mWillFinishToHome, true /* withScreenshots */, "display change");
                         return;
                     }
                     // Don't consider order-only changes as changing apps.
@@ -633,7 +640,7 @@
                         + foundRecentsClosing);
                 if (foundRecentsClosing) {
                     mWillFinishToHome = false;
-                    cancel(false /* toHome */, "didn't merge");
+                    cancel(false /* toHome */, false /* withScreenshots */, "didn't merge");
                 }
                 return;
             }
@@ -671,7 +678,8 @@
             try {
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
                         "[%d] RecentsController.screenshotTask: taskId=%d", mInstanceId, taskId);
-                return ActivityTaskManager.getService().takeTaskSnapshot(taskId);
+                return ActivityTaskManager.getService().takeTaskSnapshot(taskId,
+                        true /* updateCache */);
             } catch (RemoteException e) {
                 Slog.e(TAG, "Failed to screenshot task", e);
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
index f819bee..c414e70 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/ISplitScreen.aidl
@@ -73,8 +73,8 @@
     /**
      * Starts an activity in a stage.
      */
-    oneway void startIntent(in PendingIntent intent, in Intent fillInIntent, int position,
-            in Bundle options, in InstanceId instanceId) = 9;
+    oneway void startIntent(in PendingIntent intent, int userId, in Intent fillInIntent,
+            int position, in Bundle options, in InstanceId instanceId) = 9;
 
     /**
      * Starts tasks simultaneously in one transition.
@@ -86,8 +86,8 @@
     /**
      * Starts a pair of intent and task in one transition.
      */
-    oneway void startIntentAndTask(in PendingIntent pendingIntent, in Bundle options1, int taskId,
-            in Bundle options2, int sidePosition, float splitRatio,
+    oneway void startIntentAndTask(in PendingIntent pendingIntent, int userId1, in Bundle options1,
+            int taskId, in Bundle options2, int sidePosition, float splitRatio,
             in RemoteTransition remoteTransition, in InstanceId instanceId) = 16;
 
     /**
@@ -107,7 +107,7 @@
     /**
      * Starts a pair of intent and task using legacy transition system.
      */
-    oneway void startIntentAndTaskWithLegacyTransition(in PendingIntent pendingIntent,
+    oneway void startIntentAndTaskWithLegacyTransition(in PendingIntent pendingIntent, int userId1,
             in Bundle options1, int taskId, in Bundle options2, int splitPosition, float splitRatio,
             in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 12;
 
@@ -121,18 +121,18 @@
     /**
      * Start a pair of intents using legacy transition system.
      */
-    oneway void startIntentsWithLegacyTransition(in PendingIntent pendingIntent1,
+    oneway void startIntentsWithLegacyTransition(in PendingIntent pendingIntent1, int userId1,
             in ShortcutInfo shortcutInfo1, in Bundle options1, in PendingIntent pendingIntent2,
-            in ShortcutInfo shortcutInfo2, in Bundle options2, int splitPosition, float splitRatio,
-            in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 18;
+            int userId2, in ShortcutInfo shortcutInfo2, in Bundle options2, int splitPosition,
+            float splitRatio, in RemoteAnimationAdapter adapter, in InstanceId instanceId) = 18;
 
     /**
      * Start a pair of intents in one transition.
      */
-    oneway void startIntents(in PendingIntent pendingIntent1, in ShortcutInfo shortcutInfo1,
-            in Bundle options1, in PendingIntent pendingIntent2, in ShortcutInfo shortcutInfo2,
-            in Bundle options2, int splitPosition, float splitRatio,
-            in RemoteTransition remoteTransition, in InstanceId instanceId) = 19;
+    oneway void startIntents(in PendingIntent pendingIntent1, int userId1,
+            in ShortcutInfo shortcutInfo1, in Bundle options1, in PendingIntent pendingIntent2,
+            int userId2, in ShortcutInfo shortcutInfo2, in Bundle options2, int splitPosition,
+            float splitRatio, in RemoteTransition remoteTransition, in InstanceId instanceId) = 19;
 
     /**
      * Blocking call that notifies and gets additional split-screen targets when entering
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index c654c1b..ea33a1f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -502,7 +502,8 @@
         if (options == null) options = new Bundle();
         final ActivityOptions activityOptions = ActivityOptions.fromBundle(options);
 
-        if (samePackage(packageName, getPackageName(reverseSplitPosition(position)))) {
+        if (samePackage(packageName, getPackageName(reverseSplitPosition(position)),
+                user.getIdentifier(), getUserId(reverseSplitPosition(position)))) {
             if (supportMultiInstancesSplit(packageName)) {
                 activityOptions.setApplyMultipleTaskFlagForShortcut(true);
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
@@ -531,7 +532,9 @@
 
         final String packageName1 = shortcutInfo.getPackage();
         final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer);
-        if (samePackage(packageName1, packageName2)) {
+        final int userId1 = shortcutInfo.getUserId();
+        final int userId2 = SplitScreenUtils.getUserId(taskId, mTaskOrganizer);
+        if (samePackage(packageName1, packageName2, userId1, userId2)) {
             if (supportMultiInstancesSplit(shortcutInfo.getPackage())) {
                 activityOptions.setApplyMultipleTaskFlagForShortcut(true);
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
@@ -558,7 +561,9 @@
         // NOTE: This doesn't correctly pull out packageName2 if taskId is referring to a task in
         //       recents that hasn't launched and is not being organized
         final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer);
-        if (samePackage(packageName1, packageName2)) {
+        final int userId1 = shortcutInfo.getUserId();
+        final int userId2 = SplitScreenUtils.getUserId(taskId, mTaskOrganizer);
+        if (samePackage(packageName1, packageName2, userId1, userId2)) {
             if (supportMultiInstancesSplit(packageName1)) {
                 activityOptions.setApplyMultipleTaskFlagForShortcut(true);
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
@@ -578,23 +583,24 @@
     }
 
     /**
-     * See {@link #startIntent(PendingIntent, Intent, int, Bundle)}
+     * See {@link #startIntent(PendingIntent, int, Intent, int, Bundle)}
      * @param instanceId to be used by {@link SplitscreenEventLogger}
      */
-    public void startIntent(PendingIntent intent, @Nullable Intent fillInIntent,
+    public void startIntent(PendingIntent intent, int userId, @Nullable Intent fillInIntent,
             @SplitPosition int position, @Nullable Bundle options, @NonNull InstanceId instanceId) {
         mStageCoordinator.onRequestToSplit(instanceId, ENTER_REASON_LAUNCHER);
-        startIntent(intent, fillInIntent, position, options);
+        startIntent(intent, userId, fillInIntent, position, options);
     }
 
-    private void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent,
+    private void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, int userId1,
             @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
             @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter,
             InstanceId instanceId) {
         Intent fillInIntent = null;
         final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent);
         final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer);
-        if (samePackage(packageName1, packageName2)) {
+        final int userId2 = SplitScreenUtils.getUserId(taskId, mTaskOrganizer);
+        if (samePackage(packageName1, packageName2, userId1, userId2)) {
             if (supportMultiInstancesSplit(packageName1)) {
                 fillInIntent = new Intent();
                 fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
@@ -611,15 +617,17 @@
                 options1, taskId, options2, splitPosition, splitRatio, adapter, instanceId);
     }
 
-    private void startIntentAndTask(PendingIntent pendingIntent, @Nullable Bundle options1,
-            int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition,
-            float splitRatio, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
+    private void startIntentAndTask(PendingIntent pendingIntent, int userId1,
+            @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
+            @SplitPosition int splitPosition, float splitRatio,
+            @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
         Intent fillInIntent = null;
         final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent);
         // NOTE: This doesn't correctly pull out packageName2 if taskId is referring to a task in
         //       recents that hasn't launched and is not being organized
         final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer);
-        if (samePackage(packageName1, packageName2)) {
+        final int userId2 = SplitScreenUtils.getUserId(taskId, mTaskOrganizer);
+        if (samePackage(packageName1, packageName2, userId1, userId2)) {
             if (supportMultiInstancesSplit(packageName1)) {
                 fillInIntent = new Intent();
                 fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
@@ -639,16 +647,16 @@
                 options2, splitPosition, splitRatio, remoteTransition, instanceId);
     }
 
-    private void startIntentsWithLegacyTransition(PendingIntent pendingIntent1,
+    private void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, int userId1,
             @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
-            PendingIntent pendingIntent2, @Nullable ShortcutInfo shortcutInfo2,
+            PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2,
             @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio,
             RemoteAnimationAdapter adapter, InstanceId instanceId) {
         Intent fillInIntent1 = null;
         Intent fillInIntent2 = null;
         final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent1);
         final String packageName2 = SplitScreenUtils.getPackageName(pendingIntent2);
-        if (samePackage(packageName1, packageName2)) {
+        if (samePackage(packageName1, packageName2, userId1, userId2)) {
             if (supportMultiInstancesSplit(packageName1)) {
                 fillInIntent1 = new Intent();
                 fillInIntent1.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
@@ -668,16 +676,16 @@
                 splitPosition, splitRatio, adapter, instanceId);
     }
 
-    private void startIntents(PendingIntent pendingIntent1,
+    private void startIntents(PendingIntent pendingIntent1, int userId1,
             @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
-            PendingIntent pendingIntent2, @Nullable ShortcutInfo shortcutInfo2,
+            PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2,
             @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio,
             @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
         Intent fillInIntent1 = null;
         Intent fillInIntent2 = null;
         final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent1);
         final String packageName2 = SplitScreenUtils.getPackageName(pendingIntent2);
-        if (samePackage(packageName1, packageName2)) {
+        if (samePackage(packageName1, packageName2, userId1, userId2)) {
             if (supportMultiInstancesSplit(packageName1)) {
                 fillInIntent1 = new Intent();
                 fillInIntent1.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
@@ -698,7 +706,7 @@
     }
 
     @Override
-    public void startIntent(PendingIntent intent, @Nullable Intent fillInIntent,
+    public void startIntent(PendingIntent intent, int userId1, @Nullable Intent fillInIntent,
             @SplitPosition int position, @Nullable Bundle options) {
         // Flag this as a no-user-action launch to prevent sending user leaving event to the current
         // top activity since it's going to be put into another side of the split. This prevents the
@@ -708,13 +716,14 @@
 
         final String packageName1 = SplitScreenUtils.getPackageName(intent);
         final String packageName2 = getPackageName(reverseSplitPosition(position));
-        if (SplitScreenUtils.samePackage(packageName1, packageName2)) {
+        final int userId2 = getUserId(reverseSplitPosition(position));
+        if (samePackage(packageName1, packageName2, userId1, userId2)) {
             if (supportMultiInstancesSplit(packageName1)) {
                 // To prevent accumulating large number of instances in the background, reuse task
                 // in the background with priority.
                 final ActivityManager.RecentTaskInfo taskInfo = mRecentTasksOptional
                         .map(recentTasks -> recentTasks.findTaskInBackground(
-                                intent.getIntent().getComponent()))
+                                intent.getIntent().getComponent(), userId1))
                         .orElse(null);
                 if (taskInfo != null) {
                     startTask(taskInfo.taskId, position, options);
@@ -761,6 +770,24 @@
         return taskInfo != null ? SplitScreenUtils.getPackageName(taskInfo.baseIntent) : null;
     }
 
+    /** Retrieve user id of a specific split position if split screen is activated, otherwise
+     *  returns the user id of the top running task. */
+    private int getUserId(@SplitPosition int position) {
+        ActivityManager.RunningTaskInfo taskInfo;
+        if (isSplitScreenVisible()) {
+            taskInfo = getTaskInfo(position);
+        } else {
+            taskInfo = mRecentTasksOptional
+                    .map(recentTasks -> recentTasks.getTopRunningTask())
+                    .orElse(null);
+            if (!isValidToSplit(taskInfo)) {
+                return -1;
+            }
+        }
+
+        return taskInfo != null ? taskInfo.userId : -1;
+    }
+
     @VisibleForTesting
     boolean supportMultiInstancesSplit(String packageName) {
         if (packageName != null) {
@@ -1069,14 +1096,14 @@
         }
 
         @Override
-        public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent,
+        public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, int userId1,
                 Bundle options1, int taskId, Bundle options2, int splitPosition, float splitRatio,
                 RemoteAnimationAdapter adapter, InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController,
                     "startIntentAndTaskWithLegacyTransition", (controller) ->
                             controller.startIntentAndTaskWithLegacyTransition(pendingIntent,
-                                    options1, taskId, options2, splitPosition, splitRatio, adapter,
-                                    instanceId));
+                                    userId1, options1, taskId, options2, splitPosition, splitRatio,
+                                    adapter, instanceId));
         }
 
         @Override
@@ -1102,13 +1129,14 @@
         }
 
         @Override
-        public void startIntentAndTask(PendingIntent pendingIntent, @Nullable Bundle options1,
-                int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition,
-                float splitRatio, @Nullable RemoteTransition remoteTransition,
-                InstanceId instanceId) {
+        public void startIntentAndTask(PendingIntent pendingIntent, int userId1,
+                @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
+                @SplitPosition int splitPosition, float splitRatio,
+                @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController, "startIntentAndTask",
-                    (controller) -> controller.startIntentAndTask(pendingIntent, options1, taskId,
-                            options2, splitPosition, splitRatio, remoteTransition, instanceId));
+                    (controller) -> controller.startIntentAndTask(pendingIntent, userId1, options1,
+                            taskId, options2, splitPosition, splitRatio, remoteTransition,
+                            instanceId));
         }
 
         @Override
@@ -1122,29 +1150,29 @@
         }
 
         @Override
-        public void startIntentsWithLegacyTransition(PendingIntent pendingIntent1,
+        public void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, int userId1,
                 @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
-                PendingIntent pendingIntent2, @Nullable ShortcutInfo shortcutInfo2,
+                PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2,
                 @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio,
                 RemoteAnimationAdapter adapter, InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController, "startIntentsWithLegacyTransition",
                     (controller) ->
-                        controller.startIntentsWithLegacyTransition(pendingIntent1, shortcutInfo1,
-                                options1, pendingIntent2, shortcutInfo2, options2, splitPosition,
-                                splitRatio, adapter, instanceId)
+                        controller.startIntentsWithLegacyTransition(pendingIntent1, userId1,
+                                shortcutInfo1, options1, pendingIntent2, userId2, shortcutInfo2,
+                                options2, splitPosition, splitRatio, adapter, instanceId)
                     );
         }
 
         @Override
-        public void startIntents(PendingIntent pendingIntent1, @Nullable ShortcutInfo shortcutInfo1,
-                @Nullable Bundle options1, PendingIntent pendingIntent2,
-                @Nullable ShortcutInfo shortcutInfo2, @Nullable Bundle options2,
-                @SplitPosition int splitPosition, float splitRatio,
+        public void startIntents(PendingIntent pendingIntent1, int userId1,
+                @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
+                PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2,
+                @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio,
                 @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController, "startIntents",
                     (controller) ->
-                            controller.startIntents(pendingIntent1, shortcutInfo1,
-                                    options1, pendingIntent2, shortcutInfo2, options2,
+                            controller.startIntents(pendingIntent1, userId1, shortcutInfo1,
+                                    options1, pendingIntent2, userId2, shortcutInfo2, options2,
                                     splitPosition, splitRatio, remoteTransition, instanceId)
             );
         }
@@ -1158,11 +1186,11 @@
         }
 
         @Override
-        public void startIntent(PendingIntent intent, Intent fillInIntent, int position,
+        public void startIntent(PendingIntent intent, int userId, Intent fillInIntent, int position,
                 @Nullable Bundle options, InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController, "startIntent",
-                    (controller) -> controller.startIntent(intent, fillInIntent, position, options,
-                            instanceId));
+                    (controller) -> controller.startIntent(intent, userId, fillInIntent, position,
+                            options, instanceId));
         }
 
         @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
index ee36d52..d2b0e28 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -20,8 +20,10 @@
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
-import static android.view.WindowManager.TRANSIT_TO_FRONT;
 
+import static com.android.wm.shell.animation.Interpolators.ALPHA_IN;
+import static com.android.wm.shell.animation.Interpolators.ALPHA_OUT;
+import static com.android.wm.shell.common.split.SplitScreenConstants.FADE_DURATION;
 import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
 import static com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
@@ -34,7 +36,6 @@
 import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.graphics.Rect;
 import android.os.IBinder;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
@@ -63,7 +64,7 @@
     private final Runnable mOnFinish;
 
     DismissSession mPendingDismiss = null;
-    TransitSession mPendingEnter = null;
+    EnterSession mPendingEnter = null;
     TransitSession mPendingResize = null;
 
     private IBinder mAnimatingTransition = null;
@@ -86,15 +87,22 @@
         mStageCoordinator = stageCoordinator;
     }
 
+    private void initTransition(@NonNull IBinder transition,
+            @NonNull SurfaceControl.Transaction finishTransaction,
+            @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        mAnimatingTransition = transition;
+        mFinishTransaction = finishTransaction;
+        mFinishCallback = finishCallback;
+    }
+
+    /** Play animation for enter transition or dismiss transition. */
     void playAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback,
             @NonNull WindowContainerToken mainRoot, @NonNull WindowContainerToken sideRoot,
             @NonNull WindowContainerToken topRoot) {
-        mFinishCallback = finishCallback;
-        mAnimatingTransition = transition;
-        mFinishTransaction = finishTransaction;
+        initTransition(transition, finishTransaction, finishCallback);
 
         final TransitSession pendingTransition = getPendingTransition(transition);
         if (pendingTransition != null) {
@@ -116,17 +124,19 @@
         playInternalAnimation(transition, info, startTransaction, mainRoot, sideRoot, topRoot);
     }
 
+    /** Internal funcation of playAnimation. */
     private void playInternalAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction t, @NonNull WindowContainerToken mainRoot,
             @NonNull WindowContainerToken sideRoot, @NonNull WindowContainerToken topRoot) {
         // Play some place-holder fade animations
+        final boolean isEnter = isPendingEnter(transition);
         for (int i = info.getChanges().size() - 1; i >= 0; --i) {
             final TransitionInfo.Change change = info.getChanges().get(i);
             final SurfaceControl leash = change.getLeash();
             final int mode = info.getChanges().get(i).getMode();
 
+            final int rootIdx = TransitionUtil.rootIndexFor(change, info);
             if (mode == TRANSIT_CHANGE) {
-                final int rootIdx = TransitionUtil.rootIndexFor(change, info);
                 if (change.getParent() != null) {
                     // This is probably reparented, so we want the parent to be immediately visible
                     final TransitionInfo.Change parentChange = info.getChange(change.getParent());
@@ -142,17 +152,23 @@
                             change.getEndRelOffset().x, change.getEndRelOffset().y);
                 }
             }
-            boolean isRootOrSplitSideRoot = change.getParent() == null
-                    || topRoot.equals(change.getParent());
-            boolean isDivider = change.getFlags() == FLAG_IS_DIVIDER_BAR;
-            // For enter or exit, we only want to animate side roots and the divider but not the
-            // top-root.
-            if (!isRootOrSplitSideRoot || topRoot.equals(change.getContainer()) || isDivider) {
-                continue;
-            }
 
-            if (isPendingEnter(transition) && (mainRoot.equals(change.getContainer())
-                    || sideRoot.equals(change.getContainer()))) {
+            final boolean isTopRoot = topRoot.equals(change.getContainer());
+            final boolean isMainRoot = mainRoot.equals(change.getContainer());
+            final boolean isSideRoot = sideRoot.equals(change.getContainer());
+            final boolean isDivider = change.getFlags() == FLAG_IS_DIVIDER_BAR;
+            final boolean isMainChild = mainRoot.equals(change.getParent());
+            final boolean isSideChild = sideRoot.equals(change.getParent());
+            if (isEnter && (isMainChild || isSideChild)) {
+                // Reset child tasks bounds on finish.
+                mFinishTransaction.setPosition(leash,
+                        change.getEndRelOffset().x, change.getEndRelOffset().y);
+                mFinishTransaction.setCrop(leash, null);
+            } else if (isTopRoot) {
+                // Ensure top root is visible at start.
+                t.setAlpha(leash, 1.f);
+                t.show(leash);
+            } else if (isEnter && isMainRoot || isSideRoot) {
                 t.setPosition(leash, change.getEndAbsBounds().left, change.getEndAbsBounds().top);
                 t.setWindowCrop(leash, change.getEndAbsBounds().width(),
                         change.getEndAbsBounds().height());
@@ -161,35 +177,102 @@
                 t.setLayer(leash, Integer.MAX_VALUE);
                 t.show(leash);
             }
+
+            // We want to use child tasks to animate so ignore split root container and non task
+            // except divider change.
+            if (isTopRoot || isMainRoot || isSideRoot
+                    || (change.getTaskInfo() == null && !isDivider)) {
+                continue;
+            }
+            if (isEnter && mPendingEnter.mResizeAnim) {
+                // We will run animation in next transition so skip anim here
+                continue;
+            } else if (isPendingDismiss(transition)
+                    && mPendingDismiss.mReason == EXIT_REASON_DRAG_DIVIDER) {
+                // TODO(b/280020345): need to refine animation for this but just skip anim now.
+                continue;
+            }
+
+            // Because cross fade might be looked more flicker during animation
+            // (surface become black in middle of animation), we only do fade-out
+            // and show opening surface directly.
             boolean isOpening = TransitionUtil.isOpeningType(info.getType());
-            if (isOpening && (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT)) {
-                // fade in
-                startExampleAnimation(leash, true /* show */);
-            } else if (!isOpening && (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK)) {
+            if (!isOpening && (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK)) {
                 // fade out
-                if (info.getType() == TRANSIT_SPLIT_DISMISS_SNAP) {
-                    // Dismissing via snap-to-top/bottom means that the dismissed task is already
-                    // not-visible (usually cropped to oblivion) so immediately set its alpha to 0
-                    // and don't animate it so it doesn't pop-in when reparented.
-                    t.setAlpha(leash, 0.f);
+                if (change.getSnapshot() != null) {
+                    // This case is happened if task is going to reparent to TDA, the origin leash
+                    // doesn't rendor so we use snapshot to replace it animating.
+                    t.reparent(change.getSnapshot(), info.getRoot(rootIdx).getLeash());
+                    // Use origin leash layer.
+                    t.setLayer(change.getSnapshot(), info.getChanges().size() - i);
+                    t.setPosition(change.getSnapshot(), change.getStartAbsBounds().left,
+                            change.getStartAbsBounds().top);
+                    t.show(change.getSnapshot());
+                    startFadeAnimation(change.getSnapshot(), false /* show */);
                 } else {
-                    startExampleAnimation(leash, false /* show */);
+                    startFadeAnimation(leash, false /* show */);
                 }
+            } else if (mode == TRANSIT_CHANGE && change.getSnapshot() != null) {
+                t.reparent(change.getSnapshot(), info.getRoot(rootIdx).getLeash());
+                // Ensure snapshot it on the top of all transition surfaces
+                t.setLayer(change.getSnapshot(), info.getChanges().size() + 1);
+                t.setPosition(change.getSnapshot(), change.getStartAbsBounds().left,
+                        change.getStartAbsBounds().top);
+                t.show(change.getSnapshot());
+                startFadeAnimation(change.getSnapshot(), false /* show */);
             }
         }
         t.apply();
         onFinish(null /* wct */, null /* wctCB */);
     }
 
+    /** Play animation for drag divider dismiss transition. */
+    void playDragDismissAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction startTransaction,
+            @NonNull SurfaceControl.Transaction finishTransaction,
+            @NonNull Transitions.TransitionFinishCallback finishCallback,
+            @NonNull WindowContainerToken toTopRoot, @NonNull SplitDecorManager toTopDecor,
+            @NonNull WindowContainerToken topRoot) {
+        initTransition(transition, finishTransaction, finishCallback);
+
+        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+            final TransitionInfo.Change change = info.getChanges().get(i);
+            final SurfaceControl leash = change.getLeash();
+
+            if (toTopRoot.equals(change.getContainer())) {
+                startTransaction.setAlpha(leash, 1.f);
+                startTransaction.show(leash);
+
+                ValueAnimator va = new ValueAnimator();
+                mAnimations.add(va);
+
+                toTopDecor.onResized(startTransaction, animated -> {
+                    mAnimations.remove(va);
+                    if (animated) {
+                        mTransitions.getMainExecutor().execute(() -> {
+                            onFinish(null /* wct */, null /* wctCB */);
+                        });
+                    }
+                });
+            } else if (topRoot.equals(change.getContainer())) {
+                // Ensure it on top of all changes in transition.
+                startTransaction.setLayer(leash, Integer.MAX_VALUE);
+                startTransaction.setAlpha(leash, 1.f);
+                startTransaction.show(leash);
+            }
+        }
+        startTransaction.apply();
+        onFinish(null /* wct */, null /* wctCB */);
+    }
+
+    /** Play animation for resize transition. */
     void playResizeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback,
             @NonNull WindowContainerToken mainRoot, @NonNull WindowContainerToken sideRoot,
             @NonNull SplitDecorManager mainDecor, @NonNull SplitDecorManager sideDecor) {
-        mFinishCallback = finishCallback;
-        mAnimatingTransition = transition;
-        mFinishTransaction = finishTransaction;
+        initTransition(transition, finishTransaction, finishCallback);
 
         for (int i = info.getChanges().size() - 1; i >= 0; --i) {
             final TransitionInfo.Change change = info.getChanges().get(i);
@@ -208,11 +291,13 @@
                 mAnimations.add(va);
 
                 decor.setScreenshotIfNeeded(change.getSnapshot(), startTransaction);
-                decor.onResized(startTransaction, () -> {
-                    mTransitions.getMainExecutor().execute(() -> {
-                        mAnimations.remove(va);
-                        onFinish(null /* wct */, null /* wctCB */);
-                    });
+                decor.onResized(startTransaction, animated -> {
+                    mAnimations.remove(va);
+                    if (animated) {
+                        mTransitions.getMainExecutor().execute(() -> {
+                            onFinish(null /* wct */, null /* wctCB */);
+                        });
+                    }
                 });
             }
         }
@@ -265,7 +350,7 @@
             Transitions.TransitionHandler handler,
             @Nullable TransitionConsumedCallback consumedCallback,
             @Nullable TransitionFinishedCallback finishedCallback,
-            int extraTransitType) {
+            int extraTransitType, boolean resizeAnim) {
         if (mPendingEnter != null) {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "  splitTransition "
                     + " skip to start enter split transition since it already exist. ");
@@ -273,7 +358,7 @@
         }
         final IBinder transition = mTransitions.startTransition(transitType, wct, handler);
         setEnterTransition(transition, remoteTransition, consumedCallback, finishedCallback,
-                extraTransitType);
+                extraTransitType, resizeAnim);
         return transition;
     }
 
@@ -282,9 +367,10 @@
             @Nullable RemoteTransition remoteTransition,
             @Nullable TransitionConsumedCallback consumedCallback,
             @Nullable TransitionFinishedCallback finishedCallback,
-            int extraTransitType) {
-        mPendingEnter = new TransitSession(
-                transition, consumedCallback, finishedCallback, remoteTransition, extraTransitType);
+            int extraTransitType, boolean resizeAnim) {
+        mPendingEnter = new EnterSession(
+                transition, consumedCallback, finishedCallback, remoteTransition, extraTransitType,
+                resizeAnim);
 
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "  splitTransition "
                 + " deduced Enter split screen");
@@ -407,78 +493,28 @@
         }
     }
 
-    // TODO(shell-transitions): real animations
-    private void startExampleAnimation(@NonNull SurfaceControl leash, boolean show) {
+    private void startFadeAnimation(@NonNull SurfaceControl leash, boolean show) {
         final float end = show ? 1.f : 0.f;
         final float start = 1.f - end;
         final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
         final ValueAnimator va = ValueAnimator.ofFloat(start, end);
-        va.setDuration(500);
+        va.setDuration(FADE_DURATION);
+        va.setInterpolator(show ? ALPHA_IN : ALPHA_OUT);
         va.addUpdateListener(animation -> {
             float fraction = animation.getAnimatedFraction();
             transaction.setAlpha(leash, start * (1.f - fraction) + end * fraction);
             transaction.apply();
         });
-        final Runnable finisher = () -> {
-            transaction.setAlpha(leash, end);
-            transaction.apply();
-            mTransactionPool.release(transaction);
-            mTransitions.getMainExecutor().execute(() -> {
-                mAnimations.remove(va);
-                onFinish(null /* wct */, null /* wctCB */);
-            });
-        };
         va.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                finisher.run();
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                finisher.run();
-            }
-        });
-        mAnimations.add(va);
-        mTransitions.getAnimExecutor().execute(va::start);
-    }
-
-    // TODO(shell-transitions): real animations
-    private void startExampleResizeAnimation(@NonNull SurfaceControl leash,
-            @NonNull Rect startBounds, @NonNull Rect endBounds) {
-        final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
-        final ValueAnimator va = ValueAnimator.ofFloat(0.f, 1.f);
-        va.setDuration(500);
-        va.addUpdateListener(animation -> {
-            float fraction = animation.getAnimatedFraction();
-            transaction.setWindowCrop(leash,
-                    (int) (startBounds.width() * (1.f - fraction) + endBounds.width() * fraction),
-                    (int) (startBounds.height() * (1.f - fraction)
-                            + endBounds.height() * fraction));
-            transaction.setPosition(leash,
-                    startBounds.left * (1.f - fraction) + endBounds.left * fraction,
-                    startBounds.top * (1.f - fraction) + endBounds.top * fraction);
-            transaction.apply();
-        });
-        final Runnable finisher = () -> {
-            transaction.setWindowCrop(leash, 0, 0);
-            transaction.setPosition(leash, endBounds.left, endBounds.top);
-            transaction.apply();
-            mTransactionPool.release(transaction);
-            mTransitions.getMainExecutor().execute(() -> {
-                mAnimations.remove(va);
-                onFinish(null /* wct */, null /* wctCB */);
-            });
-        };
-        va.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                finisher.run();
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                finisher.run();
+                transaction.setAlpha(leash, end);
+                transaction.apply();
+                mTransactionPool.release(transaction);
+                mTransitions.getMainExecutor().execute(() -> {
+                    mAnimations.remove(va);
+                    onFinish(null /* wct */, null /* wctCB */);
+                });
             }
         });
         mAnimations.add(va);
@@ -567,6 +603,21 @@
         }
     }
 
+    /** Bundled information of enter transition. */
+    class EnterSession extends TransitSession {
+        final boolean mResizeAnim;
+
+        EnterSession(IBinder transition,
+                @Nullable TransitionConsumedCallback consumedCallback,
+                @Nullable TransitionFinishedCallback finishedCallback,
+                @Nullable RemoteTransition remoteTransition,
+                int extraTransitType, boolean resizeAnim) {
+            super(transition, consumedCallback, finishedCallback, remoteTransition,
+                    extraTransitType);
+            this.mResizeAnim = resizeAnim;
+        }
+    }
+
     /** Bundled information of dismiss transition. */
     class DismissSession extends TransitSession {
         final int mReason;
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 fcea9ad..256d48c 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
@@ -23,6 +23,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.RemoteAnimationTarget.MODE_OPENING;
@@ -191,6 +192,9 @@
     private final SplitScreenTransitions mSplitTransitions;
     private final SplitscreenEventLogger mLogger;
     private final ShellExecutor mMainExecutor;
+    // Cache live tile tasks while entering recents, evict them from stages in finish transaction
+    // if user is opening another task(s).
+    private final ArrayList<Integer> mPausingTasks = new ArrayList<>();
     private final Optional<RecentTasksController> mRecentTasks;
 
     private final Rect mTempRect1 = new Rect();
@@ -394,7 +398,8 @@
             mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct,
                     null, this, null /* consumedCallback */, null /* finishedCallback */,
                     isSplitScreenVisible()
-                            ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN);
+                            ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN,
+                    !mIsDropEntering);
         } else {
             mSyncQueue.queue(wct);
             mSyncQueue.runInSync(t -> {
@@ -502,7 +507,8 @@
         prepareEnterSplitScreen(wct, null /* taskInfo */, position);
 
         mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this,
-                null /* consumedCallback */, null /* finishedCallback */, extraTransitType);
+                null /* consumedCallback */, null /* finishedCallback */, extraTransitType,
+                !mIsDropEntering);
     }
 
     /** Launches an activity into split by legacy transition. */
@@ -579,7 +585,6 @@
             return;
         }
 
-        prepareEvictChildTasksIfSplitActive(wct);
         setSideStagePosition(splitPosition, wct);
         options1 = options1 != null ? options1 : new Bundle();
         addActivityOptions(options1, mSideStage);
@@ -601,7 +606,6 @@
             return;
         }
 
-        prepareEvictChildTasksIfSplitActive(wct);
         setSideStagePosition(splitPosition, wct);
         options1 = options1 != null ? options1 : new Bundle();
         addActivityOptions(options1, mSideStage);
@@ -622,7 +626,6 @@
             return;
         }
 
-        prepareEvictChildTasksIfSplitActive(wct);
         setSideStagePosition(splitPosition, wct);
         options1 = options1 != null ? options1 : new Bundle();
         addActivityOptions(options1, mSideStage);
@@ -658,9 +661,13 @@
         // Add task launch requests
         wct.startTask(mainTaskId, mainOptions);
 
+        // leave recents animation by re-start pausing tasks
+        if (mPausingTasks.contains(mainTaskId)) {
+            mPausingTasks.clear();
+        }
         mSplitTransitions.startEnterTransition(
                 TRANSIT_TO_FRONT, wct, remoteTransition, this, null, null,
-                TRANSIT_SPLIT_SCREEN_PAIR_OPEN);
+                TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
         setEnterInstanceId(instanceId);
     }
 
@@ -688,7 +695,6 @@
             mMainStage.activate(wct, false /* reparent */);
         }
 
-        prepareEvictChildTasksIfSplitActive(wct);
         mSplitLayout.setDivideRatio(splitRatio);
         updateWindowBounds(mSplitLayout, wct);
         wct.reorder(mRootTaskInfo.token, true);
@@ -712,7 +718,7 @@
 
         mSplitTransitions.startEnterTransition(
                 TRANSIT_TO_FRONT, wct, remoteTransition, this, null, null,
-                TRANSIT_SPLIT_SCREEN_PAIR_OPEN);
+                TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
         setEnterInstanceId(instanceId);
     }
 
@@ -1072,24 +1078,11 @@
         }
 
         final WindowContainerTransaction evictWct = new WindowContainerTransaction();
-        prepareEvictNonOpeningChildTasks(SPLIT_POSITION_TOP_OR_LEFT, apps, evictWct);
-        prepareEvictNonOpeningChildTasks(SPLIT_POSITION_BOTTOM_OR_RIGHT, apps, evictWct);
+        mMainStage.evictNonOpeningChildren(apps, evictWct);
+        mSideStage.evictNonOpeningChildren(apps, evictWct);
         mSyncQueue.queue(evictWct);
     }
 
-
-    /**
-     * Collects all the current child tasks of a specific split and prepares transaction to evict
-     * them to display.
-     */
-    void prepareEvictChildTasks(@SplitPosition int position, WindowContainerTransaction wct) {
-        if (position == mSideStagePosition) {
-            mSideStage.evictAllChildren(wct);
-        } else {
-            mMainStage.evictAllChildren(wct);
-        }
-    }
-
     void prepareEvictNonOpeningChildTasks(@SplitPosition int position, RemoteAnimationTarget[] apps,
             WindowContainerTransaction wct) {
         if (position == mSideStagePosition) {
@@ -1104,13 +1097,6 @@
         mSideStage.evictInvisibleChildren(wct);
     }
 
-    void prepareEvictChildTasksIfSplitActive(WindowContainerTransaction wct) {
-        if (mMainStage.isActive()) {
-            mMainStage.evictAllChildren(wct);
-            mSideStage.evictAllChildren(wct);
-        }
-    }
-
     Bundle resolveStartStage(@StageType int stage, @SplitPosition int position,
             @Nullable Bundle options, @Nullable WindowContainerTransaction wct) {
         switch (stage) {
@@ -1349,8 +1335,6 @@
             mIsExiting = true;
             childrenToTop.resetBounds(wct);
             wct.reorder(childrenToTop.mRootTaskInfo.token, true);
-            wct.setSmallestScreenWidthDp(childrenToTop.mRootTaskInfo.token,
-                    SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
         }
         wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
                 false /* reparentLeafTaskIfRelaunch */);
@@ -1493,29 +1477,14 @@
 
     private void prepareBringSplit(WindowContainerTransaction wct,
             @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
-        StageTaskListener targetStage;
-        if (isSplitScreenVisible()) {
-            // If the split screen is foreground, retrieves target stage based on position.
-            targetStage = startPosition == mSideStagePosition ? mSideStage : mMainStage;
-        } else {
-            targetStage = mSideStage;
-        }
-
         if (taskInfo != null) {
             wct.startTask(taskInfo.taskId,
                     resolveStartStage(STAGE_TYPE_UNDEFINED, startPosition, null, wct));
         }
-        // If running background, we need to reparent current top visible task to another stage
-        // and evict all tasks current under its.
+        // If running background, we need to reparent current top visible task to main stage.
         if (!isSplitScreenVisible()) {
-            // Recreate so we need to reset position rather than keep position of background split.
-            mSplitLayout.resetDividerPosition();
-            updateWindowBounds(mSplitLayout, wct);
-            final StageTaskListener anotherStage = targetStage == mMainStage
-                    ? mSideStage : mMainStage;
-            anotherStage.reparentTopTask(wct);
-            wct.reorder(mRootTaskInfo.token, true);
-            setRootForceTranslucent(false, wct);
+            mMainStage.reparentTopTask(wct);
+            prepareSplitLayout(wct);
         }
     }
 
@@ -1531,14 +1500,32 @@
             mSideStage.addTask(taskInfo, wct);
         }
         mMainStage.activate(wct, true /* includingTopTask */);
-        mSplitLayout.resetDividerPosition();
+        prepareSplitLayout(wct);
+    }
+
+    private void prepareSplitLayout(WindowContainerTransaction wct) {
+        if (mIsDropEntering) {
+            mSplitLayout.resetDividerPosition();
+        } else {
+            mSplitLayout.setDividerAtBorder(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT);
+        }
         updateWindowBounds(mSplitLayout, wct);
+        if (!mIsDropEntering) {
+            // Reset its smallest width dp to avoid is change layout before it actually resized to
+            // split bounds.
+            wct.setSmallestScreenWidthDp(mMainStage.mRootTaskInfo.token,
+                    SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
+        }
         wct.reorder(mRootTaskInfo.token, true);
         setRootForceTranslucent(false, wct);
     }
 
     void finishEnterSplitScreen(SurfaceControl.Transaction t) {
         mSplitLayout.update(t);
+        mMainStage.getSplitDecorManager().inflate(mContext, mMainStage.mRootLeash,
+                getMainStageBounds());
+        mSideStage.getSplitDecorManager().inflate(mContext, mSideStage.mRootLeash,
+                getSideStageBounds());
         setDividerVisibility(true, t);
         // Ensure divider surface are re-parented back into the hierarchy at the end of the
         // transition. See Transition#buildFinishTransaction for more detail.
@@ -1547,6 +1534,7 @@
         updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
         t.show(mRootTaskLeash);
         setSplitsVisible(true);
+        mIsDropEntering = false;
         updateRecentTasksSplitPair();
         if (!mLogger.hasStartedSession()) {
             mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
@@ -1649,7 +1637,8 @@
     }
 
     private void updateRecentTasksSplitPair() {
-        if (!mShouldUpdateRecents) {
+        // Preventing from single task update while processing recents.
+        if (!mShouldUpdateRecents || !mPausingTasks.isEmpty()) {
             return;
         }
         mRecentTasks.ifPresent(recentTasks -> {
@@ -1776,18 +1765,10 @@
         // Handle entering split screen while there is a split pair running in the background.
         if (stageListener == mSideStageListener && !isSplitScreenVisible() && isSplitActive()
                 && mSplitRequest == null) {
-            if (mIsDropEntering) {
-                mSplitLayout.resetDividerPosition();
-            } else {
-                mSplitLayout.setDividerAtBorder(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT);
-            }
             final WindowContainerTransaction wct = new WindowContainerTransaction();
-            mMainStage.reparentTopTask(wct);
+            prepareEnterSplitScreen(wct);
             mMainStage.evictAllChildren(wct);
             mSideStage.evictOtherChildren(wct, taskId);
-            updateWindowBounds(mSplitLayout, wct);
-            wct.reorder(mRootTaskInfo.token, true);
-            setRootForceTranslucent(false, wct);
 
             mSyncQueue.queue(wct);
             mSyncQueue.runInSync(t -> {
@@ -1982,20 +1963,8 @@
                 exitSplitScreen(null /* childrenToTop */, EXIT_REASON_APP_FINISHED);
             }
         } else if (isSideStage && hasChildren && !mMainStage.isActive()) {
-            mSplitLayout.init();
-
             final WindowContainerTransaction wct = new WindowContainerTransaction();
-            if (mIsDropEntering) {
-                prepareEnterSplitScreen(wct);
-            } else {
-                // TODO (b/238697912) : Add the validation to prevent entering non-recovered status
-                onSplitScreenEnter();
-                mSplitLayout.setDividerAtBorder(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT);
-                mMainStage.activate(wct, true /* includingTopTask */);
-                updateWindowBounds(mSplitLayout, wct);
-                wct.reorder(mRootTaskInfo.token, true);
-                setRootForceTranslucent(false, wct);
-            }
+            prepareEnterSplitScreen(wct);
 
             mSyncQueue.queue(wct);
             mSyncQueue.runInSync(t -> {
@@ -2030,13 +1999,15 @@
         final boolean mainStageToTop =
                 bottomOrRight ? mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
                         : mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT;
+        final StageTaskListener toTopStage = mainStageToTop ? mMainStage : mSideStage;
         if (!ENABLE_SHELL_TRANSITIONS) {
-            exitSplitScreen(mainStageToTop ? mMainStage : mSideStage, reason);
+            exitSplitScreen(toTopStage, reason);
             return;
         }
 
         final int dismissTop = mainStageToTop ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
         final WindowContainerTransaction wct = new WindowContainerTransaction();
+        toTopStage.resetBounds(wct);
         prepareExitSplitScreen(dismissTop, wct);
         if (mRootTaskInfo != null) {
             wct.setDoNotPip(mRootTaskInfo.token);
@@ -2076,18 +2047,16 @@
         // Reset this flag every time onLayoutSizeChanged.
         mShowDecorImmediately = false;
 
-        if (!ENABLE_SHELL_TRANSITIONS) {
-            // Only need screenshot for legacy case because shell transition should screenshot
-            // itself during transition.
-            final SurfaceControl.Transaction startT = mTransactionPool.acquire();
-            mMainStage.screenshotIfNeeded(startT);
-            mSideStage.screenshotIfNeeded(startT);
-            mTransactionPool.release(startT);
-        }
-
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         boolean sizeChanged = updateWindowBounds(layout, wct);
-        if (!sizeChanged) return;
+        if (!sizeChanged) {
+            // We still need to resize on decor for ensure all current status clear.
+            final SurfaceControl.Transaction t = mTransactionPool.acquire();
+            mMainStage.onResized(t);
+            mSideStage.onResized(t);
+            mTransactionPool.release(t);
+            return;
+        }
 
         sendOnBoundsChanged();
         if (ENABLE_SHELL_TRANSITIONS) {
@@ -2095,6 +2064,13 @@
             mSplitTransitions.startResizeTransition(wct, this, (finishWct, t) ->
                     mSplitLayout.setDividerInteractive(true, false, "onSplitResizeFinish"));
         } else {
+            // Only need screenshot for legacy case because shell transition should screenshot
+            // itself during transition.
+            final SurfaceControl.Transaction startT = mTransactionPool.acquire();
+            mMainStage.screenshotIfNeeded(startT);
+            mSideStage.screenshotIfNeeded(startT);
+            mTransactionPool.release(startT);
+
             mSyncQueue.queue(wct);
             mSyncQueue.runInSync(t -> {
                 updateSurfaceBounds(layout, t, false /* applyResizingOffset */);
@@ -2175,6 +2151,14 @@
             return;
         }
         mDisplayLayout.set(mDisplayController.getDisplayLayout(displayId));
+
+        if (mSplitLayout != null && mSplitLayout.isDensityChanged(newConfig.densityDpi)
+                && mMainStage.isActive()
+                && mSplitLayout.updateConfiguration(newConfig)
+                && ENABLE_SHELL_TRANSITIONS) {
+            mSplitLayout.update(null /* t */);
+            onLayoutSizeChanged(mSplitLayout);
+        }
     }
 
     void updateSurfaces(SurfaceControl.Transaction transaction) {
@@ -2344,7 +2328,7 @@
                 prepareEnterSplitScreen(out);
                 mSplitTransitions.setEnterTransition(transition, request.getRemoteTransition(),
                         null /* consumedCallback */, null /* finishedCallback */,
-                        0 /* extraTransitType */);
+                        TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, !mIsDropEntering);
             }
         }
         return out;
@@ -2369,6 +2353,10 @@
                             + " so make sure split-screen state is cleaned-up. "
                             + "mainStageCount=%d sideStageCount=%d", mMainStage.getChildCount(),
                     mSideStage.getChildCount());
+            if (triggerTask != null) {
+                mRecentTasks.ifPresent(
+                        recentTasks -> recentTasks.removeSplitPair(triggerTask.taskId));
+            }
             prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, outWCT);
         }
     }
@@ -2555,8 +2543,17 @@
             shouldAnimate = startPendingEnterAnimation(
                     mSplitTransitions.mPendingEnter, info, startTransaction, finishTransaction);
         } else if (mSplitTransitions.isPendingDismiss(transition)) {
+            final SplitScreenTransitions.DismissSession dismiss = mSplitTransitions.mPendingDismiss;
             shouldAnimate = startPendingDismissAnimation(
-                    mSplitTransitions.mPendingDismiss, info, startTransaction, finishTransaction);
+                    dismiss, info, startTransaction, finishTransaction);
+            if (shouldAnimate && dismiss.mReason == EXIT_REASON_DRAG_DIVIDER) {
+                final StageTaskListener toTopStage =
+                        dismiss.mDismissTop == STAGE_TYPE_MAIN ? mMainStage : mSideStage;
+                mSplitTransitions.playDragDismissAnimation(transition, info, startTransaction,
+                        finishTransaction, finishCallback, toTopStage.mRootTaskInfo.token,
+                        toTopStage.getSplitDecorManager(), mRootTaskInfo.token);
+                return true;
+            }
         } else if (mSplitTransitions.isPendingResize(transition)) {
             mSplitTransitions.playResizeAnimation(transition, info, startTransaction,
                     finishTransaction, finishCallback, mMainStage.mRootTaskInfo.token,
@@ -2583,7 +2580,7 @@
     }
 
     private boolean startPendingEnterAnimation(
-            @NonNull SplitScreenTransitions.TransitSession enterTransition,
+            @NonNull SplitScreenTransitions.EnterSession enterTransition,
             @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t,
             @NonNull SurfaceControl.Transaction finishT) {
         // First, verify that we actually have opened apps in both splits.
@@ -2593,6 +2590,9 @@
             final TransitionInfo.Change change = info.getChanges().get(iC);
             final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
             if (taskInfo == null || !taskInfo.hasParentTask()) continue;
+            if (mPausingTasks.contains(taskInfo.taskId)) {
+                continue;
+            }
             final @StageType int stageType = getStageType(getStageOfTask(taskInfo));
             if (stageType == STAGE_TYPE_MAIN
                     && (isOpeningType(change.getMode()) || change.getMode() == TRANSIT_CHANGE)) {
@@ -2607,7 +2607,8 @@
                 == TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE) {
             if (mainChild == null && sideChild == null) {
                 Log.w(TAG, "Launched a task in split, but didn't receive any task in transition.");
-                mSplitTransitions.mPendingEnter.cancel(null /* finishedCb */);
+                mSplitTransitions.mPendingEnter.cancel((cancelWct, cancelT)
+                        -> prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, cancelWct));
                 return true;
             }
         } else {
@@ -2617,10 +2618,7 @@
                 final int dismissTop = mainChild != null ? STAGE_TYPE_MAIN :
                         (sideChild != null ? STAGE_TYPE_SIDE : STAGE_TYPE_UNDEFINED);
                 mSplitTransitions.mPendingEnter.cancel(
-                        (cancelWct, cancelT) -> {
-                            mSideStage.removeAllTasks(cancelWct, dismissTop == STAGE_TYPE_SIDE);
-                            mMainStage.deactivate(cancelWct, dismissTop == STAGE_TYPE_MAIN);
-                        });
+                        (cancelWct, cancelT) -> prepareExitSplitScreen(dismissTop, cancelWct));
                 return true;
             }
         }
@@ -2629,28 +2627,45 @@
         // transitions locally, but remotes (like Launcher) may get confused if they were
         // depending on listener callbacks. This can happen because task-organizer callbacks
         // aren't serialized with transition callbacks.
+        // This usually occurred on app use trampoline launch new task and finish itself.
         // TODO(b/184679596): Find a way to either include task-org information in
         //                    the transition, or synchronize task-org callbacks.
-        if (mainChild != null && !mMainStage.containsTask(mainChild.getTaskInfo().taskId)) {
+        final boolean mainNotContainOpenTask =
+                mainChild != null && !mMainStage.containsTask(mainChild.getTaskInfo().taskId);
+        final boolean sideNotContainOpenTask =
+                sideChild != null && !mSideStage.containsTask(sideChild.getTaskInfo().taskId);
+        if (mainNotContainOpenTask) {
             Log.w(TAG, "Expected onTaskAppeared on " + mMainStage
                     + " to have been called with " + mainChild.getTaskInfo().taskId
                     + " before startAnimation().");
         }
-        if (sideChild != null && !mSideStage.containsTask(sideChild.getTaskInfo().taskId)) {
+        if (sideNotContainOpenTask) {
             Log.w(TAG, "Expected onTaskAppeared on " + mSideStage
                     + " to have been called with " + sideChild.getTaskInfo().taskId
                     + " before startAnimation().");
         }
-
         final TransitionInfo.Change finalMainChild = mainChild;
         final TransitionInfo.Change finalSideChild = sideChild;
         enterTransition.setFinishedCallback((callbackWct, callbackT) -> {
             if (finalMainChild != null) {
-                mMainStage.evictOtherChildren(callbackWct, finalMainChild.getTaskInfo().taskId);
+                if (!mainNotContainOpenTask) {
+                    mMainStage.evictOtherChildren(callbackWct, finalMainChild.getTaskInfo().taskId);
+                } else {
+                    mMainStage.evictInvisibleChildren(callbackWct);
+                }
             }
             if (finalSideChild != null) {
-                mSideStage.evictOtherChildren(callbackWct, finalSideChild.getTaskInfo().taskId);
+                if (!sideNotContainOpenTask) {
+                    mSideStage.evictOtherChildren(callbackWct, finalSideChild.getTaskInfo().taskId);
+                } else {
+                    mSideStage.evictInvisibleChildren(callbackWct);
+                }
             }
+            if (enterTransition.mResizeAnim) {
+                mShowDecorImmediately = true;
+                mSplitLayout.flingDividerToCenter();
+            }
+            mPausingTasks.clear();
         });
 
         finishEnterSplitScreen(finishT);
@@ -2749,7 +2764,7 @@
                     for (TransitionInfo.Change change : info.getChanges()) {
                         final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
                         if (taskInfo != null
-                                && taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
+                                && taskInfo.getWindowingMode() != WINDOWING_MODE_MULTI_WINDOW) {
                             recentTasks.removeSplitPair(taskInfo.taskId);
                         }
                     }
@@ -2797,6 +2812,10 @@
             mSplitTransitions.mPendingDismiss = null;
             return false;
         }
+        dismissTransition.setFinishedCallback((callbackWct, callbackT) -> {
+            mMainStage.getSplitDecorManager().release(callbackT);
+            mSideStage.getSplitDecorManager().release(callbackT);
+        });
 
         addDividerBarToTransition(info, false /* show */);
         return true;
@@ -2804,12 +2823,33 @@
 
     /** Call this when starting the open-recents animation while split-screen is active. */
     public void onRecentsInSplitAnimationStart(TransitionInfo info) {
+        if (isSplitScreenVisible()) {
+            // Cache tasks on live tile.
+            for (int i = 0; i < info.getChanges().size(); ++i) {
+                final TransitionInfo.Change change = info.getChanges().get(i);
+                if (TransitionUtil.isClosingType(change.getMode())
+                        && change.getTaskInfo() != null) {
+                    final int taskId = change.getTaskInfo().taskId;
+                    if (mMainStage.getTopVisibleChildTaskId() == taskId
+                            || mSideStage.getTopVisibleChildTaskId() == taskId) {
+                        mPausingTasks.add(taskId);
+                    }
+                }
+            }
+        }
+
         addDividerBarToTransition(info, false /* show */);
     }
 
+    /** Call this when the recents animation canceled during split-screen. */
+    public void onRecentsInSplitAnimationCanceled() {
+        mPausingTasks.clear();
+    }
+
     /** Call this when the recents animation during split-screen finishes. */
     public void onRecentsInSplitAnimationFinish(WindowContainerTransaction finishWct,
-            SurfaceControl.Transaction finishT, TransitionInfo info) {
+            SurfaceControl.Transaction finishT) {
+        mPausingTasks.clear();
         // Check if the recent transition is finished by returning to the current
         // split, so we can restore the divider bar.
         for (int i = 0; i < finishWct.getHierarchyOps().size(); ++i) {
@@ -2833,6 +2873,27 @@
         logExit(EXIT_REASON_UNKNOWN);
     }
 
+    /** Call this when the recents animation finishes by doing pair-to-pair switch. */
+    public void onRecentsPairToPairAnimationFinish(WindowContainerTransaction finishWct) {
+        // Pair-to-pair switch happened so here should evict the live tile from its stage.
+        // Otherwise, the task will remain in stage, and occluding the new task when next time
+        // user entering recents.
+        for (int i = mPausingTasks.size() - 1; i >= 0; --i) {
+            final int taskId = mPausingTasks.get(i);
+            if (mMainStage.containsTask(taskId)) {
+                mMainStage.evictChildren(finishWct, taskId);
+            } else if (mSideStage.containsTask(taskId)) {
+                mSideStage.evictChildren(finishWct, taskId);
+            }
+        }
+        // If pending enter hasn't consumed, the mix handler will invoke start pending
+        // animation within following transition.
+        if (mSplitTransitions.mPendingEnter == null) {
+            mPausingTasks.clear();
+            updateRecentTasksSplitPair();
+        }
+    }
+
     private void addDividerBarToTransition(@NonNull TransitionInfo info, boolean show) {
         final SurfaceControl leash = mSplitLayout.getDividerLeash();
         if (leash == null || !leash.isValid()) {
@@ -2885,6 +2946,9 @@
             pw.println(innerPrefix + "SplitLayout");
             mSplitLayout.dump(pw, childPrefix);
         }
+        if (!mPausingTasks.isEmpty()) {
+            pw.println(childPrefix + "mPausingTasks=" + mPausingTasks);
+        }
     }
 
     /**
@@ -2904,9 +2968,10 @@
         if (!isSplitScreenVisible()) {
             mIsDropEntering = true;
         }
-        if (!isSplitScreenVisible()) {
+        if (!isSplitScreenVisible() && !ENABLE_SHELL_TRANSITIONS) {
             // If split running background, exit split first.
-            // TODO(b/280392203) : skip doing this on shell transition once this bug is fixed.
+            // Skip this on shell transition due to we could evict existing tasks on transition
+            // finished.
             exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RECREATE_SPLIT);
         }
         mLogger.enterRequestedByDrag(position, dragSessionId);
@@ -2916,9 +2981,10 @@
      * Sets info to be logged when splitscreen is next entered.
      */
     public void onRequestToSplit(InstanceId sessionId, int enterReason) {
-        if (!isSplitScreenVisible()) {
+        if (!isSplitScreenVisible() && !ENABLE_SHELL_TRANSITIONS) {
             // If split running background, exit split first.
-            // TODO(b/280392203) : skip doing this on shell transition once this bug is fixed.
+            // Skip this on shell transition due to we could evict existing tasks on transition
+            // finished.
             exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RECREATE_SPLIT);
         }
         mLogger.enterRequested(sessionId, enterReason);
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 e2e9270..92ff5fe 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
@@ -19,6 +19,7 @@
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
 import static android.view.RemoteAnimationTarget.MODE_OPENING;
 
 import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
@@ -201,7 +202,7 @@
     public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
         if (mRootTaskInfo.taskId == taskInfo.taskId) {
             // Inflates split decor view only when the root task is visible.
-            if (mRootTaskInfo.isVisible != taskInfo.isVisible) {
+            if (!ENABLE_SHELL_TRANSITIONS && mRootTaskInfo.isVisible != taskInfo.isVisible) {
                 if (taskInfo.isVisible) {
                     mSplitDecorManager.inflate(mContext, mRootLeash,
                             taskInfo.configuration.windowConfiguration.getBounds());
@@ -376,6 +377,13 @@
         }
     }
 
+    void evictChildren(WindowContainerTransaction wct, int taskId) {
+        final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.get(taskId);
+        if (taskInfo != null) {
+            wct.reparent(taskInfo.token, null /* parent */, false /* onTop */);
+        }
+    }
+
     void reparentTopTask(WindowContainerTransaction wct) {
         wct.reparentTasks(null /* currentParent */, mRootTaskInfo.token,
                 CONTROLLED_WINDOWING_MODES, CONTROLLED_ACTIVITY_TYPES,
@@ -385,6 +393,7 @@
     void resetBounds(WindowContainerTransaction wct) {
         wct.setBounds(mRootTaskInfo.token, null);
         wct.setAppBounds(mRootTaskInfo.token, null);
+        wct.setSmallestScreenWidthDp(mRootTaskInfo.token, SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
     }
 
     void onSplitScreenListenerRegistered(SplitScreen.SplitScreenListener listener,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
index 3f944cb..0eb7c2d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
@@ -32,6 +32,7 @@
 import android.content.res.Configuration;
 import android.os.Bundle;
 import android.util.ArrayMap;
+import android.view.SurfaceControlRegistry;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
@@ -52,6 +53,7 @@
 public class ShellController {
     private static final String TAG = ShellController.class.getSimpleName();
 
+    private final Context mContext;
     private final ShellInit mShellInit;
     private final ShellCommandHandler mShellCommandHandler;
     private final ShellExecutor mMainExecutor;
@@ -72,8 +74,11 @@
     private Configuration mLastConfiguration;
 
 
-    public ShellController(ShellInit shellInit, ShellCommandHandler shellCommandHandler,
+    public ShellController(Context context,
+            ShellInit shellInit,
+            ShellCommandHandler shellCommandHandler,
             ShellExecutor mainExecutor) {
+        mContext = context;
         mShellInit = shellInit;
         mShellCommandHandler = shellCommandHandler;
         mMainExecutor = mainExecutor;
@@ -254,6 +259,16 @@
         }
     }
 
+    private void handleInit() {
+        SurfaceControlRegistry.createProcessInstance(mContext);
+        mShellInit.init();
+    }
+
+    private void handleDump(PrintWriter pw) {
+        mShellCommandHandler.dump(pw);
+        SurfaceControlRegistry.dump(100 /* limit */, false /* runGc */, pw);
+    }
+
     public void dump(@NonNull PrintWriter pw, String prefix) {
         final String innerPrefix = prefix + "  ";
         pw.println(prefix + TAG);
@@ -279,7 +294,7 @@
         @Override
         public void onInit() {
             try {
-                mMainExecutor.executeBlocking(() -> mShellInit.init());
+                mMainExecutor.executeBlocking(() -> ShellController.this.handleInit());
             } catch (InterruptedException e) {
                 throw new RuntimeException("Failed to initialize the Shell in 2s", e);
             }
@@ -344,7 +359,7 @@
         @Override
         public void dump(PrintWriter pw) {
             try {
-                mMainExecutor.executeBlocking(() -> mShellCommandHandler.dump(pw));
+                mMainExecutor.executeBlocking(() -> ShellController.this.handleDump(pw));
             } catch (InterruptedException e) {
                 throw new RuntimeException("Failed to dump the Shell in 2s", e);
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
index fe2faaf..2e7fca3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
@@ -135,6 +135,21 @@
     }
 
     /**
+     * Looks through the pending transitions for a opening transaction that matches the provided
+     * `taskView`.
+     * @param taskView the pending transition should be for this.
+     */
+    private PendingTransition findPendingOpeningTransition(TaskViewTaskController taskView) {
+        for (int i = mPending.size() - 1; i >= 0; --i) {
+            if (mPending.get(i).mTaskView != taskView) continue;
+            if (TransitionUtil.isOpeningType(mPending.get(i).mType)) {
+                return mPending.get(i);
+            }
+        }
+        return null;
+    }
+
+    /**
      * Looks through the pending transitions for one matching `taskView`.
      * @param taskView the pending transition should be for this.
      * @param type the type of transition it's looking for
@@ -149,6 +164,19 @@
         return null;
     }
 
+    /**
+     * Returns all the pending transitions for a given `taskView`.
+     * @param taskView the pending transition should be for this.
+     */
+    ArrayList<PendingTransition> findAllPending(TaskViewTaskController taskView) {
+        ArrayList<PendingTransition> list = new ArrayList<>();
+        for (int i = mPending.size() - 1; i >= 0; --i) {
+            if (mPending.get(i).mTaskView != taskView) continue;
+            list.add(mPending.get(i));
+        }
+        return list;
+    }
+
     private PendingTransition findPending(IBinder claimed) {
         for (int i = 0; i < mPending.size(); ++i) {
             if (mPending.get(i).mClaimed != claimed) continue;
@@ -249,9 +277,10 @@
             // Task view isn't visible, the bounds will next visibility update.
             return;
         }
-        if (hasPending()) {
-            // There is already a transition in-flight, the window bounds will be set in
-            // prepareOpenAnimation.
+        PendingTransition pendingOpen = findPendingOpeningTransition(taskView);
+        if (pendingOpen != null) {
+            // There is already an opening transition in-flight, the window bounds will be
+            // set in prepareOpenAnimation (via the window crop) if needed.
             return;
         }
         WindowContainerTransaction wct = new WindowContainerTransaction();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 6fa1861..64571e0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -40,6 +40,7 @@
 import android.window.WindowContainerTransactionCallback;
 
 import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
 import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.pip.phone.PipTouchHandler;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -63,6 +64,7 @@
     private PipTransitionController mPipHandler;
     private RecentsTransitionHandler mRecentsHandler;
     private StageCoordinator mSplitHandler;
+    private final KeyguardTransitionHandler mKeyguardHandler;
 
     private static class MixedTransition {
         static final int TYPE_ENTER_PIP_FROM_SPLIT = 1;
@@ -76,6 +78,9 @@
         /** Recents transition while split-screen foreground. */
         static final int TYPE_RECENTS_DURING_SPLIT = 4;
 
+        /** Keyguard exit/occlude/unocclude transition. */
+        static final int TYPE_KEYGUARD = 5;
+
         /** The default animation for this mixed transition. */
         static final int ANIM_TYPE_DEFAULT = 0;
 
@@ -126,8 +131,10 @@
     public DefaultMixedHandler(@NonNull ShellInit shellInit, @NonNull Transitions player,
             Optional<SplitScreenController> splitScreenControllerOptional,
             Optional<PipTouchHandler> pipTouchHandlerOptional,
-            Optional<RecentsTransitionHandler> recentsHandlerOptional) {
+            Optional<RecentsTransitionHandler> recentsHandlerOptional,
+            KeyguardTransitionHandler keyguardHandler) {
         mPlayer = player;
+        mKeyguardHandler = keyguardHandler;
         if (Transitions.ENABLE_SHELL_TRANSITIONS && pipTouchHandlerOptional.isPresent()
                 && splitScreenControllerOptional.isPresent()) {
             // Add after dependencies because it is higher priority
@@ -263,12 +270,26 @@
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback) {
+
         MixedTransition mixed = null;
         for (int i = mActiveTransitions.size() - 1; i >= 0; --i) {
             if (mActiveTransitions.get(i).mTransition != transition) continue;
             mixed = mActiveTransitions.get(i);
             break;
         }
+
+        // Offer Keyguard the opportunity to take over lock transitions - ideally we could know by
+        // the time of handleRequest, but we need more information than is available at that time.
+        if (KeyguardTransitionHandler.handles(info)) {
+            if (mixed != null && mixed.mType != MixedTransition.TYPE_KEYGUARD) {
+                ProtoLog.w(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
+                        "Converting mixed transition into a keyguard transition");
+                onTransitionConsumed(transition, false, null);
+            }
+            mixed = new MixedTransition(MixedTransition.TYPE_KEYGUARD, transition);
+            mActiveTransitions.add(mixed);
+        }
+
         if (mixed == null) return false;
 
         if (mixed.mType == MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT) {
@@ -282,6 +303,9 @@
         } else if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_SPLIT) {
             return animateRecentsDuringSplit(mixed, info, startTransaction, finishTransaction,
                     finishCallback);
+        } else if (mixed.mType == MixedTransition.TYPE_KEYGUARD) {
+            return animateKeyguard(mixed, info, startTransaction, finishTransaction,
+                    finishCallback);
         } else {
             mActiveTransitions.remove(mixed);
             throw new IllegalStateException("Starting mixed animation without a known mixed type? "
@@ -516,9 +540,12 @@
             mixed.mInFlightSubAnimations = 0;
             mActiveTransitions.remove(mixed);
             // If pair-to-pair switching, the post-recents clean-up isn't needed.
+            wct = wct != null ? wct : new WindowContainerTransaction();
             if (mixed.mAnimType != MixedTransition.ANIM_TYPE_PAIR_TO_PAIR) {
-                wct = wct != null ? wct : new WindowContainerTransaction();
-                mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction, info);
+                mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction);
+            } else {
+                // notify pair-to-pair recents animation finish
+                mSplitHandler.onRecentsPairToPairAnimationFinish(wct);
             }
             mSplitHandler.onTransitionAnimationComplete();
             finishCallback.onTransitionFinished(wct, wctCB);
@@ -528,11 +555,33 @@
         final boolean handled = mixed.mLeftoversHandler.startAnimation(mixed.mTransition, info,
                 startTransaction, finishTransaction, finishCB);
         if (!handled) {
+            mSplitHandler.onRecentsInSplitAnimationCanceled();
             mActiveTransitions.remove(mixed);
         }
         return handled;
     }
 
+    private boolean animateKeyguard(@NonNull final MixedTransition mixed,
+            @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction startTransaction,
+            @NonNull SurfaceControl.Transaction finishTransaction,
+            @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        boolean consumed = mKeyguardHandler.startAnimation(
+                mixed.mTransition, info, startTransaction, finishTransaction, finishCallback);
+        if (!consumed) {
+            return false;
+        }
+        // Sync pip state.
+        if (mPipHandler != null) {
+            // We don't know when to apply `startTransaction` so use a separate transaction here.
+            // This should be fine because these surface properties are independent.
+            final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+            mPipHandler.syncPipSurfaceState(info, t, finishTransaction);
+            t.apply();
+        }
+        return true;
+    }
+
     @Override
     public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
@@ -574,6 +623,8 @@
                 }
                 mixed.mLeftoversHandler.mergeAnimation(transition, info, t, mergeTarget,
                         finishCallback);
+            } else if (mixed.mType == MixedTransition.TYPE_KEYGUARD) {
+                mKeyguardHandler.mergeAnimation(transition, info, t, mergeTarget, finishCallback);
             } else {
                 throw new IllegalStateException("Playing a mixed transition with unknown type? "
                         + mixed.mType);
@@ -597,6 +648,8 @@
             mixed.mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT);
         } else if (mixed.mType == MixedTransition.TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE) {
             mixed.mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT);
+        } else if (mixed.mType == MixedTransition.TYPE_KEYGUARD) {
+            mKeyguardHandler.onTransitionConsumed(transition, aborted, finishT);
         }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index 21dca95..dc8a258 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -299,7 +299,8 @@
         }
 
         // Early check if the transition doesn't warrant an animation.
-        if (Transitions.isAllNoAnimation(info) || Transitions.isAllOrderOnly(info)) {
+        if (Transitions.isAllNoAnimation(info) || Transitions.isAllOrderOnly(info)
+                || (info.getFlags() & WindowManager.TRANSIT_FLAG_INVISIBLE) != 0) {
             startTransaction.apply();
             finishTransaction.apply();
             finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
@@ -435,6 +436,23 @@
                         backgroundColorForTransition =
                                 uiContext.getColor(R.color.overview_background);
                     }
+                    if (wallpaperTransit == WALLPAPER_TRANSITION_OPEN
+                            && TransitionUtil.isOpeningType(info.getType())) {
+                        // Need to flip the z-order of opening/closing because the WALLPAPER_OPEN
+                        // always animates the closing task over the opening one while
+                        // traditionally, an OPEN transition animates the opening over the closing.
+
+                        // See Transitions#setupAnimHierarchy for details about these variables.
+                        final int numChanges = info.getChanges().size();
+                        final int zSplitLine = numChanges + 1;
+                        if (TransitionUtil.isOpeningType(mode)) {
+                            final int layer = zSplitLine - i;
+                            startTransaction.setLayer(change.getLeash(), layer);
+                        } else if (TransitionUtil.isClosingType(mode)) {
+                            final int layer = zSplitLine + numChanges - i;
+                            startTransaction.setLayer(change.getLeash(), layer);
+                        }
+                    }
                 }
 
                 final float cornerRadius;
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 ef2a511..a242c72 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
@@ -94,8 +94,7 @@
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback) {
-        if (!Transitions.SHELL_TRANSITIONS_ROTATION && TransitionUtil.hasDisplayChange(info)
-                && !TransitionUtil.alwaysReportToKeyguard(info)) {
+        if (!Transitions.SHELL_TRANSITIONS_ROTATION && TransitionUtil.hasDisplayChange(info)) {
             // Note that if the remote doesn't have permission ACCESS_SURFACE_FLINGER, some
             // operations of the start transaction may be ignored.
             mRequestedRemotes.remove(transition);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
index 19d8384..fc301b6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
@@ -23,6 +23,7 @@
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
 import static android.view.WindowManager.transitTypeToString;
+import static android.window.TransitionInfo.FLAGS_IS_NON_APP_WINDOW;
 import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
 import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
 
@@ -150,6 +151,10 @@
                             .loadAnimationAttr(options.getPackageName(), options.getAnimations(),
                                     animAttr, translucent);
                 }
+            } else if (translucent && !isTask && ((changeFlags & FLAGS_IS_NON_APP_WINDOW) == 0)) {
+                // Un-styled translucent activities technically have undefined animations; however,
+                // as is always the case, some apps now rely on this being no-animation, so skip
+                // loading animations here.
             } else {
                 a = transitionAnimation.loadDefaultAnimationAttr(animAttr, translucent);
             }
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 ab27c55..3b306e7 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
@@ -71,6 +71,7 @@
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TransactionPool;
 import com.android.wm.shell.common.annotations.ExternalThread;
+import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellController;
@@ -190,6 +191,12 @@
      */
     private static final int SYNC_ALLOWANCE_MS = 120;
 
+    /**
+     * Keyguard gets a more generous timeout to finish its animations, because we are always holding
+     * a sleep token during occlude/unocclude transitions and we want them to finish playing cleanly
+     */
+    private static final int SYNC_ALLOWANCE_KEYGUARD_MS = 2000;
+
     /** For testing only. Disables the force-finish timeout on sync. */
     private boolean mDisableForceSync = false;
 
@@ -491,6 +498,10 @@
                 finishT.show(leash);
             } else if (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK) {
                 finishT.hide(leash);
+            } else if (isOpening && mode == TRANSIT_CHANGE) {
+                // Just in case there is a race with another animation (eg. recents finish()).
+                // Changes are visible->visible so it's a problem if it isn't visible.
+                t.show(leash);
             }
         }
     }
@@ -668,7 +679,7 @@
                 // Sleep starts a process of forcing all prior transitions to finish immediately
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
                         "Start finish-for-sync track %d", i);
-                finishForSync(i, null /* forceFinish */);
+                finishForSync(active, i, null /* forceFinish */);
             }
             if (hadPreceding) {
                 return false;
@@ -686,7 +697,11 @@
                     active.mToken, info, active.mStartT, active.mFinishT);
         }
 
-        if (info.getRootCount() == 0 && !TransitionUtil.alwaysReportToKeyguard(info)) {
+        /*
+         * Some transitions we always need to report to keyguard even if they are empty.
+         * TODO (b/274954192): Remove this once keyguard dispatching fully moves to Shell.
+         */
+        if (info.getRootCount() == 0 && !KeyguardTransitionHandler.handles(info)) {
             // No root-leashes implies that the transition is empty/no-op, so just do
             // housekeeping and return.
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "No transition roots in %s so"
@@ -1012,6 +1027,9 @@
         for (int i = 0; i < mPendingTransitions.size(); ++i) {
             if (mPendingTransitions.get(i).mToken == token) return true;
         }
+        for (int i = 0; i < mReadyDuringSync.size(); ++i) {
+            if (mReadyDuringSync.get(i).mToken == token) return true;
+        }
         for (int t = 0; t < mTracks.size(); ++t) {
             final Track tr = mTracks.get(t);
             for (int i = 0; i < tr.mReadyTransitions.size(); ++i) {
@@ -1098,10 +1116,17 @@
      *
      * This is then repeated until there are no more pending sleep transitions.
      *
+     * @param reason The SLEEP transition that triggered this round of finishes. We will continue
+     *               looping round finishing transitions as long as this is still waiting.
      * @param forceFinish When non-null, this is the transition that we last sent the SLEEP merge
      *                    signal to -- so it will be force-finished if it's still running.
      */
-    private void finishForSync(int trackIdx, @Nullable ActiveTransition forceFinish) {
+    private void finishForSync(ActiveTransition reason,
+            int trackIdx, @Nullable ActiveTransition forceFinish) {
+        if (!isTransitionKnown(reason.mToken)) {
+            Log.d(TAG, "finishForSleep: already played sync transition " + reason);
+            return;
+        }
         final Track track = mTracks.get(trackIdx);
         if (forceFinish != null) {
             final Track trk = mTracks.get(forceFinish.getTrack());
@@ -1145,8 +1170,11 @@
             if (track.mActiveTransition == playing) {
                 if (!mDisableForceSync) {
                     // Give it a short amount of time to process it before forcing.
-                    mMainExecutor.executeDelayed(() -> finishForSync(trackIdx, playing),
-                            SYNC_ALLOWANCE_MS);
+                    final int tolerance = KeyguardTransitionHandler.handles(playing.mInfo)
+                            ? SYNC_ALLOWANCE_KEYGUARD_MS
+                            : SYNC_ALLOWANCE_MS;
+                    mMainExecutor.executeDelayed(
+                            () -> finishForSync(reason, trackIdx, playing), tolerance);
                 }
                 break;
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
index 5d7b629..bb0eba6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
@@ -18,6 +18,8 @@
 
 import static android.view.WindowManager.TRANSIT_CHANGE;
 
+import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TRANSITIONS;
+
 import android.os.IBinder;
 import android.view.SurfaceControl;
 import android.window.TransitionInfo;
@@ -27,6 +29,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.common.TransactionPool;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.Transitions;
@@ -36,6 +39,7 @@
 import com.android.wm.shell.unfold.animation.FullscreenUnfoldTaskAnimator;
 import com.android.wm.shell.unfold.animation.SplitTaskUnfoldAnimator;
 import com.android.wm.shell.unfold.animation.UnfoldTaskAnimator;
+import com.android.wm.shell.util.TransitionUtil;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -105,8 +109,14 @@
             animator.clearTasks();
 
             info.getChanges().forEach(change -> {
-                if (change.getTaskInfo() != null
-                        && change.getMode() == TRANSIT_CHANGE
+                if (change.getTaskInfo() != null) {
+                    ProtoLog.v(WM_SHELL_TRANSITIONS,
+                            "startAnimation, check taskInfo: %s, mode: %s, isApplicableTask: %s",
+                            change.getTaskInfo(), TransitionInfo.modeToString(change.getMode()),
+                            animator.isApplicableTask(change.getTaskInfo()));
+                }
+                if (change.getTaskInfo() != null && (change.getMode() == TRANSIT_CHANGE
+                        || TransitionUtil.isOpeningType(change.getMode()))
                         && animator.isApplicableTask(change.getTaskInfo())) {
                     animator.onTaskAppeared(change.getTaskInfo(), change.getLeash());
                 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
index 123bf3b..a4cf149 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
@@ -213,7 +213,7 @@
     @Override
     public boolean isApplicableTask(TaskInfo taskInfo) {
         return taskInfo.hasParentTask()
-                && taskInfo.isVisible
+                && taskInfo.isRunning
                 && taskInfo.realActivity != null // to filter out parents created by organizer
                 && taskInfo.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW;
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
index 402b0ce..143b42a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
@@ -24,9 +24,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.view.WindowManager.TRANSIT_CLOSE;
-import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
-import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
@@ -85,23 +83,6 @@
         return false;
     }
 
-    /**
-     * Some transitions we always need to report to keyguard even if they are empty.
-     * TODO (b/274954192): Remove this once keyguard dispatching moves to Shell.
-     */
-    public static boolean alwaysReportToKeyguard(TransitionInfo info) {
-        // occlusion status of activities can change while screen is off so there will be no
-        // visibility change but we still need keyguardservice to be notified.
-        if (info.getType() == TRANSIT_KEYGUARD_UNOCCLUDE) return true;
-
-        // It's possible for some activities to stop with bad timing (esp. since we can't yet
-        // queue activity transitions initiated by apps) that results in an empty transition for
-        // keyguard going-away. In general, we should should always report Keyguard-going-away.
-        if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0) return true;
-
-        return false;
-    }
-
     /** Returns `true` if `change` is a wallpaper. */
     public static boolean isWallpaper(TransitionInfo.Change change) {
         return (change.getTaskInfo() == null)
@@ -195,7 +176,14 @@
         }
 
         // Put all the OPEN/SHOW on top
-        if (TransitionUtil.isOpeningType(mode)) {
+        if ((change.getFlags() & FLAG_IS_WALLPAPER) != 0) {
+            // Wallpaper is always at the bottom, opening wallpaper on top of closing one.
+            if (mode == WindowManager.TRANSIT_OPEN || mode == WindowManager.TRANSIT_TO_FRONT) {
+                t.setLayer(leash, -zSplitLine + info.getChanges().size() - layer);
+            } else {
+                t.setLayer(leash, -zSplitLine - layer);
+            }
+        } else if (TransitionUtil.isOpeningType(mode)) {
             if (isOpening) {
                 t.setLayer(leash, zSplitLine + info.getChanges().size() - layer);
                 if ((change.getFlags() & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) == 0) {
@@ -252,11 +240,20 @@
     public static RemoteAnimationTarget newTarget(TransitionInfo.Change change, int order,
             TransitionInfo info, SurfaceControl.Transaction t,
             @Nullable ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
+        return newTarget(change, order, false /* forceTranslucent */, info, t, leashMap);
+    }
+
+    /**
+     * Creates a new RemoteAnimationTarget from the provided change info
+     */
+    public static RemoteAnimationTarget newTarget(TransitionInfo.Change change, int order,
+            boolean forceTranslucent, TransitionInfo info, SurfaceControl.Transaction t,
+            @Nullable ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
         final SurfaceControl leash = createLeash(info, change, order, t);
         if (leashMap != null) {
             leashMap.put(change.getLeash(), leash);
         }
-        return newTarget(change, order, leash);
+        return newTarget(change, order, leash, forceTranslucent);
     }
 
     /**
@@ -264,6 +261,14 @@
      */
     public static RemoteAnimationTarget newTarget(TransitionInfo.Change change, int order,
             SurfaceControl leash) {
+        return newTarget(change, order, leash, false /* forceTranslucent */);
+    }
+
+    /**
+     * Creates a new RemoteAnimationTarget from the provided change and leash
+     */
+    public static RemoteAnimationTarget newTarget(TransitionInfo.Change change, int order,
+            SurfaceControl leash, boolean forceTranslucent) {
         if (isDividerBar(change)) {
             return getDividerTarget(change, leash);
         }
@@ -293,7 +298,7 @@
                 // TODO: once we can properly sync transactions across process,
                 // then get rid of this leash.
                 leash,
-                (change.getFlags() & TransitionInfo.FLAG_TRANSLUCENT) != 0,
+                forceTranslucent || (change.getFlags() & TransitionInfo.FLAG_TRANSLUCENT) != 0,
                 null,
                 // TODO(shell-transitions): we need to send content insets? evaluate how its used.
                 new Rect(0, 0, 0, 0),
@@ -312,6 +317,7 @@
         target.setWillShowImeOnTarget(
                 (change.getFlags() & TransitionInfo.FLAG_WILL_IME_SHOWN) != 0);
         target.setRotationChange(change.getEndRotation() - change.getStartRotation());
+        target.backgroundColor = change.getBackgroundColor();
         return target;
     }
 
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 54babce..9fd57d7 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
@@ -104,6 +104,7 @@
     private final InputMonitorFactory mInputMonitorFactory;
     private TaskOperations mTaskOperations;
     private final Supplier<SurfaceControl.Transaction> mTransactionFactory;
+    private final Transitions mTransitions;
 
     private Optional<SplitScreenController> mSplitScreenController;
 
@@ -118,6 +119,7 @@
             ShellTaskOrganizer taskOrganizer,
             DisplayController displayController,
             SyncTransactionQueue syncQueue,
+            Transitions transitions,
             Optional<DesktopModeController> desktopModeController,
             Optional<DesktopTasksController> desktopTasksController,
             Optional<SplitScreenController> splitScreenController) {
@@ -128,6 +130,7 @@
                 taskOrganizer,
                 displayController,
                 syncQueue,
+                transitions,
                 desktopModeController,
                 desktopTasksController,
                 splitScreenController,
@@ -144,6 +147,7 @@
             ShellTaskOrganizer taskOrganizer,
             DisplayController displayController,
             SyncTransactionQueue syncQueue,
+            Transitions transitions,
             Optional<DesktopModeController> desktopModeController,
             Optional<DesktopTasksController> desktopTasksController,
             Optional<SplitScreenController> splitScreenController,
@@ -158,6 +162,7 @@
         mDisplayController = displayController;
         mSplitScreenController = splitScreenController;
         mSyncQueue = syncQueue;
+        mTransitions = transitions;
         mDesktopModeController = desktopModeController;
         mDesktopTasksController = desktopTasksController;
 
@@ -818,7 +823,8 @@
         } else {
             windowDecoration.createResizeVeil();
             return new VeiledResizeTaskPositioner(mTaskOrganizer, windowDecoration,
-                    mDisplayController, disallowedAreaForEndBounds, mDragStartListener);
+                    mDisplayController, disallowedAreaForEndBounds, mDragStartListener,
+                    mTransitions);
         }
     }
 
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 95ed42a..ce11b26 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
@@ -296,15 +296,15 @@
     /**
      * Fade in the resize veil
      */
-    void showResizeVeil() {
-        mResizeVeil.showVeil(mTaskSurface);
+    void showResizeVeil(Rect taskBounds) {
+        mResizeVeil.showVeil(mTaskSurface, taskBounds);
     }
 
     /**
      * Set new bounds for the resize veil
      */
     void updateResizeVeil(Rect newBounds) {
-        mResizeVeil.relayout(newBounds);
+        mResizeVeil.updateResizeVeil(newBounds);
     }
 
     /**
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 4899453..8277109 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
@@ -44,7 +44,7 @@
  * Creates and updates a veil that covers task contents on resize.
  */
 public class ResizeVeil {
-    private static final int RESIZE_ALPHA_DURATION = 200;
+    private static final int RESIZE_ALPHA_DURATION = 100;
     private final Context mContext;
     private final Supplier<SurfaceControl.Builder> mSurfaceControlBuilderSupplier;
     private final Supplier<SurfaceControl.Transaction> mSurfaceControlTransactionSupplier;
@@ -104,7 +104,7 @@
     /**
      * Animate veil's alpha to 1, fading it in.
      */
-    public void showVeil(SurfaceControl parentSurface) {
+    public void showVeil(SurfaceControl parentSurface, Rect taskBounds) {
         // Parent surface can change, ensure it is up to date.
         SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
         if (!parentSurface.equals(mParentSurface)) {
@@ -115,8 +115,6 @@
         int backgroundColorId = getBackgroundColorId();
         mViewHost.getView().setBackgroundColor(mContext.getColor(backgroundColorId));
 
-        t.show(mVeilSurface)
-                .apply();
         final ValueAnimator animator = new ValueAnimator();
         animator.setFloatValues(0f, 1f);
         animator.setDuration(RESIZE_ALPHA_DURATION);
@@ -124,19 +122,32 @@
             t.setAlpha(mVeilSurface, animator.getAnimatedFraction());
             t.apply();
         });
-        animator.start();
+
+        relayout(taskBounds, t);
+        t.show(mVeilSurface)
+                .addTransactionCommittedListener(mContext.getMainExecutor(), () -> animator.start())
+                .setAlpha(mVeilSurface, 0);
+        mViewHost.getView().getViewRootImpl().applyTransactionOnDraw(t);
     }
 
     /**
      * Update veil bounds to match bounds changes.
      * @param newBounds bounds to update veil to.
      */
-    public void relayout(Rect newBounds) {
-        SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
+    private void relayout(Rect newBounds, SurfaceControl.Transaction t) {
         mViewHost.relayout(newBounds.width(), newBounds.height());
         t.setWindowCrop(mVeilSurface, newBounds.width(), newBounds.height());
         t.setPosition(mParentSurface, newBounds.left, newBounds.top);
         t.setWindowCrop(mParentSurface, newBounds.width(), newBounds.height());
+    }
+
+    /**
+     * Calls relayout to update task and veil bounds.
+     * @param newBounds bounds to update veil to.
+     */
+    public void updateResizeVeil(Rect newBounds) {
+        SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
+        relayout(newBounds, t);
         mViewHost.getView().getViewRootImpl().applyTransactionOnDraw(t);
     }
 
@@ -144,7 +155,6 @@
      * Animate veil's alpha to 0, fading it out.
      */
     public void hideVeil() {
-        final View resizeVeilView = mViewHost.getView();
         final ValueAnimator animator = new ValueAnimator();
         animator.setFloatValues(1, 0);
         animator.setDuration(RESIZE_ALPHA_DURATION);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
index 3a3ac4c..58c78e6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
@@ -16,13 +16,22 @@
 
 package com.android.wm.shell.windowdecor;
 
+import static android.view.WindowManager.TRANSIT_CHANGE;
+
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.os.IBinder;
 import android.view.SurfaceControl;
+import android.window.TransitionInfo;
+import android.window.TransitionRequestInfo;
 import android.window.WindowContainerTransaction;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.transition.Transitions;
 
 import java.util.function.Supplier;
 
@@ -32,12 +41,14 @@
  * If the drag is resizing the task, we resize the veil instead.
  * If the drag is repositioning, we update in the typical manner.
  */
-public class VeiledResizeTaskPositioner implements DragPositioningCallback {
+public class VeiledResizeTaskPositioner implements DragPositioningCallback,
+        Transitions.TransitionHandler {
 
     private DesktopModeWindowDecoration mDesktopWindowDecoration;
     private ShellTaskOrganizer mTaskOrganizer;
     private DisplayController mDisplayController;
     private DragPositioningCallbackUtility.DragStartListener mDragStartListener;
+    private final Transitions mTransitions;
     private final Rect mStableBounds = new Rect();
     private final Rect mTaskBoundsAtDragStart = new Rect();
     private final PointF mRepositionStartPoint = new PointF();
@@ -46,28 +57,29 @@
     // finalize the bounds there using WCT#setBounds
     private final Rect mDisallowedAreaForEndBounds = new Rect();
     private final Supplier<SurfaceControl.Transaction> mTransactionSupplier;
-    private boolean mHasDragResized;
     private int mCtrlType;
 
     public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer,
             DesktopModeWindowDecoration windowDecoration, DisplayController displayController,
             Rect disallowedAreaForEndBounds,
-            DragPositioningCallbackUtility.DragStartListener dragStartListener) {
+            DragPositioningCallbackUtility.DragStartListener dragStartListener,
+            Transitions transitions) {
         this(taskOrganizer, windowDecoration, displayController, disallowedAreaForEndBounds,
-                dragStartListener, SurfaceControl.Transaction::new);
+                dragStartListener, SurfaceControl.Transaction::new, transitions);
     }
 
     public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer,
             DesktopModeWindowDecoration windowDecoration, DisplayController displayController,
             Rect disallowedAreaForEndBounds,
             DragPositioningCallbackUtility.DragStartListener dragStartListener,
-            Supplier<SurfaceControl.Transaction> supplier) {
+            Supplier<SurfaceControl.Transaction> supplier, Transitions transitions) {
         mTaskOrganizer = taskOrganizer;
         mDesktopWindowDecoration = windowDecoration;
         mDisplayController = displayController;
         mDragStartListener = dragStartListener;
         mDisallowedAreaForEndBounds.set(disallowedAreaForEndBounds);
         mTransactionSupplier = supplier;
+        mTransitions = transitions;
     }
 
     @Override
@@ -77,14 +89,13 @@
                 mDesktopWindowDecoration.mTaskInfo.configuration.windowConfiguration.getBounds());
         mRepositionStartPoint.set(x, y);
         if (isResizing()) {
-            mDesktopWindowDecoration.showResizeVeil();
+            mDesktopWindowDecoration.showResizeVeil(mTaskBoundsAtDragStart);
             if (!mDesktopWindowDecoration.mTaskInfo.isFocused) {
                 WindowContainerTransaction wct = new WindowContainerTransaction();
                 wct.reorder(mDesktopWindowDecoration.mTaskInfo.token, true);
                 mTaskOrganizer.applyTransaction(wct);
             }
         }
-        mHasDragResized = false;
         mDragStartListener.onDragStart(mDesktopWindowDecoration.mTaskInfo.taskId);
         mRepositionTaskBounds.set(mTaskBoundsAtDragStart);
     }
@@ -96,7 +107,6 @@
                 mRepositionTaskBounds, mTaskBoundsAtDragStart, mStableBounds, delta,
                 mDisplayController, mDesktopWindowDecoration)) {
             mDesktopWindowDecoration.updateResizeVeil(mRepositionTaskBounds);
-            mHasDragResized = true;
         } else if (mCtrlType == CTRL_TYPE_UNDEFINED) {
             final SurfaceControl.Transaction t = mTransactionSupplier.get();
             DragPositioningCallbackUtility.setPositionOnDrag(mDesktopWindowDecoration,
@@ -111,18 +121,23 @@
         PointF delta = DragPositioningCallbackUtility.calculateDelta(x, y,
                 mRepositionStartPoint);
         if (isResizing()) {
-            if (mHasDragResized) {
+            if (!mTaskBoundsAtDragStart.equals(mRepositionTaskBounds)) {
                 DragPositioningCallbackUtility.changeBounds(
                         mCtrlType, mRepositionTaskBounds, mTaskBoundsAtDragStart, mStableBounds,
                         delta, mDisplayController, mDesktopWindowDecoration);
-                DragPositioningCallbackUtility.applyTaskBoundsChange(
-                        new WindowContainerTransaction(), mDesktopWindowDecoration,
-                        mRepositionTaskBounds, mTaskOrganizer);
+                mDesktopWindowDecoration.updateResizeVeil(mRepositionTaskBounds);
+                final WindowContainerTransaction wct = new WindowContainerTransaction();
+                wct.setBounds(mDesktopWindowDecoration.mTaskInfo.token, mRepositionTaskBounds);
+                if (Transitions.ENABLE_SHELL_TRANSITIONS) {
+                    mTransitions.startTransition(TRANSIT_CHANGE, wct, this);
+                } else {
+                    mTaskOrganizer.applyTransaction(wct);
+                }
+            } else {
+                // If bounds haven't changed, perform necessary veil reset here as startAnimation
+                // won't be called.
+                mDesktopWindowDecoration.hideResizeVeil();
             }
-            // TODO: (b/279062291) Synchronize the start of hide to the end of the draw triggered
-            //  above.
-            mDesktopWindowDecoration.updateResizeVeil(mRepositionTaskBounds);
-            mDesktopWindowDecoration.hideResizeVeil();
         } else if (!mDisallowedAreaForEndBounds.contains((int) x, (int) y)) {
             DragPositioningCallbackUtility.updateTaskBounds(mRepositionTaskBounds,
                     mTaskBoundsAtDragStart, mRepositionStartPoint, x, y);
@@ -133,7 +148,6 @@
         mCtrlType = CTRL_TYPE_UNDEFINED;
         mTaskBoundsAtDragStart.setEmpty();
         mRepositionStartPoint.set(0, 0);
-        mHasDragResized = false;
     }
 
     private boolean isResizing() {
@@ -141,4 +155,26 @@
                 || (mCtrlType & CTRL_TYPE_LEFT) != 0 || (mCtrlType & CTRL_TYPE_RIGHT) != 0;
     }
 
+    @Override
+    public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction startTransaction,
+            @NonNull SurfaceControl.Transaction finishTransaction,
+            @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        startTransaction.apply();
+        mDesktopWindowDecoration.hideResizeVeil();
+        mCtrlType = CTRL_TYPE_UNDEFINED;
+        finishCallback.onTransitionFinished(null, null);
+        return true;
+    }
+
+    /**
+     * We should never reach this as this handler's transitions are only started from shell
+     * explicitly.
+     */
+    @Nullable
+    @Override
+    public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
+            @NonNull TransitionRequestInfo request) {
+        return null;
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
index b7e73ad..72f25f3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
@@ -18,6 +18,7 @@
 
 import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.common.traces.component.EdgeExtensionComponentMatcher
@@ -60,6 +61,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
index 0b0a3da..ed3df9c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
@@ -18,6 +18,7 @@
 
 import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
@@ -58,6 +59,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
index 8cf871f..b4c6afd 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
@@ -59,6 +60,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
index 3b2da8d..2cedc35 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
@@ -18,6 +18,7 @@
 
 import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
@@ -62,6 +63,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
new file mode 100644
index 0000000..e0dbfa3
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen
+
+import android.platform.test.annotations.Postsubmit
+import android.tools.common.NavBar
+import android.tools.common.Rotation
+import android.tools.common.flicker.subject.region.RegionSubject
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.ICommonAssertions
+import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
+import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
+import com.android.wm.shell.flicker.layerIsVisibleAtEnd
+import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd
+import com.android.wm.shell.flicker.splitscreen.benchmark.UnlockKeyguardToSplitScreenBenchmark
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test unlocking insecure keyguard to back to split screen tasks and verify the transition behavior.
+ *
+ * To run this test: `atest WMShellFlickerTests:UnlockKeyguardToSplitScreen`
+ */
+@RequiresDevice
+@Postsubmit
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class UnlockKeyguardToSplitScreen(override val flicker: FlickerTest) :
+        UnlockKeyguardToSplitScreenBenchmark(flicker), ICommonAssertions {
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    @Test
+    fun splitScreenDividerIsVisibleAtEnd() {
+        flicker.assertLayersEnd { this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) }
+    }
+
+    @Test fun primaryAppLayerIsVisibleAtEnd() = flicker.layerIsVisibleAtEnd(primaryApp)
+
+    @Test
+    fun primaryAppBoundsIsVisibleAtEnd() =
+            flicker.splitAppLayerBoundsIsVisibleAtEnd(
+                    primaryApp,
+                    landscapePosLeft = false,
+                    portraitPosTop = false
+            )
+
+    @Test
+    fun secondaryAppBoundsIsVisibleAtEnd() =
+            flicker.splitAppLayerBoundsIsVisibleAtEnd(
+                    secondaryApp,
+                    landscapePosLeft = true,
+                    portraitPosTop = true
+            )
+
+    @Test
+    fun primaryAppWindowIsVisibleAtEnd() = flicker.appWindowIsVisibleAtEnd(primaryApp)
+
+    @Test
+    fun secondaryAppWindowIsVisibleAtEnd() = flicker.appWindowIsVisibleAtEnd(secondaryApp)
+
+    @Test
+    fun notOverlapsForPrimaryAndSecondaryAppLayers() {
+        flicker.assertLayers {
+            this.invoke("notOverlapsForPrimaryAndSecondaryLayers") {
+                val primaryAppRegions = it.subjects.filter { subject ->
+                    subject.name.contains(primaryApp.toLayerName()) && subject.isVisible
+                }.mapNotNull { primaryApp -> primaryApp.layer.visibleRegion }.toTypedArray()
+
+                val primaryAppRegionArea = RegionSubject(primaryAppRegions, it.timestamp)
+                it.visibleRegion(secondaryApp).notOverlaps(primaryAppRegionArea.region)
+            }
+        }
+    }
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests(
+                    // TODO(b/283963801) address entireScreenCovered test faliure in landscape.
+                    supportedRotations = listOf(Rotation.ROTATION_0),
+                    supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+            )
+        }
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
index a189a3f..a5ad97d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen.benchmark
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -62,6 +63,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
index 55ab7b3..fa6a4bf 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen.benchmark
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
@@ -68,6 +69,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
index c4cfd1a..d2beb67 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen.benchmark
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
@@ -55,6 +56,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
index 146287c..e95fd94 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen.benchmark
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
@@ -58,6 +59,7 @@
         Assume.assumeTrue(tapl.isTablet || !flicker.scenario.isLandscapeOrSeascapeAtStart)
     }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
index cc71502..63b74e2 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen.benchmark
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -70,6 +71,7 @@
         Assume.assumeTrue(tapl.isTablet)
     }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
index de78f09..e94da87 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen.benchmark
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -67,6 +68,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
index a29eb40..f41117f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen.benchmark
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -70,6 +71,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
index b2395ca..12f610b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen.benchmark
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -65,6 +66,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
index e1d85d0..77818d3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen.benchmark
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
@@ -64,6 +65,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
index ba8c460..6ff2290 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen.benchmark
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.common.Rotation
@@ -134,6 +135,7 @@
         return displayBounds.width > displayBounds.height
     }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
index bbb2edc..400adea 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen.benchmark
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -63,6 +64,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
index fa38293..1ec4340 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen.benchmark
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -61,6 +62,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
index 1064bd9..9757153 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen.benchmark
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.NavBar
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -61,6 +62,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui")
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
index 8f4393f..c19a38d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.splitscreen.benchmark
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.device.flicker.legacy.FlickerBuilder
@@ -64,6 +65,7 @@
             thisTransition(this)
         }
 
+    @PlatinumTest(focusArea = "sysui")
     @IwTest(focusArea = "sysui") @Presubmit @Test open fun cujCompleted() {}
 
     companion object {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt
new file mode 100644
index 0000000..5f16e5b
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen.benchmark
+
+import android.tools.common.NavBar
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
+import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class UnlockKeyguardToSplitScreenBenchmark(override val flicker: FlickerTest) :
+        SplitScreenBase(flicker) {
+    protected val thisTransition: FlickerBuilder.() -> Unit
+        get() = {
+            setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp) }
+            transitions {
+                device.sleep()
+                wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
+                device.wakeUp()
+                device.pressMenu()
+                wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
+            }
+        }
+
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            defaultSetup(this)
+            defaultTeardown(this)
+            thisTransition(this)
+        }
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests(
+                    supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+            )
+        }
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
index a625346..4fca8b4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
@@ -65,12 +65,14 @@
         final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
                 .addChange(createChange(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY))
                 .build();
-        doReturn(mAnimator).when(mAnimRunner).createAnimator(any(), any(), any(), any(), any());
+        doReturn(mAnimator).when(mAnimRunner).createAnimator(any(), any(), any(), any(),
+                any());
 
         mAnimRunner.startAnimation(mTransition, info, mStartTransaction, mFinishTransaction);
 
         final ArgumentCaptor<Runnable> finishCallback = ArgumentCaptor.forClass(Runnable.class);
-        verify(mAnimRunner).createAnimator(eq(info), eq(mStartTransaction), eq(mFinishTransaction),
+        verify(mAnimRunner).createAnimator(eq(info), eq(mStartTransaction),
+                eq(mFinishTransaction),
                 finishCallback.capture(), any());
         verify(mStartTransaction).apply();
         verify(mAnimator).start();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
index 4f4f356..ab1ccd4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
@@ -47,6 +47,7 @@
 
     @Mock
     ShellInit mShellInit;
+
     @Mock
     Transitions mTransitions;
     @Mock
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java
index b8f615a..ba34f1f7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingControllerTests.java
@@ -29,9 +29,13 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
+import android.animation.Animator;
+import android.animation.ValueAnimator;
 import android.graphics.Rect;
+import android.view.SurfaceControl;
 import android.window.TransitionInfo;
 
+import androidx.test.annotation.UiThreadTest;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
@@ -58,7 +62,8 @@
     @Before
     public void setup() {
         super.setUp();
-        doReturn(mAnimator).when(mAnimRunner).createAnimator(any(), any(), any(), any(), any());
+        doReturn(mAnimator).when(mAnimRunner).createAnimator(any(), any(), any(), any(),
+                any());
     }
 
     @Test
@@ -182,6 +187,44 @@
         verifyNoMoreInteractions(mFinishTransaction);
     }
 
+    @UiThreadTest
+    @Test
+    public void testMergeAnimation() {
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
+                .addChange(createEmbeddedChange(
+                        EMBEDDED_LEFT_BOUNDS, EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS))
+                .build();
+
+        final ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
+        animator.addListener(new Animator.AnimatorListener() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mController.onAnimationFinished(mTransition);
+            }
+
+            @Override
+            public void onAnimationCancel(Animator animation) {
+            }
+
+            @Override
+            public void onAnimationRepeat(Animator animation) {
+            }
+        });
+        doReturn(animator).when(mAnimRunner).createAnimator(any(), any(), any(), any(), any());
+        mController.startAnimation(mTransition, info, mStartTransaction,
+                mFinishTransaction, mFinishCallback);
+        verify(mFinishCallback, never()).onTransitionFinished(any(), any());
+        mController.mergeAnimation(mTransition, info, new SurfaceControl.Transaction(),
+                mTransition,
+                (wct, cb) -> {
+                });
+        verify(mFinishCallback).onTransitionFinished(any(), any());
+    }
+
     @Test
     public void testOnAnimationFinished() {
         // Should not call finish when there is no transition.
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/TouchTrackerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/TouchTrackerTest.java
deleted file mode 100644
index d62e660..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/TouchTrackerTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.back;
-
-import static org.junit.Assert.assertEquals;
-
-import android.window.BackEvent;
-import android.window.BackMotionEvent;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class TouchTrackerTest {
-    private static final float FAKE_THRESHOLD = 400;
-    private static final float INITIAL_X_LEFT_EDGE = 5;
-    private static final float INITIAL_X_RIGHT_EDGE = FAKE_THRESHOLD - INITIAL_X_LEFT_EDGE;
-    private TouchTracker mTouchTracker;
-
-    @Before
-    public void setUp() throws Exception {
-        mTouchTracker = new TouchTracker();
-        mTouchTracker.setProgressThreshold(FAKE_THRESHOLD);
-    }
-
-    @Test
-    public void generatesProgress_onStart() {
-        mTouchTracker.setGestureStartLocation(INITIAL_X_LEFT_EDGE, 0, BackEvent.EDGE_LEFT);
-        BackMotionEvent event = mTouchTracker.createStartEvent(null);
-        assertEquals(event.getProgress(), 0f, 0f);
-    }
-
-    @Test
-    public void generatesProgress_leftEdge() {
-        mTouchTracker.setGestureStartLocation(INITIAL_X_LEFT_EDGE, 0, BackEvent.EDGE_LEFT);
-        float touchX = 10;
-        float velocityX = 0;
-        float velocityY = 0;
-
-        // Pre-commit
-        mTouchTracker.update(touchX, 0, velocityX, velocityY);
-        assertEquals(getProgress(), (touchX - INITIAL_X_LEFT_EDGE) / FAKE_THRESHOLD, 0f);
-
-        // Post-commit
-        touchX += 100;
-        mTouchTracker.setTriggerBack(true);
-        mTouchTracker.update(touchX, 0, velocityX, velocityY);
-        assertEquals(getProgress(), (touchX - INITIAL_X_LEFT_EDGE) / FAKE_THRESHOLD, 0f);
-
-        // Cancel
-        touchX -= 10;
-        mTouchTracker.setTriggerBack(false);
-        mTouchTracker.update(touchX, 0, velocityX, velocityY);
-        assertEquals(getProgress(), 0, 0f);
-
-        // Cancel more
-        touchX -= 10;
-        mTouchTracker.update(touchX, 0, velocityX, velocityY);
-        assertEquals(getProgress(), 0, 0f);
-
-        // Restart
-        touchX += 10;
-        mTouchTracker.update(touchX, 0, velocityX, velocityY);
-        assertEquals(getProgress(), 0, 0f);
-
-        // Restarted, but pre-commit
-        float restartX = touchX;
-        touchX += 10;
-        mTouchTracker.update(touchX, 0, velocityX, velocityY);
-        assertEquals(getProgress(), (touchX - restartX) / FAKE_THRESHOLD, 0f);
-
-        // Restarted, post-commit
-        touchX += 10;
-        mTouchTracker.setTriggerBack(true);
-        mTouchTracker.update(touchX, 0, velocityX, velocityY);
-        assertEquals(getProgress(), (touchX - INITIAL_X_LEFT_EDGE) / FAKE_THRESHOLD, 0f);
-    }
-
-    @Test
-    public void generatesProgress_rightEdge() {
-        mTouchTracker.setGestureStartLocation(INITIAL_X_RIGHT_EDGE, 0, BackEvent.EDGE_RIGHT);
-        float touchX = INITIAL_X_RIGHT_EDGE - 10; // Fake right edge
-        float velocityX = 0f;
-        float velocityY = 0f;
-
-        // Pre-commit
-        mTouchTracker.update(touchX, 0, velocityX, velocityY);
-        assertEquals(getProgress(), (INITIAL_X_RIGHT_EDGE - touchX) / FAKE_THRESHOLD, 0f);
-
-        // Post-commit
-        touchX -= 100;
-        mTouchTracker.setTriggerBack(true);
-        mTouchTracker.update(touchX, 0, velocityX, velocityY);
-        assertEquals(getProgress(), (INITIAL_X_RIGHT_EDGE - touchX) / FAKE_THRESHOLD, 0f);
-
-        // Cancel
-        touchX += 10;
-        mTouchTracker.setTriggerBack(false);
-        mTouchTracker.update(touchX, 0, velocityX, velocityY);
-        assertEquals(getProgress(), 0, 0f);
-
-        // Cancel more
-        touchX += 10;
-        mTouchTracker.update(touchX, 0, velocityX, velocityY);
-        assertEquals(getProgress(), 0, 0f);
-
-        // Restart
-        touchX -= 10;
-        mTouchTracker.update(touchX, 0, velocityX, velocityY);
-        assertEquals(getProgress(), 0, 0f);
-
-        // Restarted, but pre-commit
-        float restartX = touchX;
-        touchX -= 10;
-        mTouchTracker.update(touchX, 0, velocityX, velocityY);
-        assertEquals(getProgress(), (restartX - touchX) / FAKE_THRESHOLD, 0f);
-
-        // Restarted, post-commit
-        touchX -= 10;
-        mTouchTracker.setTriggerBack(true);
-        mTouchTracker.update(touchX, 0, velocityX, velocityY);
-        assertEquals(getProgress(), (INITIAL_X_RIGHT_EDGE - touchX) / FAKE_THRESHOLD, 0f);
-    }
-
-    private float getProgress() {
-        return mTouchTracker.createProgressEvent().getProgress();
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/TouchTrackerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/TouchTrackerTest.kt
new file mode 100644
index 0000000..9088e89
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/TouchTrackerTest.kt
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.back
+
+import android.util.MathUtils
+import android.window.BackEvent
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+class TouchTrackerTest {
+    private fun linearTouchTracker(): TouchTracker = TouchTracker().apply {
+        setProgressThresholds(MAX_DISTANCE, MAX_DISTANCE, NON_LINEAR_FACTOR)
+    }
+
+    private fun nonLinearTouchTracker(): TouchTracker = TouchTracker().apply {
+        setProgressThresholds(LINEAR_DISTANCE, MAX_DISTANCE, NON_LINEAR_FACTOR)
+    }
+
+    private fun TouchTracker.assertProgress(expected: Float) {
+        val actualProgress = createProgressEvent().progress
+        assertEquals(expected, actualProgress, /* delta = */ 0f)
+    }
+
+    @Test
+    fun generatesProgress_onStart() {
+        val linearTracker = linearTouchTracker()
+        linearTracker.setGestureStartLocation(INITIAL_X_LEFT_EDGE, 0f, BackEvent.EDGE_LEFT)
+        val event = linearTracker.createStartEvent(null)
+        assertEquals(0f, event.progress, 0f)
+    }
+
+    @Test
+    fun generatesProgress_leftEdge() {
+        val linearTracker = linearTouchTracker()
+        linearTracker.setGestureStartLocation(INITIAL_X_LEFT_EDGE, 0f, BackEvent.EDGE_LEFT)
+        var touchX = 10f
+        val velocityX = 0f
+        val velocityY = 0f
+
+        // Pre-commit
+        linearTracker.update(touchX, 0f, velocityX, velocityY)
+        linearTracker.assertProgress((touchX - INITIAL_X_LEFT_EDGE) / MAX_DISTANCE)
+
+        // Post-commit
+        touchX += 100f
+        linearTracker.setTriggerBack(true)
+        linearTracker.update(touchX, 0f, velocityX, velocityY)
+        linearTracker.assertProgress((touchX - INITIAL_X_LEFT_EDGE) / MAX_DISTANCE)
+
+        // Cancel
+        touchX -= 10f
+        linearTracker.setTriggerBack(false)
+        linearTracker.update(touchX, 0f, velocityX, velocityY)
+        linearTracker.assertProgress(0f)
+
+        // Cancel more
+        touchX -= 10f
+        linearTracker.update(touchX, 0f, velocityX, velocityY)
+        linearTracker.assertProgress(0f)
+
+        // Restart
+        touchX += 10f
+        linearTracker.update(touchX, 0f, velocityX, velocityY)
+        linearTracker.assertProgress(0f)
+
+        // Restarted, but pre-commit
+        val restartX = touchX
+        touchX += 10f
+        linearTracker.update(touchX, 0f, velocityX, velocityY)
+        linearTracker.assertProgress((touchX - restartX) / MAX_DISTANCE)
+
+        // Restarted, post-commit
+        touchX += 10f
+        linearTracker.setTriggerBack(true)
+        linearTracker.update(touchX, 0f, velocityX, velocityY)
+        linearTracker.assertProgress((touchX - INITIAL_X_LEFT_EDGE) / MAX_DISTANCE)
+    }
+
+    @Test
+    fun generatesProgress_rightEdge() {
+        val linearTracker = linearTouchTracker()
+        linearTracker.setGestureStartLocation(INITIAL_X_RIGHT_EDGE, 0f, BackEvent.EDGE_RIGHT)
+        var touchX = INITIAL_X_RIGHT_EDGE - 10 // Fake right edge
+        val velocityX = 0f
+        val velocityY = 0f
+        val target = MAX_DISTANCE
+
+        // Pre-commit
+        linearTracker.update(touchX, 0f, velocityX, velocityY)
+        linearTracker.assertProgress((INITIAL_X_RIGHT_EDGE - touchX) / target)
+
+        // Post-commit
+        touchX -= 100f
+        linearTracker.setTriggerBack(true)
+        linearTracker.update(touchX, 0f, velocityX, velocityY)
+        linearTracker.assertProgress((INITIAL_X_RIGHT_EDGE - touchX) / target)
+
+        // Cancel
+        touchX += 10f
+        linearTracker.setTriggerBack(false)
+        linearTracker.update(touchX, 0f, velocityX, velocityY)
+        linearTracker.assertProgress(0f)
+
+        // Cancel more
+        touchX += 10f
+        linearTracker.update(touchX, 0f, velocityX, velocityY)
+        linearTracker.assertProgress(0f)
+
+        // Restart
+        touchX -= 10f
+        linearTracker.update(touchX, 0f, velocityX, velocityY)
+        linearTracker.assertProgress(0f)
+
+        // Restarted, but pre-commit
+        val restartX = touchX
+        touchX -= 10f
+        linearTracker.update(touchX, 0f, velocityX, velocityY)
+        linearTracker.assertProgress((restartX - touchX) / target)
+
+        // Restarted, post-commit
+        touchX -= 10f
+        linearTracker.setTriggerBack(true)
+        linearTracker.update(touchX, 0f, velocityX, velocityY)
+        linearTracker.assertProgress((INITIAL_X_RIGHT_EDGE - touchX) / target)
+    }
+
+    @Test
+    fun generatesNonLinearProgress_leftEdge() {
+        val nonLinearTracker = nonLinearTouchTracker()
+        nonLinearTracker.setGestureStartLocation(INITIAL_X_LEFT_EDGE, 0f, BackEvent.EDGE_LEFT)
+        var touchX = 10f
+        val velocityX = 0f
+        val velocityY = 0f
+        val linearTarget = LINEAR_DISTANCE + (MAX_DISTANCE - LINEAR_DISTANCE) * NON_LINEAR_FACTOR
+
+        // Pre-commit: linear progress
+        nonLinearTracker.update(touchX, 0f, velocityX, velocityY)
+        nonLinearTracker.assertProgress((touchX - INITIAL_X_LEFT_EDGE) / linearTarget)
+
+        // Post-commit: still linear progress
+        touchX += 100f
+        nonLinearTracker.setTriggerBack(true)
+        nonLinearTracker.update(touchX, 0f, velocityX, velocityY)
+        nonLinearTracker.assertProgress((touchX - INITIAL_X_LEFT_EDGE) / linearTarget)
+
+        // still linear progress
+        touchX = INITIAL_X_LEFT_EDGE + LINEAR_DISTANCE
+        nonLinearTracker.update(touchX, 0f, velocityX, velocityY)
+        nonLinearTracker.assertProgress((touchX - INITIAL_X_LEFT_EDGE) / linearTarget)
+
+        // non linear progress
+        touchX += 10
+        nonLinearTracker.update(touchX, 0f, velocityX, velocityY)
+        val nonLinearTouch = (touchX - INITIAL_X_LEFT_EDGE) - LINEAR_DISTANCE
+        val nonLinearProgress = nonLinearTouch / NON_LINEAR_DISTANCE
+        val nonLinearTarget = MathUtils.lerp(linearTarget, MAX_DISTANCE, nonLinearProgress)
+        nonLinearTracker.assertProgress((touchX - INITIAL_X_LEFT_EDGE) / nonLinearTarget)
+    }
+
+    companion object {
+        private const val MAX_DISTANCE = 500f
+        private const val LINEAR_DISTANCE = 400f
+        private const val NON_LINEAR_DISTANCE = MAX_DISTANCE - LINEAR_DISTANCE
+        private const val NON_LINEAR_FACTOR = 0.2f
+        private const val INITIAL_X_LEFT_EDGE = 5f
+        private const val INITIAL_X_RIGHT_EDGE = MAX_DISTANCE - INITIAL_X_LEFT_EDGE
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
index 9e988e8..7c1da35 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/draganddrop/DragAndDropPolicyTest.java
@@ -211,7 +211,7 @@
                 mPolicy.getTargets(mInsets), TYPE_FULLSCREEN);
 
         mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), mActivityClipData);
-        verify(mSplitScreenStarter).startIntent(any(), any(),
+        verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
                 eq(SPLIT_POSITION_UNDEFINED), any());
     }
 
@@ -223,12 +223,12 @@
                 mPolicy.getTargets(mInsets), TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT);
 
         mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_LEFT), mActivityClipData);
-        verify(mSplitScreenStarter).startIntent(any(), any(),
+        verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
                 eq(SPLIT_POSITION_TOP_OR_LEFT), any());
         reset(mSplitScreenStarter);
 
         mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_RIGHT), mActivityClipData);
-        verify(mSplitScreenStarter).startIntent(any(), any(),
+        verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
                 eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any());
     }
 
@@ -240,12 +240,12 @@
                 mPolicy.getTargets(mInsets), TYPE_SPLIT_TOP, TYPE_SPLIT_BOTTOM);
 
         mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_TOP), mActivityClipData);
-        verify(mSplitScreenStarter).startIntent(any(), any(),
+        verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
                 eq(SPLIT_POSITION_TOP_OR_LEFT), any());
         reset(mSplitScreenStarter);
 
         mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_BOTTOM), mActivityClipData);
-        verify(mSplitScreenStarter).startIntent(any(), any(),
+        verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
                 eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any());
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index 04f2c99..85167cb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -129,7 +129,7 @@
             return null;
         }).when(mMockExecutor).execute(any());
         mShellInit = spy(new ShellInit(mMockExecutor));
-        mShellController = spy(new ShellController(mShellInit, mMockShellCommandHandler,
+        mShellController = spy(new ShellController(mContext, mShellInit, mMockShellCommandHandler,
                 mMockExecutor));
         mPipController = new PipController(mContext, mShellInit, mMockShellCommandHandler,
                 mShellController, mMockDisplayController, mMockPipAnimationController,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index b542fae..2c69522 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -107,7 +107,7 @@
         mMainExecutor = new TestShellExecutor();
         when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
         mShellInit = spy(new ShellInit(mMainExecutor));
-        mShellController = spy(new ShellController(mShellInit, mShellCommandHandler,
+        mShellController = spy(new ShellController(mContext, mShellInit, mShellCommandHandler,
                 mMainExecutor));
         mRecentTasksControllerReal = new RecentTasksController(mContext, mShellInit,
                 mShellController, mShellCommandHandler, mTaskStackListener, mActivityTaskManager,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
index d0e2601..fb17d87 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
@@ -111,7 +111,7 @@
     public void setup() {
         assumeTrue(ActivityTaskManager.supportsSplitScreenMultiWindow(mContext));
         MockitoAnnotations.initMocks(this);
-        mShellController = spy(new ShellController(mShellInit, mShellCommandHandler,
+        mShellController = spy(new ShellController(mContext, mShellInit, mShellCommandHandler,
                 mMainExecutor));
         mSplitScreenController = spy(new SplitScreenController(mContext, mShellInit,
                 mShellCommandHandler, mShellController, mTaskOrganizer, mSyncQueue,
@@ -181,7 +181,8 @@
         PendingIntent pendingIntent =
                 PendingIntent.getActivity(mContext, 0, startIntent, FLAG_IMMUTABLE);
 
-        mSplitScreenController.startIntent(pendingIntent, null, SPLIT_POSITION_TOP_OR_LEFT, null);
+        mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
+                SPLIT_POSITION_TOP_OR_LEFT, null);
 
         verify(mStageCoordinator).startIntent(eq(pendingIntent), mIntentCaptor.capture(),
                 eq(SPLIT_POSITION_TOP_OR_LEFT), isNull());
@@ -200,7 +201,8 @@
                 createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent);
         doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask();
 
-        mSplitScreenController.startIntent(pendingIntent, null, SPLIT_POSITION_TOP_OR_LEFT, null);
+        mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
+                SPLIT_POSITION_TOP_OR_LEFT, null);
 
         verify(mStageCoordinator).startIntent(eq(pendingIntent), mIntentCaptor.capture(),
                 eq(SPLIT_POSITION_TOP_OR_LEFT), isNull());
@@ -221,9 +223,10 @@
         doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask();
         // Put the same component into a task in the background
         ActivityManager.RecentTaskInfo sameTaskInfo = new ActivityManager.RecentTaskInfo();
-        doReturn(sameTaskInfo).when(mRecentTasks).findTaskInBackground(any());
+        doReturn(sameTaskInfo).when(mRecentTasks).findTaskInBackground(any(), anyInt());
 
-        mSplitScreenController.startIntent(pendingIntent, null, SPLIT_POSITION_TOP_OR_LEFT, null);
+        mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
+                SPLIT_POSITION_TOP_OR_LEFT, null);
 
         verify(mSplitScreenController).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
                 isNull());
@@ -244,9 +247,10 @@
                 SPLIT_POSITION_BOTTOM_OR_RIGHT);
         // Put the same component into a task in the background
         doReturn(new ActivityManager.RecentTaskInfo()).when(mRecentTasks)
-                .findTaskInBackground(any());
+                .findTaskInBackground(any(), anyInt());
 
-        mSplitScreenController.startIntent(pendingIntent, null, SPLIT_POSITION_TOP_OR_LEFT, null);
+        mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
+                SPLIT_POSITION_TOP_OR_LEFT, null);
 
         verify(mSplitScreenController).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
                 isNull());
@@ -265,7 +269,8 @@
         doReturn(sameTaskInfo).when(mSplitScreenController).getTaskInfo(
                 SPLIT_POSITION_BOTTOM_OR_RIGHT);
 
-        mSplitScreenController.startIntent(pendingIntent, null, SPLIT_POSITION_TOP_OR_LEFT, null);
+        mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
+                SPLIT_POSITION_TOP_OR_LEFT, null);
 
         verify(mStageCoordinator).switchSplitPosition(anyString());
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
index ae69b3d..4e446c6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
@@ -44,11 +44,15 @@
 
     static SplitLayout createMockSplitLayout() {
         final Rect dividerBounds = new Rect(48, 0, 52, 100);
+        final Rect bounds1 = new Rect(0, 0, 40, 100);
+        final Rect bounds2 = new Rect(60, 0, 100, 100);
         final SurfaceControl leash = createMockSurface();
         SplitLayout out = mock(SplitLayout.class);
         doReturn(dividerBounds).when(out).getDividerBounds();
         doReturn(dividerBounds).when(out).getRefDividerBounds();
         doReturn(leash).when(out).getDividerLeash();
+        doReturn(bounds1).when(out).getBounds1();
+        doReturn(bounds2).when(out).getBounds2();
         return out;
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index de701ec..5f705d7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -42,6 +42,7 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 
 import android.annotation.NonNull;
 import android.app.ActivityManager;
@@ -72,6 +73,7 @@
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.common.split.SplitDecorManager;
 import com.android.wm.shell.common.split.SplitLayout;
 import com.android.wm.shell.transition.Transitions;
 
@@ -117,13 +119,13 @@
         doReturn(mockExecutor).when(mTransitions).getAnimExecutor();
         doReturn(mock(SurfaceControl.Transaction.class)).when(mTransactionPool).acquire();
         mSplitLayout = SplitTestUtils.createMockSplitLayout();
-        mMainStage = new MainStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
+        mMainStage = spy(new MainStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
                 StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession,
-                mIconProvider);
+                mIconProvider));
         mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
-        mSideStage = new SideStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
+        mSideStage = spy(new SideStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
                 StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession,
-                mIconProvider);
+                mIconProvider));
         mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
         mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
                 mSyncQueue, mTaskOrganizer, mMainStage, mSideStage, mDisplayController,
@@ -137,6 +139,8 @@
                 .setParentTaskId(mMainStage.mRootTaskInfo.taskId).build();
         mSideChild = new TestRunningTaskInfoBuilder()
                 .setParentTaskId(mSideStage.mRootTaskInfo.taskId).build();
+        doReturn(mock(SplitDecorManager.class)).when(mMainStage).getSplitDecorManager();
+        doReturn(mock(SplitDecorManager.class)).when(mSideStage).getSplitDecorManager();
     }
 
     @Test
@@ -182,7 +186,7 @@
         IBinder transition = mSplitScreenTransitions.startEnterTransition(
                 TRANSIT_OPEN, new WindowContainerTransaction(),
                 new RemoteTransition(testRemote, "Test"), mStageCoordinator, null, null,
-                TRANSIT_SPLIT_SCREEN_PAIR_OPEN);
+                TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
         mMainStage.onTaskAppeared(mMainChild, createMockSurface());
         mSideStage.onTaskAppeared(mSideChild, createMockSurface());
         boolean accepted = mStageCoordinator.startAnimation(transition, info,
@@ -279,7 +283,7 @@
         // Make sure it cleans-up if recents doesn't restore
         WindowContainerTransaction commitWCT = new WindowContainerTransaction();
         mStageCoordinator.onRecentsInSplitAnimationFinish(commitWCT,
-                mock(SurfaceControl.Transaction.class), mock(TransitionInfo.class));
+                mock(SurfaceControl.Transaction.class));
         assertFalse(mStageCoordinator.isSplitScreenVisible());
     }
 
@@ -318,7 +322,7 @@
         mMainStage.onTaskAppeared(mMainChild, mock(SurfaceControl.class));
         mSideStage.onTaskAppeared(mSideChild, mock(SurfaceControl.class));
         mStageCoordinator.onRecentsInSplitAnimationFinish(restoreWCT,
-                mock(SurfaceControl.Transaction.class), mock(TransitionInfo.class));
+                mock(SurfaceControl.Transaction.class));
         assertTrue(mStageCoordinator.isSplitScreenVisible());
     }
 
@@ -408,7 +412,7 @@
         IBinder enterTransit = mSplitScreenTransitions.startEnterTransition(
                 TRANSIT_OPEN, new WindowContainerTransaction(),
                 new RemoteTransition(new TestRemoteTransition(), "Test"),
-                mStageCoordinator, null, null, TRANSIT_SPLIT_SCREEN_PAIR_OPEN);
+                mStageCoordinator, null, null, TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
         mMainStage.onTaskAppeared(mMainChild, createMockSurface());
         mSideStage.onTaskAppeared(mSideChild, createMockSurface());
         mStageCoordinator.startAnimation(enterTransit, enterInfo,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index 44a0ede..66b6c62 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -68,6 +68,7 @@
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.common.split.SplitDecorManager;
 import com.android.wm.shell.common.split.SplitLayout;
 import com.android.wm.shell.splitscreen.SplitScreen.SplitScreenListener;
 import com.android.wm.shell.sysui.ShellController;
@@ -145,6 +146,8 @@
 
         mSideStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().build();
         mMainStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().build();
+        doReturn(mock(SplitDecorManager.class)).when(mMainStage).getSplitDecorManager();
+        doReturn(mock(SplitDecorManager.class)).when(mSideStage).getSplitDecorManager();
     }
 
     @Test
@@ -158,7 +161,6 @@
         verify(mStageCoordinator).prepareEnterSplitScreen(eq(wct), eq(task),
                 eq(SPLIT_POSITION_BOTTOM_OR_RIGHT));
         verify(mMainStage).reparentTopTask(eq(wct));
-        verify(mSplitLayout).resetDividerPosition();
         assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());
         assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getMainStagePosition());
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
index 8115a5d..ee9f886 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
@@ -364,6 +364,7 @@
                 1, HardwareBuffer.USAGE_CPU_READ_RARELY);
         return new TaskSnapshot(
                 System.currentTimeMillis(),
+                0 /* captureTime */,
                 new ComponentName("", ""), buffer,
                 ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
                 Surface.ROTATION_0, taskSize, contentInsets, new Rect() /* letterboxInsets */,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingWindowControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingWindowControllerTests.java
index 10dec9e..a9082a6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingWindowControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingWindowControllerTests.java
@@ -81,7 +81,7 @@
         doReturn(mock(Display.class)).when(mDisplayManager).getDisplay(anyInt());
         doReturn(mDisplayManager).when(mContext).getSystemService(eq(DisplayManager.class));
         mShellInit = spy(new ShellInit(mMainExecutor));
-        mShellController = spy(new ShellController(mShellInit, mShellCommandHandler,
+        mShellController = spy(new ShellController(mContext, mShellInit, mShellCommandHandler,
                 mMainExecutor));
         mController = new StartingWindowController(mContext, mShellInit, mShellController,
                 mTaskOrganizer, mMainExecutor, mTypeAlgorithm, mIconProvider, mTransactionPool);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java
index 8d92d08..7c520c3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/sysui/ShellControllerTest.java
@@ -78,7 +78,7 @@
         mConfigChangeListener = new TestConfigurationChangeListener();
         mUserChangeListener = new TestUserChangeListener();
         mExecutor = new TestShellExecutor();
-        mController = new ShellController(mShellInit, mShellCommandHandler, mExecutor);
+        mController = new ShellController(mContext, mShellInit, mShellCommandHandler, mExecutor);
         mController.onConfigurationChanged(getConfigurationCopy());
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java
index 9d56686..71ad0d7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java
@@ -45,6 +45,8 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.List;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -58,6 +60,12 @@
     ActivityManager.RunningTaskInfo mTaskInfo;
     @Mock
     WindowContainerToken mToken;
+    @Mock
+    TaskViewTaskController mTaskViewTaskController2;
+    @Mock
+    ActivityManager.RunningTaskInfo mTaskInfo2;
+    @Mock
+    WindowContainerToken mToken2;
 
     TaskViewTransitions mTaskViewTransitions;
 
@@ -73,10 +81,16 @@
         mTaskInfo.token = mToken;
         mTaskInfo.taskId = 314;
         mTaskInfo.taskDescription = mock(ActivityManager.TaskDescription.class);
+        when(mTaskViewTaskController.getTaskInfo()).thenReturn(mTaskInfo);
+
+        mTaskInfo2 = new ActivityManager.RunningTaskInfo();
+        mTaskInfo2.token = mToken2;
+        mTaskInfo2.taskId = 315;
+        mTaskInfo2.taskDescription = mock(ActivityManager.TaskDescription.class);
+        when(mTaskViewTaskController2.getTaskInfo()).thenReturn(mTaskInfo2);
 
         mTaskViewTransitions = spy(new TaskViewTransitions(mTransitions));
         mTaskViewTransitions.addTaskView(mTaskViewTaskController);
-        when(mTaskViewTaskController.getTaskInfo()).thenReturn(mTaskInfo);
     }
 
     @Test
@@ -119,7 +133,7 @@
     }
 
     @Test
-    public void testSetTaskBounds_taskVisibleWithPending_noTransaction() {
+    public void testSetTaskBounds_taskVisibleWithPendingOpen_noTransaction() {
         assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS);
 
         mTaskViewTransitions.setTaskViewVisible(mTaskViewTaskController, true);
@@ -135,6 +149,43 @@
     }
 
     @Test
+    public void testSetTaskBounds_taskVisibleWithPendingChange_transition() {
+        assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS);
+
+        mTaskViewTransitions.setTaskViewVisible(mTaskViewTaskController, true);
+
+        // Consume the pending transition from visibility change
+        TaskViewTransitions.PendingTransition pending =
+                mTaskViewTransitions.findPending(mTaskViewTaskController, TRANSIT_TO_FRONT);
+        assertThat(pending).isNotNull();
+        mTaskViewTransitions.startAnimation(pending.mClaimed,
+                mock(TransitionInfo.class),
+                new SurfaceControl.Transaction(),
+                new SurfaceControl.Transaction(),
+                mock(Transitions.TransitionFinishCallback.class));
+        // Verify it was consumed
+        TaskViewTransitions.PendingTransition checkPending =
+                mTaskViewTransitions.findPending(mTaskViewTaskController, TRANSIT_TO_FRONT);
+        assertThat(checkPending).isNull();
+
+        // Test that set bounds creates a new transition
+        mTaskViewTransitions.setTaskBounds(mTaskViewTaskController,
+                new Rect(0, 0, 100, 100));
+        assertThat(mTaskViewTransitions.findPending(mTaskViewTaskController, TRANSIT_CHANGE))
+                .isNotNull();
+
+        // Test that set bounds again (with different bounds) creates another transition
+        mTaskViewTransitions.setTaskBounds(mTaskViewTaskController,
+                new Rect(0, 0, 300, 200));
+        List<TaskViewTransitions.PendingTransition> pendingList =
+                mTaskViewTransitions.findAllPending(mTaskViewTaskController)
+                        .stream()
+                        .filter(pendingTransition -> pendingTransition.mType == TRANSIT_CHANGE)
+                        .toList();
+        assertThat(pendingList.size()).isEqualTo(2);
+    }
+
+    @Test
     public void testSetTaskBounds_sameBounds_noTransaction() {
         assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS);
 
@@ -161,6 +212,16 @@
                 mTaskViewTransitions.findPending(mTaskViewTaskController, TRANSIT_CHANGE);
         assertThat(pendingBounds).isNotNull();
 
+        // Test that setting same bounds with in-flight transition doesn't cause another one
+        mTaskViewTransitions.setTaskBounds(mTaskViewTaskController,
+                new Rect(0, 0, 100, 100));
+        List<TaskViewTransitions.PendingTransition> pendingList =
+                mTaskViewTransitions.findAllPending(mTaskViewTaskController)
+                        .stream()
+                        .filter(pendingTransition -> pendingTransition.mType == TRANSIT_CHANGE)
+                        .toList();
+        assertThat(pendingList.size()).isEqualTo(1);
+
         // Consume the pending bounds transaction
         mTaskViewTransitions.startAnimation(pendingBounds.mClaimed,
                 mock(TransitionInfo.class),
@@ -180,6 +241,42 @@
         assertThat(pendingBounds2).isNull();
     }
 
+
+    @Test
+    public void testSetTaskBounds_taskVisibleWithDifferentTaskViewPendingChange_transition() {
+        assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS);
+
+        mTaskViewTransitions.addTaskView(mTaskViewTaskController2);
+
+        mTaskViewTransitions.setTaskViewVisible(mTaskViewTaskController, true);
+
+        // Consume the pending transition from visibility change
+        TaskViewTransitions.PendingTransition pending =
+                mTaskViewTransitions.findPending(mTaskViewTaskController, TRANSIT_TO_FRONT);
+        assertThat(pending).isNotNull();
+        mTaskViewTransitions.startAnimation(pending.mClaimed,
+                mock(TransitionInfo.class),
+                new SurfaceControl.Transaction(),
+                new SurfaceControl.Transaction(),
+                mock(Transitions.TransitionFinishCallback.class));
+        // Verify it was consumed
+        TaskViewTransitions.PendingTransition checkPending =
+                mTaskViewTransitions.findPending(mTaskViewTaskController, TRANSIT_TO_FRONT);
+        assertThat(checkPending).isNull();
+
+        // Set the second taskview as visible & check that it has a pending transition
+        mTaskViewTransitions.setTaskViewVisible(mTaskViewTaskController2, true);
+        TaskViewTransitions.PendingTransition pending2 =
+                mTaskViewTransitions.findPending(mTaskViewTaskController2, TRANSIT_TO_FRONT);
+        assertThat(pending2).isNotNull();
+
+        // Test that set bounds on the first taskview will create a new transition
+        mTaskViewTransitions.setTaskBounds(mTaskViewTaskController,
+                new Rect(0, 0, 100, 100));
+        assertThat(mTaskViewTransitions.findPending(mTaskViewTaskController, TRANSIT_CHANGE))
+                .isNotNull();
+    }
+
     @Test
     public void testSetTaskVisibility_taskRemoved_noNPE() {
         mTaskViewTransitions.removeTaskView(mTaskViewTaskController);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java
index 4c27706..41bab95 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java
@@ -54,6 +54,7 @@
 import com.android.wm.shell.desktopmode.DesktopModeController;
 import com.android.wm.shell.desktopmode.DesktopTasksController;
 import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.transition.Transitions;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -87,6 +88,7 @@
     @Mock private DesktopTasksController mDesktopTasksController;
     @Mock private InputMonitor mInputMonitor;
     @Mock private InputManager mInputManager;
+    @Mock private Transitions mTransitions;
     @Mock private DesktopModeWindowDecorViewModel.InputMonitorFactory mMockInputMonitorFactory;
     @Mock private Supplier<SurfaceControl.Transaction> mTransactionFactory;
     @Mock private SurfaceControl.Transaction mTransaction;
@@ -106,6 +108,7 @@
                 mTaskOrganizer,
                 mDisplayController,
                 mSyncQueue,
+                mTransitions,
                 Optional.of(mDesktopModeController),
                 Optional.of(mDesktopTasksController),
                 Optional.of(mSplitScreenController),
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 445a73a..4147dd8 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
@@ -22,12 +22,14 @@
 import android.testing.AndroidTestingRunner
 import android.view.Display
 import android.view.SurfaceControl
+import android.view.WindowManager.TRANSIT_CHANGE
 import android.window.WindowContainerToken
 import androidx.test.filters.SmallTest
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayLayout
+import com.android.wm.shell.transition.Transitions
 import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT
 import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP
 import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_UNDEFINED
@@ -78,6 +80,8 @@
     private lateinit var mockTransactionFactory: Supplier<SurfaceControl.Transaction>
     @Mock
     private lateinit var mockTransaction: SurfaceControl.Transaction
+    @Mock
+    private lateinit var mockTransitions: Transitions
 
     private lateinit var taskPositioner: VeiledResizeTaskPositioner
 
@@ -92,7 +96,8 @@
                 mockDisplayController,
                 DISALLOWED_AREA_FOR_END_BOUNDS,
                 mockDragStartListener,
-                mockTransactionFactory
+                mockTransactionFactory,
+                mockTransitions
             )
 
         whenever(taskToken.asBinder()).thenReturn(taskBinder)
@@ -123,12 +128,18 @@
             STARTING_BOUNDS.left.toFloat(),
             STARTING_BOUNDS.top.toFloat()
         )
-        verify(mockDesktopWindowDecoration).showResizeVeil()
+        verify(mockDesktopWindowDecoration).showResizeVeil(STARTING_BOUNDS)
 
         taskPositioner.onDragPositioningEnd(
             STARTING_BOUNDS.left.toFloat(),
             STARTING_BOUNDS.top.toFloat()
         )
+        verify(mockTransitions, never()).startTransition(eq(TRANSIT_CHANGE), argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
+                        change.configuration.windowConfiguration.bounds == STARTING_BOUNDS}},
+            eq(taskPositioner))
         verify(mockDesktopWindowDecoration).hideResizeVeil()
     }
 
@@ -180,7 +191,7 @@
             STARTING_BOUNDS.right.toFloat(),
             STARTING_BOUNDS.top.toFloat()
         )
-        verify(mockDesktopWindowDecoration).showResizeVeil()
+        verify(mockDesktopWindowDecoration).showResizeVeil(STARTING_BOUNDS)
 
         taskPositioner.onDragPositioningMove(
             STARTING_BOUNDS.right.toFloat() + 10,
@@ -206,15 +217,12 @@
         rectAfterEnd.right += 10
         rectAfterEnd.top += 10
         verify(mockDesktopWindowDecoration, times(2)).updateResizeVeil(any())
-        verify(mockDesktopWindowDecoration).hideResizeVeil()
-
-        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
+        verify(mockTransitions).startTransition(eq(TRANSIT_CHANGE), argThat { wct ->
             return@argThat wct.changes.any { (token, change) ->
                 token == taskBinder &&
                         (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
-                        change.configuration.windowConfiguration.bounds == rectAfterEnd
-            }
-        })
+                        change.configuration.windowConfiguration.bounds == rectAfterEnd}},
+            eq(taskPositioner))
     }
 
     @Test
@@ -224,7 +232,7 @@
             STARTING_BOUNDS.left.toFloat(),
             STARTING_BOUNDS.top.toFloat()
         )
-        verify(mockDesktopWindowDecoration).showResizeVeil()
+        verify(mockDesktopWindowDecoration).showResizeVeil(STARTING_BOUNDS)
 
         taskPositioner.onDragPositioningMove(
             STARTING_BOUNDS.left.toFloat(),
@@ -235,7 +243,13 @@
             STARTING_BOUNDS.left.toFloat() + 10,
             STARTING_BOUNDS.top.toFloat() + 10
         )
-        verify(mockDesktopWindowDecoration).hideResizeVeil()
+
+        verify(mockTransitions, never()).startTransition(eq(TRANSIT_CHANGE), argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        (change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0 &&
+                        change.configuration.windowConfiguration.bounds == STARTING_BOUNDS}},
+            eq(taskPositioner))
 
         verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
             return@argThat wct.changes.any { (token, change) ->
diff --git a/libs/hwui/MemoryPolicy.h b/libs/hwui/MemoryPolicy.h
index 139cdde..347daf34 100644
--- a/libs/hwui/MemoryPolicy.h
+++ b/libs/hwui/MemoryPolicy.h
@@ -31,6 +31,12 @@
     RUNNING_MODERATE = 5,
 };
 
+enum class CacheTrimLevel {
+    ALL_CACHES = 0,
+    FONT_CACHE = 1,
+    RESOURCE_CACHE = 2,
+};
+
 struct MemoryPolicy {
     // The initial scale factor applied to the display resolution. The default is 1, but
     // lower values may be used to start with a smaller initial cache size. The cache will
diff --git a/libs/hwui/jni/BitmapFactory.cpp b/libs/hwui/jni/BitmapFactory.cpp
index 38d17de..8abcd9a 100644
--- a/libs/hwui/jni/BitmapFactory.cpp
+++ b/libs/hwui/jni/BitmapFactory.cpp
@@ -194,7 +194,11 @@
         ALOGE("Can not create a codec for Gainmap.");
         return false;
     }
-    SkColorType decodeColorType = codec->computeOutputColorType(kN32_SkColorType);
+    SkColorType decodeColorType = kN32_SkColorType;
+    if (codec->getInfo().colorType() == kGray_8_SkColorType) {
+        decodeColorType = kGray_8_SkColorType;
+    }
+    decodeColorType = codec->computeOutputColorType(decodeColorType);
     sk_sp<SkColorSpace> decodeColorSpace = codec->computeOutputColorSpace(decodeColorType, nullptr);
 
     SkISize size = codec->getSampledDimensions(sampleSize);
@@ -217,7 +221,11 @@
     const SkImageInfo decodeInfo = SkImageInfo::Make(size.width(), size.height(), decodeColorType,
                                                      alphaType, decodeColorSpace);
 
-    const SkImageInfo& bitmapInfo = decodeInfo;
+    SkImageInfo bitmapInfo = decodeInfo;
+    if (decodeColorType == kGray_8_SkColorType) {
+        // We treat gray8 as alpha8 in Bitmap's API surface
+        bitmapInfo = bitmapInfo.makeColorType(kAlpha_8_SkColorType);
+    }
     SkBitmap decodeBitmap;
     sk_sp<Bitmap> nativeBitmap = nullptr;
 
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index 6a7411f..d04de37 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -362,6 +362,10 @@
     RenderProxy::trimMemory(level);
 }
 
+static void android_view_ThreadedRenderer_trimCaches(JNIEnv* env, jobject clazz, jint level) {
+    RenderProxy::trimCaches(level);
+}
+
 static void android_view_ThreadedRenderer_overrideProperty(JNIEnv* env, jobject clazz,
         jstring name, jstring value) {
     const char* nameCharArray = env->GetStringUTFChars(name, NULL);
@@ -1018,6 +1022,7 @@
          (void*)android_view_ThreadedRenderer_notifyCallbackPending},
         {"nNotifyExpensiveFrame", "(J)V",
          (void*)android_view_ThreadedRenderer_notifyExpensiveFrame},
+        {"nTrimCaches", "(I)V", (void*)android_view_ThreadedRenderer_trimCaches},
 };
 
 static JavaVM* mJvm = nullptr;
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
index c58ba68..8d5967b 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
@@ -27,6 +27,7 @@
 #include "include/gpu/GpuTypes.h" // from Skia
 #include "utils/GLUtils.h"
 #include <effects/GainmapRenderer.h>
+#include "renderthread/CanvasContext.h"
 
 namespace android {
 namespace uirenderer {
@@ -131,6 +132,8 @@
     mat4.getColMajor(&info.transform[0]);
     info.color_space_ptr = canvas->imageInfo().colorSpace();
     info.currentHdrSdrRatio = getTargetHdrSdrRatio(info.color_space_ptr);
+    info.fboColorType = canvas->imageInfo().colorType();
+    info.shouldDither = renderthread::CanvasContext::shouldDither();
 
     // ensure that the framebuffer that the webview will render into is bound before we clear
     // the stencil and/or draw the functor.
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
index e299d12..b62711f 100644
--- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
@@ -15,22 +15,25 @@
  */
 
 #include "VkFunctorDrawable.h"
-#include <private/hwui/DrawVkInfo.h>
 
 #include <GrBackendDrawableInfo.h>
 #include <SkAndroidFrameworkUtils.h>
 #include <SkImage.h>
 #include <SkM44.h>
 #include <gui/TraceUtils.h>
+#include <private/hwui/DrawVkInfo.h>
 #include <utils/Color.h>
 #include <utils/Trace.h>
 #include <vk/GrVkTypes.h>
+
 #include <thread>
+
+#include "effects/GainmapRenderer.h"
+#include "renderthread/CanvasContext.h"
 #include "renderthread/RenderThread.h"
 #include "renderthread/VulkanManager.h"
 #include "thread/ThreadBase.h"
 #include "utils/TimeUtils.h"
-#include "effects/GainmapRenderer.h"
 
 namespace android {
 namespace uirenderer {
@@ -75,6 +78,7 @@
             .clip_bottom = mClip.fBottom,
             .is_layer = !vulkan_info.fFromSwapchainOrAndroidWindow,
             .currentHdrSdrRatio = getTargetHdrSdrRatio(mImageInfo.colorSpace()),
+            .shouldDither = renderthread::CanvasContext::shouldDither(),
     };
     mat4.getColMajor(&params.transform[0]);
     params.secondary_command_buffer = vulkan_info.fSecondaryCommandBuffer;
diff --git a/libs/hwui/private/hwui/DrawGlInfo.h b/libs/hwui/private/hwui/DrawGlInfo.h
index 7888c87..eb1f930 100644
--- a/libs/hwui/private/hwui/DrawGlInfo.h
+++ b/libs/hwui/private/hwui/DrawGlInfo.h
@@ -18,6 +18,7 @@
 #define ANDROID_HWUI_DRAW_GL_INFO_H
 
 #include <SkColorSpace.h>
+#include <SkColorType.h>
 
 namespace android {
 namespace uirenderer {
@@ -91,6 +92,12 @@
     // be baked into the color_space_ptr, so this is just to indicate the amount of extended
     // range is available if desired
     float currentHdrSdrRatio;
+
+    // Whether or not dithering is globally enabled
+    bool shouldDither;
+
+    // The color type of the destination framebuffer
+    SkColorType fboColorType;
 };  // struct DrawGlInfo
 
 }  // namespace uirenderer
diff --git a/libs/hwui/private/hwui/DrawVkInfo.h b/libs/hwui/private/hwui/DrawVkInfo.h
index 8f7063d..1220806 100644
--- a/libs/hwui/private/hwui/DrawVkInfo.h
+++ b/libs/hwui/private/hwui/DrawVkInfo.h
@@ -76,6 +76,9 @@
   // be baked into the color_space_ptr, so this is just to indicate the amount of extended
   // range is available if desired
   float currentHdrSdrRatio;
+
+  // Whether or not dithering is globally enabled
+  bool shouldDither;
 };
 
 }  // namespace uirenderer
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index c00a270..babce88 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -139,6 +139,25 @@
     }
 }
 
+void CacheManager::trimCaches(CacheTrimLevel mode) {
+    switch (mode) {
+        case CacheTrimLevel::FONT_CACHE:
+            SkGraphics::PurgeFontCache();
+            break;
+        case CacheTrimLevel::RESOURCE_CACHE:
+            SkGraphics::PurgeResourceCache();
+            break;
+        case CacheTrimLevel::ALL_CACHES:
+            SkGraphics::PurgeAllCaches();
+            if (mGrContext) {
+                mGrContext->purgeUnlockedResources(false);
+            }
+            break;
+        default:
+            break;
+    }
+}
+
 void CacheManager::trimStaleResources() {
     if (!mGrContext) {
         return;
diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h
index d21ac9b..5e43ac2 100644
--- a/libs/hwui/renderthread/CacheManager.h
+++ b/libs/hwui/renderthread/CacheManager.h
@@ -48,6 +48,7 @@
     void configureContext(GrContextOptions* context, const void* identity, ssize_t size);
 #endif
     void trimMemory(TrimLevel mode);
+    void trimCaches(CacheTrimLevel mode);
     void trimStaleResources();
     void dumpMemoryUsage(String8& log, const RenderState* renderState = nullptr);
     void getMemoryUsage(size_t* cpuUsage, size_t* gpuUsage);
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 2bd400d..16b35ff 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -1078,6 +1078,12 @@
     mHintSessionWrapper.init();
 }
 
+bool CanvasContext::shouldDither() {
+    CanvasContext* self = getActiveContext();
+    if (!self) return false;
+    return self->mColorMode != ColorMode::Default;
+}
+
 } /* namespace renderthread */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 08e2424..5219b57 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -234,6 +234,8 @@
 
     void startHintSession();
 
+    static bool shouldDither();
+
 private:
     CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
                   IContextFactory* contextFactory, std::unique_ptr<IRenderPipeline> renderPipeline,
diff --git a/libs/hwui/renderthread/HintSessionWrapper.cpp b/libs/hwui/renderthread/HintSessionWrapper.cpp
index 597cbf7..814ac4d 100644
--- a/libs/hwui/renderthread/HintSessionWrapper.cpp
+++ b/libs/hwui/renderthread/HintSessionWrapper.cpp
@@ -156,6 +156,7 @@
 
 void HintSessionWrapper::reportActualWorkDuration(long actualDurationNanos) {
     if (!init()) return;
+    mResetsSinceLastReport = 0;
     if (actualDurationNanos > kSanityCheckLowerBound &&
         actualDurationNanos < kSanityCheckUpperBound) {
         gAPH_reportActualWorkDurationFn(mHintSession, actualDurationNanos);
@@ -163,9 +164,12 @@
 }
 
 void HintSessionWrapper::sendLoadResetHint() {
+    static constexpr int kMaxResetsSinceLastReport = 2;
     if (!init()) return;
     nsecs_t now = systemTime();
-    if (now - mLastFrameNotification > kResetHintTimeout) {
+    if (now - mLastFrameNotification > kResetHintTimeout &&
+        mResetsSinceLastReport <= kMaxResetsSinceLastReport) {
+        ++mResetsSinceLastReport;
         gAPH_sendHintFn(mHintSession, static_cast<int>(SessionHint::CPU_LOAD_RESET));
     }
     mLastFrameNotification = now;
diff --git a/libs/hwui/renderthread/HintSessionWrapper.h b/libs/hwui/renderthread/HintSessionWrapper.h
index b7a433f..24b8150 100644
--- a/libs/hwui/renderthread/HintSessionWrapper.h
+++ b/libs/hwui/renderthread/HintSessionWrapper.h
@@ -42,6 +42,7 @@
     APerformanceHintSession* mHintSession = nullptr;
     std::future<APerformanceHintSession*> mHintSessionFuture;
 
+    int mResetsSinceLastReport = 0;
     nsecs_t mLastFrameNotification = 0;
     nsecs_t mLastTargetWorkDuration = 0;
 
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 31b4b20..224c878 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -231,6 +231,15 @@
     }
 }
 
+void RenderProxy::trimCaches(int level) {
+    // Avoid creating a RenderThread to do a trimMemory.
+    if (RenderThread::hasInstance()) {
+        RenderThread& thread = RenderThread::getInstance();
+        const auto trimLevel = static_cast<CacheTrimLevel>(level);
+        thread.queue().post([&thread, trimLevel]() { thread.trimCaches(trimLevel); });
+    }
+}
+
 void RenderProxy::purgeCaches() {
     if (RenderThread::hasInstance()) {
         RenderThread& thread = RenderThread::getInstance();
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 82072a6..47c1b0c 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -105,6 +105,7 @@
 
     void destroyHardwareResources();
     static void trimMemory(int level);
+    static void trimCaches(int level);
     static void purgeCaches();
     static void overrideProperty(const char* name, const char* value);
 
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 9ba67a2..eb28c08 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -521,6 +521,11 @@
     cacheManager().trimMemory(level);
 }
 
+void RenderThread::trimCaches(CacheTrimLevel level) {
+    ATRACE_CALL();
+    cacheManager().trimCaches(level);
+}
+
 } /* namespace renderthread */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index c77cd41..79e57de 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -174,6 +174,7 @@
     }
 
     void trimMemory(TrimLevel level);
+    void trimCaches(CacheTrimLevel level);
 
     /**
      * isCurrent provides a way to query, if the caller is running on
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index b1d2e33..4759689 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3730,7 +3730,12 @@
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @RequiresPermission(Manifest.permission.BLUETOOTH_STACK)
     public void setA2dpSuspended(boolean enable) {
-        AudioSystem.setParameters("A2dpSuspended=" + enable);
+        final IAudioService service = getService();
+        try {
+            service.setA2dpSuspended(enable);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     /**
@@ -3743,7 +3748,12 @@
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @RequiresPermission(Manifest.permission.BLUETOOTH_STACK)
     public void setLeAudioSuspended(boolean enable) {
-        AudioSystem.setParameters("LeAudioSuspended=" + enable);
+        final IAudioService service = getService();
+        try {
+            service.setLeAudioSuspended(enable);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     /**
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index fe5afc5..7ce189b 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -231,6 +231,12 @@
 
     void setBluetoothScoOn(boolean on);
 
+    @EnforcePermission("BLUETOOTH_STACK")
+    void setA2dpSuspended(boolean on);
+
+    @EnforcePermission("BLUETOOTH_STACK")
+    void setLeAudioSuspended(boolean enable);
+
     boolean isBluetoothScoOn();
 
     void setBluetoothA2dpOn(boolean on);
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 2541a506..32680da 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -3181,7 +3181,10 @@
                 mValid = false;
                 mNativeContext = 0;
             }
-            sPool.offer(this);
+
+            if (!mInternal) {
+                sPool.offer(this);
+            }
         }
 
         private native void native_recycle();
@@ -3245,6 +3248,7 @@
             mNativeContext = context;
             mMappable = isMappable;
             mValid = (context != 0);
+            mInternal = true;
         }
 
         private static final BlockingQueue<LinearBlock> sPool =
@@ -3255,6 +3259,7 @@
         private boolean mMappable = false;
         private ByteBuffer mMapped = null;
         private long mNativeContext = 0;
+        private boolean mInternal = false;
     }
 
     /**
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index 7e238e4..0e9c162 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -57,6 +57,30 @@
         }
     };
 
+    /**
+     * The {@link #getOriginalId() original id} of the route that represents the built-in media
+     * route.
+     *
+     * <p>A route with this id will only be visible to apps with permission to do system routing,
+     * which means having {@link android.Manifest.permission#BLUETOOTH_CONNECT} and {@link
+     * android.Manifest.permission#BLUETOOTH_SCAN}, or {@link
+     * android.Manifest.permission#MODIFY_AUDIO_ROUTING}.
+     *
+     * @hide
+     */
+    public static final String ROUTE_ID_DEVICE = "DEVICE_ROUTE";
+
+    /**
+     * The {@link #getOriginalId() original id} of the route that represents the default system
+     * media route.
+     *
+     * <p>A route with this id will be visible to apps with no permission over system routing. See
+     * {@link #ROUTE_ID_DEVICE} for details.
+     *
+     * @hide
+     */
+    public static final String ROUTE_ID_DEFAULT = "DEFAULT_ROUTE";
+
     /** @hide */
     @IntDef({CONNECTION_STATE_DISCONNECTED, CONNECTION_STATE_CONNECTING,
             CONNECTION_STATE_CONNECTED})
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 6f67d68..1b04f18 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -372,13 +372,12 @@
 void LnbClientCallbackImpl::onEvent(const LnbEventType lnbEventType) {
     ALOGV("LnbClientCallbackImpl::onEvent, type=%d", lnbEventType);
     JNIEnv *env = AndroidRuntime::getJNIEnv();
-    jobject lnb(env->NewLocalRef(mLnbObj));
-    if (!env->IsSameObject(lnb, nullptr)) {
+    ScopedLocalRef lnb(env, env->NewLocalRef(mLnbObj));
+    if (!env->IsSameObject(lnb.get(), nullptr)) {
         env->CallVoidMethod(
-                lnb,
+                lnb.get(),
                 gFields.onLnbEventID,
                 (jint)lnbEventType);
-        env->DeleteLocalRef(lnb);
     } else {
         ALOGE("LnbClientCallbackImpl::onEvent:"
                 "Lnb object has been freed. Ignoring callback.");
@@ -388,17 +387,15 @@
 void LnbClientCallbackImpl::onDiseqcMessage(const vector<uint8_t> &diseqcMessage) {
     ALOGV("LnbClientCallbackImpl::onDiseqcMessage");
     JNIEnv *env = AndroidRuntime::getJNIEnv();
-    jobject lnb(env->NewLocalRef(mLnbObj));
-    if (!env->IsSameObject(lnb, nullptr)) {
-        jbyteArray array = env->NewByteArray(diseqcMessage.size());
-        env->SetByteArrayRegion(array, 0, diseqcMessage.size(),
+    ScopedLocalRef lnb(env, env->NewLocalRef(mLnbObj));
+    if (!env->IsSameObject(lnb.get(), nullptr)) {
+        ScopedLocalRef array(env, env->NewByteArray(diseqcMessage.size()));
+        env->SetByteArrayRegion(array.get(), 0, diseqcMessage.size(),
                                 reinterpret_cast<const jbyte *>(&diseqcMessage[0]));
         env->CallVoidMethod(
-                lnb,
+                lnb.get(),
                 gFields.onLnbDiseqcMessageID,
-                array);
-        env->DeleteLocalRef(lnb);
-        env->DeleteLocalRef(array);
+                array.get());
     } else {
         ALOGE("LnbClientCallbackImpl::onDiseqcMessage:"
                 "Lnb object has been freed. Ignoring callback.");
@@ -422,10 +419,9 @@
 void DvrClientCallbackImpl::onRecordStatus(RecordStatus status) {
     ALOGV("DvrClientCallbackImpl::onRecordStatus");
     JNIEnv *env = AndroidRuntime::getJNIEnv();
-    jobject dvr(env->NewLocalRef(mDvrObj));
-    if (!env->IsSameObject(dvr, nullptr)) {
-        env->CallVoidMethod(dvr, gFields.onDvrRecordStatusID, (jint)status);
-        env->DeleteLocalRef(dvr);
+    ScopedLocalRef dvr(env, env->NewLocalRef(mDvrObj));
+    if (!env->IsSameObject(dvr.get(), nullptr)) {
+        env->CallVoidMethod(dvr.get(), gFields.onDvrRecordStatusID, (jint)status);
     } else {
         ALOGE("DvrClientCallbackImpl::onRecordStatus:"
                 "Dvr object has been freed. Ignoring callback.");
@@ -435,10 +431,9 @@
 void DvrClientCallbackImpl::onPlaybackStatus(PlaybackStatus status) {
     ALOGV("DvrClientCallbackImpl::onPlaybackStatus");
     JNIEnv *env = AndroidRuntime::getJNIEnv();
-    jobject dvr(env->NewLocalRef(mDvrObj));
-    if (!env->IsSameObject(dvr, nullptr)) {
-        env->CallVoidMethod(dvr, gFields.onDvrPlaybackStatusID, (jint)status);
-        env->DeleteLocalRef(dvr);
+    ScopedLocalRef dvr(env, env->NewLocalRef(mDvrObj));
+    if (!env->IsSameObject(dvr.get(), nullptr)) {
+        env->CallVoidMethod(dvr.get(), gFields.onDvrPlaybackStatusID, (jint)status);
     } else {
         ALOGE("DvrClientCallbackImpl::onPlaybackStatus:"
                 "Dvr object has been freed. Ignoring callback.");
@@ -614,7 +609,7 @@
 }
 
 /////////////// FilterClientCallbackImpl ///////////////////////
-void FilterClientCallbackImpl::getSectionEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getSectionEvent(const jobjectArray& arr, const int size,
                                                const DemuxFilterEvent &event) {
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
@@ -624,20 +619,20 @@
     jint sectionNum = sectionEvent.sectionNum;
     jlong dataLength = sectionEvent.dataLength;
 
-    jobject obj = env->NewObject(mSectionEventClass, mSectionEventInitID, tableId, version,
-                                 sectionNum, dataLength);
-    env->SetObjectArrayElement(arr, size, obj);
-    env->DeleteLocalRef(obj);
+    ScopedLocalRef obj(env, env->NewObject(mSectionEventClass, mSectionEventInitID, tableId,
+                                           version, sectionNum, dataLength));
+    env->SetObjectArrayElement(arr, size, obj.get());
 }
 
-void FilterClientCallbackImpl::getMediaEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getMediaEvent(const jobjectArray& arr, const int size,
                                              const DemuxFilterEvent &event) {
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
     const DemuxFilterMediaEvent &mediaEvent = event.get<DemuxFilterEvent::Tag::media>();
-    jobject audioDescriptor = nullptr;
+    ScopedLocalRef<jobject> audioDescriptor(env);
     gAudioPresentationFields.init(env);
-    jobject presentationsJObj = JAudioPresentationInfo::asJobject(env, gAudioPresentationFields);
+    ScopedLocalRef presentationsJObj(env, JAudioPresentationInfo::asJobject(
+        env, gAudioPresentationFields));
     switch (mediaEvent.extraMetaData.getTag()) {
         case DemuxFilterMediaEventExtraMetaData::Tag::audio: {
 
@@ -650,9 +645,9 @@
             jbyte adGainFront = ad.adGainFront;
             jbyte adGainSurround = ad.adGainSurround;
 
-            audioDescriptor = env->NewObject(mAudioDescriptorClass, mAudioDescriptorInitID, adFade,
-                                             adPan, versionTextTag, adGainCenter, adGainFront,
-                                             adGainSurround);
+            audioDescriptor.reset(env->NewObject(mAudioDescriptorClass, mAudioDescriptorInitID,
+                                                 adFade, adPan, versionTextTag, adGainCenter,
+                                                 adGainFront, adGainSurround));
             break;
         }
         case DemuxFilterMediaEventExtraMetaData::Tag::audioPresentations: {
@@ -660,7 +655,7 @@
                     env, gAudioPresentationFields,
                     mediaEvent.extraMetaData
                             .get<DemuxFilterMediaEventExtraMetaData::Tag::audioPresentations>(),
-                    presentationsJObj);
+                    presentationsJObj.get());
             break;
         }
         default: {
@@ -693,31 +688,27 @@
         sc = mediaEvent.scIndexMask.get<DemuxFilterScIndexMask::Tag::scVvc>();
     }
 
-    jobject obj = env->NewObject(mMediaEventClass, mMediaEventInitID, streamId, isPtsPresent, pts,
-                                 isDtsPresent, dts, dataLength, offset, nullptr, isSecureMemory,
-                                 avDataId, mpuSequenceNumber, isPesPrivateData, sc,
-                                 audioDescriptor, presentationsJObj);
+    ScopedLocalRef obj(env, env->NewObject(mMediaEventClass, mMediaEventInitID, streamId,
+                                           isPtsPresent, pts, isDtsPresent, dts, dataLength,
+                                           offset, nullptr, isSecureMemory, avDataId,
+                                           mpuSequenceNumber, isPesPrivateData, sc,
+                                           audioDescriptor.get(), presentationsJObj.get()));
 
     uint64_t avSharedMemSize = mFilterClient->getAvSharedHandleInfo().size;
     if (mediaEvent.avMemory.fds.size() > 0 || mediaEvent.avDataId != 0 ||
         (dataLength > 0 && (dataLength + offset) < avSharedMemSize)) {
         sp<MediaEvent> mediaEventSp =
                 new MediaEvent(mFilterClient, dupFromAidl(mediaEvent.avMemory),
-                               mediaEvent.avDataId, dataLength + offset, obj);
+                               mediaEvent.avDataId, dataLength + offset, obj.get());
         mediaEventSp->mAvHandleRefCnt++;
-        env->SetLongField(obj, mMediaEventFieldContextID, (jlong)mediaEventSp.get());
-        mediaEventSp->incStrong(obj);
+        env->SetLongField(obj.get(), mMediaEventFieldContextID, (jlong)mediaEventSp.get());
+        mediaEventSp->incStrong(obj.get());
     }
 
-    env->SetObjectArrayElement(arr, size, obj);
-    if(audioDescriptor != nullptr) {
-        env->DeleteLocalRef(audioDescriptor);
-    }
-    env->DeleteLocalRef(obj);
-    env->DeleteLocalRef(presentationsJObj);
+    env->SetObjectArrayElement(arr, size, obj.get());
 }
 
-void FilterClientCallbackImpl::getPesEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getPesEvent(const jobjectArray& arr, const int size,
                                            const DemuxFilterEvent &event) {
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
@@ -726,13 +717,12 @@
     jint dataLength = pesEvent.dataLength;
     jint mpuSequenceNumber = pesEvent.mpuSequenceNumber;
 
-    jobject obj = env->NewObject(mPesEventClass, mPesEventInitID, streamId, dataLength,
-                                 mpuSequenceNumber);
-    env->SetObjectArrayElement(arr, size, obj);
-    env->DeleteLocalRef(obj);
+    ScopedLocalRef obj(env, env->NewObject(mPesEventClass, mPesEventInitID, streamId, dataLength,
+                                 mpuSequenceNumber));
+    env->SetObjectArrayElement(arr, size, obj.get());
 }
 
-void FilterClientCallbackImpl::getTsRecordEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getTsRecordEvent(const jobjectArray& arr, const int size,
                                                 const DemuxFilterEvent &event) {
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
@@ -764,13 +754,12 @@
     jlong pts = tsRecordEvent.pts;
     jint firstMbInSlice = tsRecordEvent.firstMbInSlice;
 
-    jobject obj = env->NewObject(mTsRecordEventClass, mTsRecordEventInitID, jpid, ts, sc,
-                                 byteNumber, pts, firstMbInSlice);
-    env->SetObjectArrayElement(arr, size, obj);
-    env->DeleteLocalRef(obj);
+    ScopedLocalRef obj(env, env->NewObject(mTsRecordEventClass, mTsRecordEventInitID, jpid, ts, sc,
+                                 byteNumber, pts, firstMbInSlice));
+    env->SetObjectArrayElement(arr, size, obj.get());
 }
 
-void FilterClientCallbackImpl::getMmtpRecordEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getMmtpRecordEvent(const jobjectArray& arr, const int size,
                                                   const DemuxFilterEvent &event) {
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
@@ -783,13 +772,13 @@
     jint firstMbInSlice = mmtpRecordEvent.firstMbInSlice;
     jlong tsIndexMask = mmtpRecordEvent.tsIndexMask;
 
-    jobject obj = env->NewObject(mMmtpRecordEventClass, mMmtpRecordEventInitID, scHevcIndexMask,
-                                 byteNumber, mpuSequenceNumber, pts, firstMbInSlice, tsIndexMask);
-    env->SetObjectArrayElement(arr, size, obj);
-    env->DeleteLocalRef(obj);
+    ScopedLocalRef obj(env, env->NewObject(mMmtpRecordEventClass, mMmtpRecordEventInitID,
+                                           scHevcIndexMask, byteNumber, mpuSequenceNumber, pts,
+                                           firstMbInSlice, tsIndexMask));
+    env->SetObjectArrayElement(arr, size, obj.get());
 }
 
-void FilterClientCallbackImpl::getDownloadEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getDownloadEvent(const jobjectArray& arr, const int size,
                                                 const DemuxFilterEvent &event) {
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
@@ -801,25 +790,25 @@
     jint lastItemFragmentIndex = downloadEvent.lastItemFragmentIndex;
     jint dataLength = downloadEvent.dataLength;
 
-    jobject obj = env->NewObject(mDownloadEventClass, mDownloadEventInitID, itemId, downloadId,
-                                 mpuSequenceNumber, itemFragmentIndex, lastItemFragmentIndex,
-                                 dataLength);
-    env->SetObjectArrayElement(arr, size, obj);
-    env->DeleteLocalRef(obj);
+    ScopedLocalRef obj(env, env->NewObject(mDownloadEventClass, mDownloadEventInitID, itemId,
+                                           downloadId, mpuSequenceNumber, itemFragmentIndex,
+                                           lastItemFragmentIndex, dataLength));
+    env->SetObjectArrayElement(arr, size, obj.get());
 }
 
-void FilterClientCallbackImpl::getIpPayloadEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getIpPayloadEvent(const jobjectArray& arr, const int size,
                                                  const DemuxFilterEvent &event) {
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
-    const DemuxFilterIpPayloadEvent &ipPayloadEvent = event.get<DemuxFilterEvent::Tag::ipPayload>();
+    const DemuxFilterIpPayloadEvent &ipPayloadEvent =
+        event.get<DemuxFilterEvent::Tag::ipPayload>();
     jint dataLength = ipPayloadEvent.dataLength;
-    jobject obj = env->NewObject(mIpPayloadEventClass, mIpPayloadEventInitID, dataLength);
-    env->SetObjectArrayElement(arr, size, obj);
-    env->DeleteLocalRef(obj);
+    ScopedLocalRef obj(env, env->NewObject(mIpPayloadEventClass, mIpPayloadEventInitID,
+                                           dataLength));
+    env->SetObjectArrayElement(arr, size, obj.get());
 }
 
-void FilterClientCallbackImpl::getTemiEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getTemiEvent(const jobjectArray& arr, const int size,
                                             const DemuxFilterEvent &event) {
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
@@ -828,110 +817,108 @@
     jbyte descrTag = temiEvent.descrTag;
     std::vector<uint8_t> descrData = temiEvent.descrData;
 
-    jbyteArray array = env->NewByteArray(descrData.size());
-    env->SetByteArrayRegion(array, 0, descrData.size(), reinterpret_cast<jbyte *>(&descrData[0]));
+    ScopedLocalRef array(env, env->NewByteArray(descrData.size()));
+    env->SetByteArrayRegion(array.get(), 0, descrData.size(),
+                            reinterpret_cast<jbyte *>(&descrData[0]));
 
-    jobject obj = env->NewObject(mTemiEventClass, mTemiEventInitID, pts, descrTag, array);
-    env->SetObjectArrayElement(arr, size, obj);
-    env->DeleteLocalRef(array);
-    env->DeleteLocalRef(obj);
+    ScopedLocalRef obj(env, env->NewObject(mTemiEventClass, mTemiEventInitID, pts, descrTag,
+                                           array.get()));
+    env->SetObjectArrayElement(arr, size, obj.get());
 }
 
-void FilterClientCallbackImpl::getScramblingStatusEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getScramblingStatusEvent(const jobjectArray& arr, const int size,
                                                         const DemuxFilterEvent &event) {
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
     const DemuxFilterMonitorEvent &scramblingStatus =
             event.get<DemuxFilterEvent::Tag::monitorEvent>()
                     .get<DemuxFilterMonitorEvent::Tag::scramblingStatus>();
-    jobject obj = env->NewObject(mScramblingStatusEventClass, mScramblingStatusEventInitID,
-                                 scramblingStatus);
-    env->SetObjectArrayElement(arr, size, obj);
-    env->DeleteLocalRef(obj);
+    ScopedLocalRef obj(env, env->NewObject(mScramblingStatusEventClass,
+                                           mScramblingStatusEventInitID,
+                                           scramblingStatus));
+    env->SetObjectArrayElement(arr, size, obj.get());
 }
 
-void FilterClientCallbackImpl::getIpCidChangeEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getIpCidChangeEvent(const jobjectArray& arr, const int size,
                                                    const DemuxFilterEvent &event) {
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
     const DemuxFilterMonitorEvent &cid = event.get<DemuxFilterEvent::Tag::monitorEvent>()
                                                  .get<DemuxFilterMonitorEvent::Tag::cid>();
-    jobject obj = env->NewObject(mIpCidChangeEventClass, mIpCidChangeEventInitID, cid);
-    env->SetObjectArrayElement(arr, size, obj);
-    env->DeleteLocalRef(obj);
+    ScopedLocalRef obj(env, env->NewObject(mIpCidChangeEventClass, mIpCidChangeEventInitID, cid));
+    env->SetObjectArrayElement(arr, size, obj.get());
 }
 
-void FilterClientCallbackImpl::getRestartEvent(jobjectArray &arr, const int size,
+void FilterClientCallbackImpl::getRestartEvent(const jobjectArray& arr, const int size,
                                                const DemuxFilterEvent &event) {
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
     const int32_t &startId = event.get<DemuxFilterEvent::Tag::startId>();
-    jobject obj = env->NewObject(mRestartEventClass, mRestartEventInitID, startId);
-    env->SetObjectArrayElement(arr, size, obj);
-    env->DeleteLocalRef(obj);
+    ScopedLocalRef obj(env, env->NewObject(mRestartEventClass, mRestartEventInitID, startId));
+    env->SetObjectArrayElement(arr, size, obj.get());
 }
 
 void FilterClientCallbackImpl::onFilterEvent(const vector<DemuxFilterEvent> &events) {
     ALOGV("FilterClientCallbackImpl::onFilterEvent");
     JNIEnv *env = AndroidRuntime::getJNIEnv();
-    jobjectArray array;
+    ScopedLocalRef<jobjectArray> array(env);
 
     if (!events.empty()) {
-        array = env->NewObjectArray(events.size(), mEventClass, nullptr);
+        array.reset(env->NewObjectArray(events.size(), mEventClass, nullptr));
     }
 
     for (int i = 0, arraySize = 0; i < events.size(); i++) {
         const DemuxFilterEvent &event = events[i];
         switch (event.getTag()) {
             case DemuxFilterEvent::Tag::media: {
-                getMediaEvent(array, arraySize, event);
+                getMediaEvent(array.get(), arraySize, event);
                 arraySize++;
                 break;
             }
             case DemuxFilterEvent::Tag::section: {
-                getSectionEvent(array, arraySize, event);
+                getSectionEvent(array.get(), arraySize, event);
                 arraySize++;
                 break;
             }
             case DemuxFilterEvent::Tag::pes: {
-                getPesEvent(array, arraySize, event);
+                getPesEvent(array.get(), arraySize, event);
                 arraySize++;
                 break;
             }
             case DemuxFilterEvent::Tag::tsRecord: {
-                getTsRecordEvent(array, arraySize, event);
+                getTsRecordEvent(array.get(), arraySize, event);
                 arraySize++;
                 break;
             }
             case DemuxFilterEvent::Tag::mmtpRecord: {
-                getMmtpRecordEvent(array, arraySize, event);
+                getMmtpRecordEvent(array.get(), arraySize, event);
                 arraySize++;
                 break;
             }
             case DemuxFilterEvent::Tag::download: {
-                getDownloadEvent(array, arraySize, event);
+                getDownloadEvent(array.get(), arraySize, event);
                 arraySize++;
                 break;
             }
             case DemuxFilterEvent::Tag::ipPayload: {
-                getIpPayloadEvent(array, arraySize, event);
+                getIpPayloadEvent(array.get(), arraySize, event);
                 arraySize++;
                 break;
             }
             case DemuxFilterEvent::Tag::temi: {
-                getTemiEvent(array, arraySize, event);
+                getTemiEvent(array.get(), arraySize, event);
                 arraySize++;
                 break;
             }
             case DemuxFilterEvent::Tag::monitorEvent: {
                 switch (event.get<DemuxFilterEvent::Tag::monitorEvent>().getTag()) {
                     case DemuxFilterMonitorEvent::Tag::scramblingStatus: {
-                        getScramblingStatusEvent(array, arraySize, event);
+                        getScramblingStatusEvent(array.get(), arraySize, event);
                         arraySize++;
                         break;
                     }
                     case DemuxFilterMonitorEvent::Tag::cid: {
-                        getIpCidChangeEvent(array, arraySize, event);
+                        getIpCidChangeEvent(array.get(), arraySize, event);
                         arraySize++;
                         break;
                     }
@@ -943,7 +930,7 @@
                 break;
             }
             case DemuxFilterEvent::Tag::startId: {
-                getRestartEvent(array, arraySize, event);
+                getRestartEvent(array.get(), arraySize, event);
                 arraySize++;
                 break;
             }
@@ -953,32 +940,29 @@
             }
         }
     }
-    jobject filter(env->NewLocalRef(mFilterObj));
-    if (!env->IsSameObject(filter, nullptr)) {
+    ScopedLocalRef filter(env, env->NewLocalRef(mFilterObj));
+    if (!env->IsSameObject(filter.get(), nullptr)) {
         jmethodID methodID = gFields.onFilterEventID;
         if (mSharedFilter) {
             methodID = gFields.onSharedFilterEventID;
         }
-        env->CallVoidMethod(filter, methodID, array);
-        env->DeleteLocalRef(filter);
+        env->CallVoidMethod(filter.get(), methodID, array.get());
     } else {
         ALOGE("FilterClientCallbackImpl::onFilterEvent:"
               "Filter object has been freed. Ignoring callback.");
     }
-    env->DeleteLocalRef(array);
 }
 
 void FilterClientCallbackImpl::onFilterStatus(const DemuxFilterStatus status) {
     ALOGV("FilterClientCallbackImpl::onFilterStatus");
     JNIEnv *env = AndroidRuntime::getJNIEnv();
-    jobject filter(env->NewLocalRef(mFilterObj));
-    if (!env->IsSameObject(filter, nullptr)) {
+    ScopedLocalRef filter(env, env->NewLocalRef(mFilterObj));
+    if (!env->IsSameObject(filter.get(), nullptr)) {
         jmethodID methodID = gFields.onFilterStatusID;
         if (mSharedFilter) {
             methodID = gFields.onSharedFilterStatusID;
         }
-        env->CallVoidMethod(filter, methodID, (jint)static_cast<uint8_t>(status));
-        env->DeleteLocalRef(filter);
+        env->CallVoidMethod(filter.get(), methodID, (jint)static_cast<uint8_t>(status));
     } else {
         ALOGE("FilterClientCallbackImpl::onFilterStatus:"
               "Filter object has been freed. Ignoring callback.");
@@ -1115,13 +1099,12 @@
     std::scoped_lock<std::mutex> lock(mMutex);
     for (const auto& mapEntry : mListenersMap) {
         ALOGV("JTuner:%p, jweak:%p", mapEntry.first, mapEntry.second);
-        jobject frontend(env->NewLocalRef(mapEntry.second));
-        if (!env->IsSameObject(frontend, nullptr)) {
+        ScopedLocalRef frontend(env, env->NewLocalRef(mapEntry.second));
+        if (!env->IsSameObject(frontend.get(), nullptr)) {
             env->CallVoidMethod(
-                    frontend,
+                    frontend.get(),
                     gFields.onFrontendEventID,
                     (jint)frontendEventType);
-            env->DeleteLocalRef(frontend);
         } else {
             ALOGW("FrontendClientCallbackImpl::onEvent:"
                     "Frontend object has been freed. Ignoring callback.");
@@ -1133,20 +1116,18 @@
         FrontendScanMessageType type, const FrontendScanMessage& message) {
     ALOGV("FrontendClientCallbackImpl::onScanMessage, type=%d", type);
     JNIEnv *env = AndroidRuntime::getJNIEnv();
-    jclass clazz = env->FindClass("android/media/tv/tuner/Tuner");
+    ScopedLocalRef clazz(env, env->FindClass("android/media/tv/tuner/Tuner"));
 
     std::scoped_lock<std::mutex> lock(mMutex);
     for (const auto& mapEntry : mListenersMap) {
-        jobject frontend(env->NewLocalRef(mapEntry.second));
-        if (env->IsSameObject(frontend, nullptr)) {
+        ScopedLocalRef frontend(env, env->NewLocalRef(mapEntry.second));
+        if (env->IsSameObject(frontend.get(), nullptr)) {
             ALOGE("FrontendClientCallbackImpl::onScanMessage:"
                     "Tuner object has been freed. Ignoring callback.");
             continue;
         }
-        executeOnScanMessage(env, clazz, frontend, type, message);
-        env->DeleteLocalRef(frontend);
+        executeOnScanMessage(env, clazz.get(), frontend.get(), type, message);
     }
-    env->DeleteLocalRef(clazz);
 }
 
 void FrontendClientCallbackImpl::executeOnScanMessage(
@@ -1183,20 +1164,19 @@
         }
         case FrontendScanMessageType::FREQUENCY: {
             std::vector<int64_t> v = message.get<FrontendScanMessage::Tag::frequencies>();
-            jlongArray freqs = env->NewLongArray(v.size());
-            env->SetLongArrayRegion(freqs, 0, v.size(), reinterpret_cast<jlong *>(&v[0]));
+            ScopedLocalRef freqs(env, env->NewLongArray(v.size()));
+            env->SetLongArrayRegion(freqs.get(), 0, v.size(), reinterpret_cast<jlong *>(&v[0]));
             env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onFrequenciesReport", "([J)V"),
-                                freqs);
-            env->DeleteLocalRef(freqs);
+                                freqs.get());
             break;
         }
         case FrontendScanMessageType::SYMBOL_RATE: {
             std::vector<int32_t> v = message.get<FrontendScanMessage::Tag::symbolRates>();
-            jintArray symbolRates = env->NewIntArray(v.size());
-            env->SetIntArrayRegion(symbolRates, 0, v.size(), reinterpret_cast<jint *>(&v[0]));
+            ScopedLocalRef symbolRates(env, env->NewIntArray(v.size()));
+            env->SetIntArrayRegion(symbolRates.get(), 0, v.size(),
+                                   reinterpret_cast<jint *>(&v[0]));
             env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onSymbolRates", "([I)V"),
-                                symbolRates);
-            env->DeleteLocalRef(symbolRates);
+                                symbolRates.get());
             break;
         }
         case FrontendScanMessageType::HIERARCHY: {
@@ -1211,27 +1191,29 @@
         }
         case FrontendScanMessageType::PLP_IDS: {
             std::vector<int32_t> jintV = message.get<FrontendScanMessage::Tag::plpIds>();
-            jintArray plpIds = env->NewIntArray(jintV.size());
-            env->SetIntArrayRegion(plpIds, 0, jintV.size(), reinterpret_cast<jint *>(&jintV[0]));
-            env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onPlpIds", "([I)V"), plpIds);
-            env->DeleteLocalRef(plpIds);
+            ScopedLocalRef plpIds(env, env->NewIntArray(jintV.size()));
+            env->SetIntArrayRegion(plpIds.get(), 0, jintV.size(),
+                                   reinterpret_cast<jint *>(&jintV[0]));
+            env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onPlpIds", "([I)V"),
+                                plpIds.get());
             break;
         }
         case FrontendScanMessageType::GROUP_IDS: {
             std::vector<int32_t> jintV = message.get<FrontendScanMessage::groupIds>();
-            jintArray groupIds = env->NewIntArray(jintV.size());
-            env->SetIntArrayRegion(groupIds, 0, jintV.size(), reinterpret_cast<jint *>(&jintV[0]));
-            env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onGroupIds", "([I)V"), groupIds);
-            env->DeleteLocalRef(groupIds);
+            ScopedLocalRef groupIds(env, env->NewIntArray(jintV.size()));
+            env->SetIntArrayRegion(groupIds.get(), 0, jintV.size(),
+                                   reinterpret_cast<jint *>(&jintV[0]));
+            env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onGroupIds", "([I)V"),
+                                groupIds.get());
             break;
         }
         case FrontendScanMessageType::INPUT_STREAM_IDS: {
             std::vector<int32_t> jintV = message.get<FrontendScanMessage::inputStreamIds>();
-            jintArray streamIds = env->NewIntArray(jintV.size());
-            env->SetIntArrayRegion(streamIds, 0, jintV.size(), reinterpret_cast<jint *>(&jintV[0]));
+            ScopedLocalRef streamIds(env, env->NewIntArray(jintV.size()));
+            env->SetIntArrayRegion(streamIds.get(), 0, jintV.size(),
+                                   reinterpret_cast<jint *>(&jintV[0]));
             env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onInputStreamIds", "([I)V"),
-                                streamIds);
-            env->DeleteLocalRef(streamIds);
+                                streamIds.get());
             break;
         }
         case FrontendScanMessageType::STANDARD: {
@@ -1254,26 +1236,25 @@
             break;
         }
         case FrontendScanMessageType::ATSC3_PLP_INFO: {
-            jclass plpClazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3PlpInfo");
-            jmethodID init = env->GetMethodID(plpClazz, "<init>", "(IZ)V");
+            ScopedLocalRef plpClazz(env,
+                    env->FindClass("android/media/tv/tuner/frontend/Atsc3PlpInfo"));
+            jmethodID init = env->GetMethodID(plpClazz.get(), "<init>", "(IZ)V");
             std::vector<FrontendScanAtsc3PlpInfo> plpInfos =
                     message.get<FrontendScanMessage::atsc3PlpInfos>();
-            jobjectArray array = env->NewObjectArray(plpInfos.size(), plpClazz, nullptr);
+            ScopedLocalRef array(env,
+                                 env->NewObjectArray(plpInfos.size(), plpClazz.get(), nullptr));
             for (int i = 0; i < plpInfos.size(); i++) {
                 const FrontendScanAtsc3PlpInfo &info = plpInfos[i];
                 jint plpId = info.plpId;
                 jboolean lls = info.bLlsFlag;
-                jobject obj = env->NewObject(plpClazz, init, plpId, lls);
-                env->SetObjectArrayElement(array, i, obj);
-                env->DeleteLocalRef(obj);
+                ScopedLocalRef obj(env, env->NewObject(plpClazz.get(), init, plpId, lls));
+                env->SetObjectArrayElement(array.get(), i, obj.get());
             }
             env->CallVoidMethod(frontend,
                                 env->GetMethodID(clazz, "onAtsc3PlpInfos",
                                                  "([Landroid/media/tv/tuner/frontend/"
                                                  "Atsc3PlpInfo;)V"),
-                                array);
-            env->DeleteLocalRef(array);
-            env->DeleteLocalRef(plpClazz);
+                                array.get());
             break;
         }
         case FrontendScanMessageType::MODULATION: {
@@ -1341,11 +1322,12 @@
         }
         case FrontendScanMessageType::DVBT_CELL_IDS: {
             std::vector<int32_t> jintV = message.get<FrontendScanMessage::dvbtCellIds>();
-            jintArray cellIds = env->NewIntArray(jintV.size());
-            env->SetIntArrayRegion(cellIds, 0, jintV.size(), reinterpret_cast<jint *>(&jintV[0]));
-            env->CallVoidMethod(frontend, env->GetMethodID(clazz, "onDvbtCellIdsReported", "([I)V"),
-                                cellIds);
-            env->DeleteLocalRef(cellIds);
+            ScopedLocalRef cellIds(env, env->NewIntArray(jintV.size()));
+            env->SetIntArrayRegion(cellIds.get(), 0, jintV.size(),
+                                   reinterpret_cast<jint *>(&jintV[0]));
+            env->CallVoidMethod(frontend,
+                                env->GetMethodID(clazz, "onDvbtCellIdsReported", "([I)V"),
+                                cellIds.get());
             break;
         }
         default:
@@ -1434,7 +1416,8 @@
     JNIEnv *env = AndroidRuntime::getJNIEnv();
     jclass arrayListClazz = env->FindClass("java/util/ArrayList");
     jmethodID arrayListAdd = env->GetMethodID(arrayListClazz, "add", "(Ljava/lang/Object;)Z");
-    jobject obj = env->NewObject(arrayListClazz, env->GetMethodID(arrayListClazz, "<init>", "()V"));
+    jobject obj = env->NewObject(arrayListClazz,
+                                 env->GetMethodID(arrayListClazz, "<init>", "()V"));
 
     jclass integerClazz = env->FindClass("java/lang/Integer");
     jmethodID intInit = env->GetMethodID(integerClazz, "<init>", "(I)V");
@@ -1672,7 +1655,7 @@
     jclass clazz = env->FindClass("android/media/tv/tuner/frontend/FrontendInfo");
     jmethodID infoInit =
             env->GetMethodID(clazz, "<init>",
-                             "(IIJJIIJI[ILandroid/media/tv/tuner/frontend/FrontendCapabilities;)V");
+                    "(IIJJIIJI[ILandroid/media/tv/tuner/frontend/FrontendCapabilities;)V");
 
     jint type = (jint)feInfo->type;
     jlong minFrequency = feInfo->minFrequency;
@@ -1812,9 +1795,8 @@
     jmethodID init = env->GetMethodID(clazz, "<init>", "(II)V");
     jobjectArray valObj = env->NewObjectArray(size, clazz, nullptr);
     for (int i = 0; i < size; i++) {
-        jobject readinessObj = env->NewObject(clazz, init, intTypes[i], readiness[i]);
-        env->SetObjectArrayElement(valObj, i, readinessObj);
-        env->DeleteLocalRef(readinessObj);
+        ScopedLocalRef readinessObj(env, env->NewObject(clazz, init, intTypes[i], readiness[i]));
+        env->SetObjectArrayElement(valObj, i, readinessObj.get());
     }
     return valObj;
 }
@@ -2260,79 +2242,72 @@
         switch (s.getTag()) {
             case FrontendStatus::Tag::isDemodLocked: {
                 jfieldID field = env->GetFieldID(clazz, "mIsDemodLocked", "Ljava/lang/Boolean;");
-                jobject newBooleanObj = env->NewObject(booleanClazz, initBoolean,
-                                                       s.get<FrontendStatus::Tag::isDemodLocked>());
-                env->SetObjectField(statusObj, field, newBooleanObj);
-                env->DeleteLocalRef(newBooleanObj);
+                ScopedLocalRef newBooleanObj(env,
+                        env->NewObject(booleanClazz, initBoolean,
+                                       s.get<FrontendStatus::Tag::isDemodLocked>()));
+                env->SetObjectField(statusObj, field, newBooleanObj.get());
                 break;
             }
             case FrontendStatus::Tag::snr: {
                 jfieldID field = env->GetFieldID(clazz, "mSnr", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
-                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::snr>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                ScopedLocalRef newIntegerObj(env,
+                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::snr>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::ber: {
                 jfieldID field = env->GetFieldID(clazz, "mBer", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
-                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::ber>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                ScopedLocalRef newIntegerObj(env,
+                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::ber>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::per: {
                 jfieldID field = env->GetFieldID(clazz, "mPer", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
-                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::per>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                ScopedLocalRef newIntegerObj(env,
+                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::per>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::preBer: {
                 jfieldID field = env->GetFieldID(clazz, "mPerBer", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
-                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::preBer>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                ScopedLocalRef newIntegerObj(env,
+                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::preBer>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::signalQuality: {
                 jfieldID field = env->GetFieldID(clazz, "mSignalQuality", "Ljava/lang/Integer;");
-                jobject newIntegerObj = env->NewObject(intClazz, initInt,
-                                                       s.get<FrontendStatus::Tag::signalQuality>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                ScopedLocalRef newIntegerObj(env,
+                        env->NewObject(intClazz, initInt,
+                                       s.get<FrontendStatus::Tag::signalQuality>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::signalStrength: {
                 jfieldID field = env->GetFieldID(clazz, "mSignalStrength", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
+                ScopedLocalRef newIntegerObj(env,
                         env->NewObject(intClazz, initInt,
-                                       s.get<FrontendStatus::Tag::signalStrength>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                                       s.get<FrontendStatus::Tag::signalStrength>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::symbolRate: {
                 jfieldID field = env->GetFieldID(clazz, "mSymbolRate", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
-                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::symbolRate>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                ScopedLocalRef newIntegerObj(env,
+                        env->NewObject(intClazz, initInt,
+                                       s.get<FrontendStatus::Tag::symbolRate>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::innerFec: {
                 jfieldID field = env->GetFieldID(clazz, "mInnerFec", "Ljava/lang/Long;");
-                jclass longClazz = env->FindClass("java/lang/Long");
-                jmethodID initLong = env->GetMethodID(longClazz, "<init>", "(J)V");
-                jobject newLongObj =
-                        env->NewObject(longClazz, initLong,
-                                       static_cast<long>(s.get<FrontendStatus::Tag::innerFec>()));
-                env->SetObjectField(statusObj, field, newLongObj);
-                env->DeleteLocalRef(newLongObj);
-                env->DeleteLocalRef(longClazz);
+                ScopedLocalRef longClazz(env, env->FindClass("java/lang/Long"));
+                jmethodID initLong = env->GetMethodID(longClazz.get(), "<init>", "(J)V");
+                ScopedLocalRef newLongObj(env,
+                        env->NewObject(longClazz.get(), initLong,
+                                       static_cast<long>(s.get<FrontendStatus::Tag::innerFec>())));
+                env->SetObjectField(statusObj, field, newLongObj.get());
                 break;
             }
             case FrontendStatus::Tag::modulationStatus: {
@@ -2373,139 +2348,128 @@
                     }
                 }
                 if (valid) {
-                    jobject newIntegerObj = env->NewObject(intClazz, initInt, intModulation);
-                    env->SetObjectField(statusObj, field, newIntegerObj);
-                    env->DeleteLocalRef(newIntegerObj);
+                    ScopedLocalRef newIntegerObj(env,
+                            env->NewObject(intClazz, initInt, intModulation));
+                    env->SetObjectField(statusObj, field, newIntegerObj.get());
                 }
                 break;
             }
             case FrontendStatus::Tag::inversion: {
                 jfieldID field = env->GetFieldID(clazz, "mInversion", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
+                ScopedLocalRef newIntegerObj(env,
                         env->NewObject(intClazz, initInt,
-                                       static_cast<jint>(s.get<FrontendStatus::Tag::inversion>()));
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                                static_cast<jint>(s.get<FrontendStatus::Tag::inversion>())));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::lnbVoltage: {
                 jfieldID field = env->GetFieldID(clazz, "mLnbVoltage", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
+                ScopedLocalRef newIntegerObj(env,
                         env->NewObject(intClazz, initInt,
-                                       static_cast<jint>(s.get<FrontendStatus::Tag::lnbVoltage>()));
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                                static_cast<jint>(s.get<FrontendStatus::Tag::lnbVoltage>())));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::plpId: {
                 jfieldID field = env->GetFieldID(clazz, "mPlpId", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
-                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::plpId>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                ScopedLocalRef newIntegerObj(env,
+                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::plpId>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::isEWBS: {
                 jfieldID field = env->GetFieldID(clazz, "mIsEwbs", "Ljava/lang/Boolean;");
-                jobject newBooleanObj = env->NewObject(booleanClazz, initBoolean,
-                                                       s.get<FrontendStatus::Tag::isEWBS>());
-                env->SetObjectField(statusObj, field, newBooleanObj);
-                env->DeleteLocalRef(newBooleanObj);
+                ScopedLocalRef newBooleanObj(env, env->NewObject(booleanClazz, initBoolean,
+                                                       s.get<FrontendStatus::Tag::isEWBS>()));
+                env->SetObjectField(statusObj, field, newBooleanObj.get());
                 break;
             }
             case FrontendStatus::Tag::agc: {
                 jfieldID field = env->GetFieldID(clazz, "mAgc", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
-                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::agc>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                ScopedLocalRef newIntegerObj(env,
+                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::agc>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::isLnaOn: {
                 jfieldID field = env->GetFieldID(clazz, "mIsLnaOn", "Ljava/lang/Boolean;");
-                jobject newBooleanObj = env->NewObject(booleanClazz, initBoolean,
-                                                       s.get<FrontendStatus::Tag::isLnaOn>());
-                env->SetObjectField(statusObj, field, newBooleanObj);
-                env->DeleteLocalRef(newBooleanObj);
+                ScopedLocalRef newBooleanObj(env, env->NewObject(booleanClazz, initBoolean,
+                                                       s.get<FrontendStatus::Tag::isLnaOn>()));
+                env->SetObjectField(statusObj, field, newBooleanObj.get());
                 break;
             }
             case FrontendStatus::Tag::isLayerError: {
                 jfieldID field = env->GetFieldID(clazz, "mIsLayerErrors", "[Z");
                 vector<bool> layerErr = s.get<FrontendStatus::Tag::isLayerError>();
 
-                jbooleanArray valObj = env->NewBooleanArray(layerErr.size());
+                ScopedLocalRef valObj(env, env->NewBooleanArray(layerErr.size()));
 
                 for (size_t i = 0; i < layerErr.size(); i++) {
                     jboolean x = layerErr[i];
-                    env->SetBooleanArrayRegion(valObj, i, 1, &x);
+                    env->SetBooleanArrayRegion(valObj.get(), i, 1, &x);
                 }
-                env->SetObjectField(statusObj, field, valObj);
-                env->DeleteLocalRef(valObj);
+                env->SetObjectField(statusObj, field, valObj.get());
                 break;
             }
             case FrontendStatus::Tag::mer: {
                 jfieldID field = env->GetFieldID(clazz, "mMer", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
-                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::mer>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                ScopedLocalRef newIntegerObj(env,
+                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::mer>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::freqOffset: {
                 jfieldID field = env->GetFieldID(clazz, "mFreqOffset", "Ljava/lang/Long;");
-                jobject newLongObj = env->NewObject(longClazz, initLong,
-                                                    s.get<FrontendStatus::Tag::freqOffset>());
-                env->SetObjectField(statusObj, field, newLongObj);
-                env->DeleteLocalRef(newLongObj);
+                ScopedLocalRef newLongObj(env, env->NewObject(longClazz, initLong,
+                                                    s.get<FrontendStatus::Tag::freqOffset>()));
+                env->SetObjectField(statusObj, field, newLongObj.get());
                 break;
             }
             case FrontendStatus::Tag::hierarchy: {
                 jfieldID field = env->GetFieldID(clazz, "mHierarchy", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
+                ScopedLocalRef newIntegerObj(env,
                         env->NewObject(intClazz, initInt,
-                                       static_cast<jint>(s.get<FrontendStatus::Tag::hierarchy>()));
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                                static_cast<jint>(s.get<FrontendStatus::Tag::hierarchy>())));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::isRfLocked: {
                 jfieldID field = env->GetFieldID(clazz, "mIsRfLocked", "Ljava/lang/Boolean;");
-                jobject newBooleanObj = env->NewObject(booleanClazz, initBoolean,
-                                                       s.get<FrontendStatus::Tag::isRfLocked>());
-                env->SetObjectField(statusObj, field, newBooleanObj);
-                env->DeleteLocalRef(newBooleanObj);
+                ScopedLocalRef newBooleanObj(env, env->NewObject(booleanClazz, initBoolean,
+                                                       s.get<FrontendStatus::Tag::isRfLocked>()));
+                env->SetObjectField(statusObj, field, newBooleanObj.get());
                 break;
             }
             case FrontendStatus::Tag::plpInfo: {
                 jfieldID field = env->GetFieldID(clazz, "mPlpInfo",
                         "[Landroid/media/tv/tuner/frontend/FrontendStatus$Atsc3PlpTuningInfo;");
-                jclass plpClazz = env->FindClass(
-                        "android/media/tv/tuner/frontend/FrontendStatus$Atsc3PlpTuningInfo");
-                jmethodID initPlp = env->GetMethodID(plpClazz, "<init>", "(IZI)V");
+                ScopedLocalRef plpClazz(env, env->FindClass(
+                        "android/media/tv/tuner/frontend/FrontendStatus$Atsc3PlpTuningInfo"));
+                jmethodID initPlp = env->GetMethodID(plpClazz.get(), "<init>", "(IZI)V");
 
-                vector<FrontendStatusAtsc3PlpInfo> plpInfos = s.get<FrontendStatus::Tag::plpInfo>();
-                jobjectArray valObj = env->NewObjectArray(plpInfos.size(), plpClazz, nullptr);
+                vector<FrontendStatusAtsc3PlpInfo> plpInfos =
+                        s.get<FrontendStatus::Tag::plpInfo>();
+                ScopedLocalRef valObj(env, env->NewObjectArray(plpInfos.size(), plpClazz.get(),
+                                                               nullptr));
                 for (int i = 0; i < plpInfos.size(); i++) {
                     const FrontendStatusAtsc3PlpInfo &info = plpInfos[i];
                     jint plpId = info.plpId;
                     jboolean isLocked = info.isLocked;
                     jint uec = info.uec;
 
-                    jobject plpObj = env->NewObject(plpClazz, initPlp, plpId, isLocked, uec);
-                    env->SetObjectArrayElement(valObj, i, plpObj);
-                    env->DeleteLocalRef(plpObj);
+                    ScopedLocalRef plpObj(env, env->NewObject(plpClazz.get(), initPlp, plpId,
+                                                              isLocked, uec));
+                    env->SetObjectArrayElement(valObj.get(), i, plpObj.get());
                 }
 
-                env->SetObjectField(statusObj, field, valObj);
-                env->DeleteLocalRef(valObj);
-                env->DeleteLocalRef(plpClazz);
+                env->SetObjectField(statusObj, field, valObj.get());
                 break;
             }
             case FrontendStatus::Tag::modulations: {
                 jfieldID field = env->GetFieldID(clazz, "mModulationsExt", "[I");
                 std::vector<FrontendModulation> v = s.get<FrontendStatus::Tag::modulations>();
 
-                jintArray valObj = env->NewIntArray(v.size());
+                ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
                 bool valid = false;
                 jint m[1];
                 for (int i = 0; i < v.size(); i++) {
@@ -2514,63 +2478,63 @@
                         case FrontendModulation::Tag::dvbc: {
                             m[0] = static_cast<jint>(
                                     modulation.get<FrontendModulation::Tag::dvbc>());
-                            env->SetIntArrayRegion(valObj, i, 1, m);
+                            env->SetIntArrayRegion(valObj.get(), i, 1, m);
                             valid = true;
                             break;
                         }
                         case FrontendModulation::Tag::dvbs: {
                             m[0] = static_cast<jint>(
                                     modulation.get<FrontendModulation::Tag::dvbs>());
-                            env->SetIntArrayRegion(valObj, i, 1, m);
+                            env->SetIntArrayRegion(valObj.get(), i, 1, m);
                             valid = true;
                            break;
                         }
                         case FrontendModulation::Tag::dvbt: {
                             m[0] = static_cast<jint>(
                                     modulation.get<FrontendModulation::Tag::dvbt>());
-                            env->SetIntArrayRegion(valObj, i, 1, m);
+                            env->SetIntArrayRegion(valObj.get(), i, 1, m);
                             valid = true;
                             break;
                         }
                         case FrontendModulation::Tag::isdbs: {
                             m[0] = static_cast<jint>(
                                     modulation.get<FrontendModulation::Tag::isdbs>());
-                            env->SetIntArrayRegion(valObj, i, 1, m);
+                            env->SetIntArrayRegion(valObj.get(), i, 1, m);
                             valid = true;
                             break;
                         }
                         case FrontendModulation::Tag::isdbs3: {
                             m[0] = static_cast<jint>(
                                     modulation.get<FrontendModulation::Tag::isdbs3>());
-                            env->SetIntArrayRegion(valObj, i, 1, m);
+                            env->SetIntArrayRegion(valObj.get(), i, 1, m);
                             valid = true;
                             break;
                         }
                         case FrontendModulation::Tag::isdbt: {
                             m[0] = static_cast<jint>(
                                     modulation.get<FrontendModulation::Tag::isdbt>());
-                            env->SetIntArrayRegion(valObj, i, 1, m);
+                            env->SetIntArrayRegion(valObj.get(), i, 1, m);
                             valid = true;
                             break;
                         }
                         case FrontendModulation::Tag::atsc: {
                             m[0] = static_cast<jint>(
                                     modulation.get<FrontendModulation::Tag::atsc>());
-                            env->SetIntArrayRegion(valObj, i, 1, m);
+                            env->SetIntArrayRegion(valObj.get(), i, 1, m);
                             valid = true;
                             break;
                         }
                         case FrontendModulation::Tag::atsc3: {
                             m[0] = static_cast<jint>(
                                     modulation.get<FrontendModulation::Tag::atsc3>());
-                            env->SetIntArrayRegion(valObj, i, 1, m);
+                            env->SetIntArrayRegion(valObj.get(), i, 1, m);
                             valid = true;
                             break;
                         }
                         case FrontendModulation::Tag::dtmb: {
                             m[0] = static_cast<jint>(
                                     modulation.get<FrontendModulation::Tag::dtmb>());
-                            env->SetIntArrayRegion(valObj, i, 1, m);
+                            env->SetIntArrayRegion(valObj.get(), i, 1, m);
                             valid = true;
                             break;
                         }
@@ -2579,31 +2543,28 @@
                     }
                 }
                 if (valid) {
-                    env->SetObjectField(statusObj, field, valObj);
+                    env->SetObjectField(statusObj, field, valObj.get());
                 }
-                env->DeleteLocalRef(valObj);
                 break;
             }
             case FrontendStatus::Tag::bers: {
                 jfieldID field = env->GetFieldID(clazz, "mBers", "[I");
                 std::vector<int32_t> v = s.get<FrontendStatus::Tag::bers>();
 
-                jintArray valObj = env->NewIntArray(v.size());
-                env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint *>(&v[0]));
+                ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
+                env->SetIntArrayRegion(valObj.get(), 0, v.size(), reinterpret_cast<jint *>(&v[0]));
 
-                env->SetObjectField(statusObj, field, valObj);
-                env->DeleteLocalRef(valObj);
+                env->SetObjectField(statusObj, field, valObj.get());
                 break;
             }
             case FrontendStatus::Tag::codeRates: {
                 jfieldID field = env->GetFieldID(clazz, "mCodeRates", "[I");
                 std::vector<FrontendInnerFec> v = s.get<FrontendStatus::Tag::codeRates>();
 
-                jintArray valObj = env->NewIntArray(v.size());
-                env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint *>(&v[0]));
+                ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
+                env->SetIntArrayRegion(valObj.get(), 0, v.size(), reinterpret_cast<jint *>(&v[0]));
 
-                env->SetObjectField(statusObj, field, valObj);
-                env->DeleteLocalRef(valObj);
+                env->SetObjectField(statusObj, field, valObj.get());
                 break;
             }
             case FrontendStatus::Tag::bandwidth: {
@@ -2642,9 +2603,9 @@
                         break;
                 }
                 if (valid) {
-                    jobject newIntegerObj = env->NewObject(intClazz, initInt, intBandwidth);
-                    env->SetObjectField(statusObj, field, newIntegerObj);
-                    env->DeleteLocalRef(newIntegerObj);
+                    ScopedLocalRef newIntegerObj(env, env->NewObject(intClazz, initInt,
+                                                                     intBandwidth));
+                    env->SetObjectField(statusObj, field, newIntegerObj.get());
                 }
                 break;
             }
@@ -2655,8 +2616,8 @@
                 bool valid = true;
                 switch (interval.getTag()) {
                     case FrontendGuardInterval::Tag::dvbt: {
-                        intInterval =
-                                static_cast<jint>(interval.get<FrontendGuardInterval::Tag::dvbt>());
+                        intInterval = static_cast<jint>(
+                                interval.get<FrontendGuardInterval::Tag::dvbt>());
                         break;
                     }
                     case FrontendGuardInterval::Tag::isdbt: {
@@ -2665,8 +2626,8 @@
                         break;
                     }
                     case FrontendGuardInterval::Tag::dtmb: {
-                        intInterval =
-                                static_cast<jint>(interval.get<FrontendGuardInterval::Tag::dtmb>());
+                        intInterval = static_cast<jint>(
+                                interval.get<FrontendGuardInterval::Tag::dtmb>());
                         break;
                     }
                     default:
@@ -2674,14 +2635,15 @@
                         break;
                 }
                 if (valid) {
-                    jobject newIntegerObj = env->NewObject(intClazz, initInt, intInterval);
-                    env->SetObjectField(statusObj, field, newIntegerObj);
-                    env->DeleteLocalRef(newIntegerObj);
+                    ScopedLocalRef newIntegerObj(env, env->NewObject(intClazz, initInt,
+                                                                     intInterval));
+                    env->SetObjectField(statusObj, field, newIntegerObj.get());
                 }
                 break;
             }
             case FrontendStatus::Tag::transmissionMode: {
-                jfieldID field = env->GetFieldID(clazz, "mTransmissionMode", "Ljava/lang/Integer;");
+                jfieldID field = env->GetFieldID(clazz, "mTransmissionMode",
+                                                 "Ljava/lang/Integer;");
                 const FrontendTransmissionMode &transmissionMode =
                         s.get<FrontendStatus::Tag::transmissionMode>();
                 jint intTransmissionMode;
@@ -2707,32 +2669,30 @@
                         break;
                 }
                 if (valid) {
-                    jobject newIntegerObj = env->NewObject(intClazz, initInt, intTransmissionMode);
-                    env->SetObjectField(statusObj, field, newIntegerObj);
-                    env->DeleteLocalRef(newIntegerObj);
+                    ScopedLocalRef newIntegerObj(env, env->NewObject(intClazz, initInt,
+                                                                     intTransmissionMode));
+                    env->SetObjectField(statusObj, field, newIntegerObj.get());
                 }
                 break;
             }
             case FrontendStatus::Tag::uec: {
                 jfieldID field = env->GetFieldID(clazz, "mUec", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
-                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::uec>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                ScopedLocalRef newIntegerObj(env,
+                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::uec>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::systemId: {
                 jfieldID field = env->GetFieldID(clazz, "mSystemId", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
-                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::systemId>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                ScopedLocalRef newIntegerObj(env,
+                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::systemId>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::interleaving: {
                 jfieldID field = env->GetFieldID(clazz, "mInterleaving", "[I");
                 std::vector<FrontendInterleaveMode> v = s.get<FrontendStatus::Tag::interleaving>();
-                jintArray valObj = env->NewIntArray(v.size());
+                ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
                 bool valid = false;
                 jint in[1];
                 for (int i = 0; i < v.size(); i++) {
@@ -2741,28 +2701,28 @@
                         case FrontendInterleaveMode::Tag::atsc3: {
                             in[0] = static_cast<jint>(
                                     interleaving.get<FrontendInterleaveMode::Tag::atsc3>());
-                            env->SetIntArrayRegion(valObj, i, 1, in);
+                            env->SetIntArrayRegion(valObj.get(), i, 1, in);
                             valid = true;
                             break;
                         }
                         case FrontendInterleaveMode::Tag::dvbc: {
                             in[0] = static_cast<jint>(
                                     interleaving.get<FrontendInterleaveMode::Tag::dvbc>());
-                            env->SetIntArrayRegion(valObj, i, 1, in);
+                            env->SetIntArrayRegion(valObj.get(), i, 1, in);
                             valid = true;
                            break;
                         }
                         case FrontendInterleaveMode::Tag::dtmb: {
                             in[0] = static_cast<jint>(
                                     interleaving.get<FrontendInterleaveMode::Tag::dtmb>());
-                            env->SetIntArrayRegion(valObj, i, 1, in);
+                            env->SetIntArrayRegion(valObj.get(), i, 1, in);
                             valid = true;
                            break;
                         }
                         case FrontendInterleaveMode::Tag::isdbt: {
                             in[0] = static_cast<jint>(
                                     interleaving.get<FrontendInterleaveMode::Tag::isdbt>());
-                            env->SetIntArrayRegion(valObj, i, 1, in);
+                            env->SetIntArrayRegion(valObj.get(), i, 1, in);
                             valid = true;
                             break;
                         }
@@ -2771,31 +2731,28 @@
                     }
                 }
                 if (valid) {
-                    env->SetObjectField(statusObj, field, valObj);
+                    env->SetObjectField(statusObj, field, valObj.get());
                 }
-                env->DeleteLocalRef(valObj);
                 break;
             }
             case FrontendStatus::Tag::isdbtSegment: {
                 jfieldID field = env->GetFieldID(clazz, "mIsdbtSegment", "[I");
                 std::vector<int32_t> v = s.get<FrontendStatus::Tag::isdbtSegment>();
 
-                jintArray valObj = env->NewIntArray(v.size());
-                env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint*>(&v[0]));
+                ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
+                env->SetIntArrayRegion(valObj.get(), 0, v.size(), reinterpret_cast<jint*>(&v[0]));
 
-                env->SetObjectField(statusObj, field, valObj);
-                env->DeleteLocalRef(valObj);
+                env->SetObjectField(statusObj, field, valObj.get());
                 break;
             }
             case FrontendStatus::Tag::tsDataRate: {
                 jfieldID field = env->GetFieldID(clazz, "mTsDataRate", "[I");
                 std::vector<int32_t> v = s.get<FrontendStatus::Tag::tsDataRate>();
 
-                jintArray valObj = env->NewIntArray(v.size());
-                env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint *>(&v[0]));
+                ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
+                env->SetIntArrayRegion(valObj.get(), 0, v.size(), reinterpret_cast<jint *>(&v[0]));
 
-                env->SetObjectField(statusObj, field, valObj);
-                env->DeleteLocalRef(valObj);
+                env->SetObjectField(statusObj, field, valObj.get());
                 break;
             }
             case FrontendStatus::Tag::rollOff: {
@@ -2813,7 +2770,8 @@
                         break;
                     }
                     case FrontendRollOff::Tag::isdbs3: {
-                        intRollOff = static_cast<jint>(rollOff.get<FrontendRollOff::Tag::isdbs3>());
+                        intRollOff = static_cast<jint>(
+                                rollOff.get<FrontendRollOff::Tag::isdbs3>());
                         break;
                     }
                     default:
@@ -2821,141 +2779,135 @@
                         break;
                 }
                 if (valid) {
-                    jobject newIntegerObj = env->NewObject(intClazz, initInt, intRollOff);
-                    env->SetObjectField(statusObj, field, newIntegerObj);
-                    env->DeleteLocalRef(newIntegerObj);
+                    ScopedLocalRef newIntegerObj(env, env->NewObject(intClazz, initInt,
+                                                                     intRollOff));
+                    env->SetObjectField(statusObj, field, newIntegerObj.get());
                 }
                 break;
             }
             case FrontendStatus::Tag::isMiso: {
                 jfieldID field = env->GetFieldID(clazz, "mIsMisoEnabled", "Ljava/lang/Boolean;");
-                jobject newBooleanObj = env->NewObject(booleanClazz, initBoolean,
-                                                       s.get<FrontendStatus::Tag::isMiso>());
-                env->SetObjectField(statusObj, field, newBooleanObj);
-                env->DeleteLocalRef(newBooleanObj);
+                ScopedLocalRef newBooleanObj(env, env->NewObject(booleanClazz, initBoolean,
+                                                       s.get<FrontendStatus::Tag::isMiso>()));
+                env->SetObjectField(statusObj, field, newBooleanObj.get());
                 break;
             }
             case FrontendStatus::Tag::isLinear: {
                 jfieldID field = env->GetFieldID(clazz, "mIsLinear", "Ljava/lang/Boolean;");
-                jobject newBooleanObj = env->NewObject(booleanClazz, initBoolean,
-                                                       s.get<FrontendStatus::Tag::isLinear>());
-                env->SetObjectField(statusObj, field, newBooleanObj);
-                env->DeleteLocalRef(newBooleanObj);
+                ScopedLocalRef newBooleanObj(env, env->NewObject(booleanClazz, initBoolean,
+                                                       s.get<FrontendStatus::Tag::isLinear>()));
+                env->SetObjectField(statusObj, field, newBooleanObj.get());
                 break;
             }
             case FrontendStatus::Tag::isShortFrames: {
                 jfieldID field = env->GetFieldID(clazz, "mIsShortFrames", "Ljava/lang/Boolean;");
-                jobject newBooleanObj = env->NewObject(booleanClazz, initBoolean,
-                                                       s.get<FrontendStatus::Tag::isShortFrames>());
-                env->SetObjectField(statusObj, field, newBooleanObj);
-                env->DeleteLocalRef(newBooleanObj);
+                ScopedLocalRef newBooleanObj(env,
+                        env->NewObject(booleanClazz, initBoolean,
+                                s.get<FrontendStatus::Tag::isShortFrames>()));
+                env->SetObjectField(statusObj, field, newBooleanObj.get());
                 break;
             }
             case FrontendStatus::Tag::isdbtMode: {
                 jfieldID field = env->GetFieldID(clazz, "mIsdbtMode", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
-                        env->NewObject(intClazz, initInt, s.get<FrontendStatus::Tag::isdbtMode>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                ScopedLocalRef newIntegerObj(env,
+                        env->NewObject(intClazz, initInt,
+                                s.get<FrontendStatus::Tag::isdbtMode>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::partialReceptionFlag: {
                 jfieldID field =
-                        env->GetFieldID(clazz, "mIsdbtPartialReceptionFlag", "Ljava/lang/Integer;");
-                jobject newIntegerObj =
+                        env->GetFieldID(clazz, "mIsdbtPartialReceptionFlag",
+                                        "Ljava/lang/Integer;");
+                ScopedLocalRef newIntegerObj(env,
                         env->NewObject(intClazz, initInt,
-                                       s.get<FrontendStatus::Tag::partialReceptionFlag>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                                       s.get<FrontendStatus::Tag::partialReceptionFlag>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::streamIdList: {
                 jfieldID field = env->GetFieldID(clazz, "mStreamIds", "[I");
                 std::vector<int32_t> ids = s.get<FrontendStatus::Tag::streamIdList>();
 
-                jintArray valObj = env->NewIntArray(v.size());
-                env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint *>(&ids[0]));
+                ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
+                env->SetIntArrayRegion(valObj.get(), 0, v.size(),
+                                       reinterpret_cast<jint *>(&ids[0]));
 
-                env->SetObjectField(statusObj, field, valObj);
-                env->DeleteLocalRef(valObj);
+                env->SetObjectField(statusObj, field, valObj.get());
                 break;
             }
             case FrontendStatus::Tag::dvbtCellIds: {
                 jfieldID field = env->GetFieldID(clazz, "mDvbtCellIds", "[I");
                 std::vector<int32_t> ids = s.get<FrontendStatus::Tag::dvbtCellIds>();
 
-                jintArray valObj = env->NewIntArray(v.size());
-                env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast<jint *>(&ids[0]));
+                ScopedLocalRef valObj(env, env->NewIntArray(v.size()));
+                env->SetIntArrayRegion(valObj.get(), 0, v.size(),
+                                       reinterpret_cast<jint *>(&ids[0]));
 
-                env->SetObjectField(statusObj, field, valObj);
-                env->DeleteLocalRef(valObj);
+                env->SetObjectField(statusObj, field, valObj.get());
                 break;
             }
             case FrontendStatus::Tag::allPlpInfo: {
                 jfieldID field = env->GetFieldID(clazz, "mAllPlpInfo",
-                                                 "[Landroid/media/tv/tuner/frontend/Atsc3PlpInfo;");
-                jclass plpClazz = env->FindClass("android/media/tv/tuner/frontend/Atsc3PlpInfo");
-                jmethodID initPlp = env->GetMethodID(plpClazz, "<init>", "(IZ)V");
+                        "[Landroid/media/tv/tuner/frontend/Atsc3PlpInfo;");
+                ScopedLocalRef plpClazz(env,
+                        env->FindClass("android/media/tv/tuner/frontend/Atsc3PlpInfo"));
+                jmethodID initPlp = env->GetMethodID(plpClazz.get(), "<init>", "(IZ)V");
 
                 vector<FrontendScanAtsc3PlpInfo> plpInfos =
                         s.get<FrontendStatus::Tag::allPlpInfo>();
-                jobjectArray valObj = env->NewObjectArray(plpInfos.size(), plpClazz, nullptr);
+                ScopedLocalRef valObj(env, env->NewObjectArray(plpInfos.size(), plpClazz.get(),
+                                                               nullptr));
                 for (int i = 0; i < plpInfos.size(); i++) {
-                    jobject plpObj = env->NewObject(plpClazz, initPlp, plpInfos[i].plpId,
-                                                    plpInfos[i].bLlsFlag);
-                    env->SetObjectArrayElement(valObj, i, plpObj);
-                    env->DeleteLocalRef(plpObj);
+                    ScopedLocalRef plpObj(env, env->NewObject(plpClazz.get(), initPlp,
+                                                              plpInfos[i].plpId,
+                                                              plpInfos[i].bLlsFlag));
+                    env->SetObjectArrayElement(valObj.get(), i, plpObj.get());
                 }
 
-                env->SetObjectField(statusObj, field, valObj);
-                env->DeleteLocalRef(valObj);
-                env->DeleteLocalRef(plpClazz);
+                env->SetObjectField(statusObj, field, valObj.get());
                 break;
             }
             case FrontendStatus::Tag::iptvContentUrl: {
                 jfieldID field = env->GetFieldID(clazz, "mIptvContentUrl", "Ljava/lang/String;");
                 std::string iptvContentUrl = s.get<FrontendStatus::Tag::iptvContentUrl>();
-                jstring iptvContentUrlUtf8 = env->NewStringUTF(iptvContentUrl.c_str());
-                env->SetObjectField(statusObj, field, iptvContentUrlUtf8);
-                env->DeleteLocalRef(iptvContentUrlUtf8);
+                ScopedLocalRef iptvContentUrlUtf8(env, env->NewStringUTF(iptvContentUrl.c_str()));
+                env->SetObjectField(statusObj, field, iptvContentUrlUtf8.get());
                 break;
             }
             case FrontendStatus::Tag::iptvPacketsLost: {
                 jfieldID field = env->GetFieldID(clazz, "mIptvPacketsLost", "Ljava/lang/Long;");
-                jobject newLongObj =
+                ScopedLocalRef newLongObj(env,
                         env->NewObject(longClazz, initLong,
-                                       s.get<FrontendStatus::Tag::iptvPacketsLost>());
-                env->SetObjectField(statusObj, field, newLongObj);
-                env->DeleteLocalRef(newLongObj);
+                                       s.get<FrontendStatus::Tag::iptvPacketsLost>()));
+                env->SetObjectField(statusObj, field, newLongObj.get());
                 break;
             }
             case FrontendStatus::Tag::iptvPacketsReceived: {
-                jfieldID field = env->GetFieldID(clazz, "mIptvPacketsReceived", "Ljava/lang/Long;");
-                jobject newLongObj =
+                jfieldID field = env->GetFieldID(clazz, "mIptvPacketsReceived",
+                                                 "Ljava/lang/Long;");
+                ScopedLocalRef newLongObj(env,
                         env->NewObject(longClazz, initLong,
-                                       s.get<FrontendStatus::Tag::iptvPacketsReceived>());
-                env->SetObjectField(statusObj, field, newLongObj);
-                env->DeleteLocalRef(newLongObj);
+                                       s.get<FrontendStatus::Tag::iptvPacketsReceived>()));
+                env->SetObjectField(statusObj, field, newLongObj.get());
                 break;
             }
             case FrontendStatus::Tag::iptvWorstJitterMs: {
                 jfieldID field = env->GetFieldID(clazz, "mIptvWorstJitterMs",
                                                  "Ljava/lang/Integer;");
-                jobject newIntegerObj =
+                ScopedLocalRef newIntegerObj(env,
                         env->NewObject(intClazz, initInt,
-                                       s.get<FrontendStatus::Tag::iptvWorstJitterMs>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                                       s.get<FrontendStatus::Tag::iptvWorstJitterMs>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
             case FrontendStatus::Tag::iptvAverageJitterMs: {
                 jfieldID field = env->GetFieldID(clazz, "mIptvAverageJitterMs",
                                                  "Ljava/lang/Integer;");
-                jobject newIntegerObj =
+                ScopedLocalRef newIntegerObj(env,
                         env->NewObject(intClazz, initInt,
-                                       s.get<FrontendStatus::Tag::iptvAverageJitterMs>());
-                env->SetObjectField(statusObj, field, newIntegerObj);
-                env->DeleteLocalRef(newIntegerObj);
+                                       s.get<FrontendStatus::Tag::iptvAverageJitterMs>()));
+                env->SetObjectField(statusObj, field, newIntegerObj.get());
                 break;
             }
         }
@@ -3089,21 +3041,22 @@
     vector<FrontendAtsc3PlpSettings> plps = vector<FrontendAtsc3PlpSettings>(len);
     // parse PLP settings
     for (int i = 0; i < len; i++) {
-        jobject plp = env->GetObjectArrayElement(plpSettings, i);
-        int32_t plpId = env->GetIntField(plp, env->GetFieldID(plpClazz, "mPlpId", "I"));
+        ScopedLocalRef plp(env, env->GetObjectArrayElement(plpSettings, i));
+        int32_t plpId = env->GetIntField(plp.get(), env->GetFieldID(plpClazz, "mPlpId", "I"));
         FrontendAtsc3Modulation modulation =
                 static_cast<FrontendAtsc3Modulation>(
-                        env->GetIntField(plp, env->GetFieldID(plpClazz, "mModulation", "I")));
+                        env->GetIntField(plp.get(), env->GetFieldID(plpClazz, "mModulation",
+                                                                    "I")));
         FrontendAtsc3TimeInterleaveMode interleaveMode =
                 static_cast<FrontendAtsc3TimeInterleaveMode>(
                         env->GetIntField(
-                                plp, env->GetFieldID(plpClazz, "mInterleaveMode", "I")));
+                                plp.get(), env->GetFieldID(plpClazz, "mInterleaveMode", "I")));
         FrontendAtsc3CodeRate codeRate =
                 static_cast<FrontendAtsc3CodeRate>(
-                        env->GetIntField(plp, env->GetFieldID(plpClazz, "mCodeRate", "I")));
+                        env->GetIntField(plp.get(), env->GetFieldID(plpClazz, "mCodeRate", "I")));
         FrontendAtsc3Fec fec =
                 static_cast<FrontendAtsc3Fec>(
-                        env->GetIntField(plp, env->GetFieldID(plpClazz, "mFec", "I")));
+                        env->GetIntField(plp.get(), env->GetFieldID(plpClazz, "mFec", "I")));
         FrontendAtsc3PlpSettings frontendAtsc3PlpSettings {
                 .plpId = plpId,
                 .modulation = modulation,
@@ -3112,7 +3065,6 @@
                 .fec = fec,
         };
         plps[i] = frontendAtsc3PlpSettings;
-        env->DeleteLocalRef(plp);
     }
     return plps;
 }
@@ -3457,18 +3409,17 @@
             "android/media/tv/tuner/frontend/IsdbtFrontendSettings$IsdbtLayerSettings");
     frontendIsdbtSettings.layerSettings.resize(len);
     for (int i = 0; i < len; i++) {
-        jobject layer = env->GetObjectArrayElement(layerSettings, i);
+        ScopedLocalRef layer(env, env->GetObjectArrayElement(layerSettings, i));
         frontendIsdbtSettings.layerSettings[i].modulation = static_cast<FrontendIsdbtModulation>(
-                env->GetIntField(layer, env->GetFieldID(layerClazz, "mModulation", "I")));
+                env->GetIntField(layer.get(), env->GetFieldID(layerClazz, "mModulation", "I")));
         frontendIsdbtSettings.layerSettings[i].timeInterleave =
                 static_cast<FrontendIsdbtTimeInterleaveMode>(
-                        env->GetIntField(layer,
+                        env->GetIntField(layer.get(),
                                          env->GetFieldID(layerClazz, "mTimeInterleaveMode", "I")));
         frontendIsdbtSettings.layerSettings[i].coderate = static_cast<FrontendIsdbtCoderate>(
-                env->GetIntField(layer, env->GetFieldID(layerClazz, "mCodeRate", "I")));
+                env->GetIntField(layer.get(), env->GetFieldID(layerClazz, "mCodeRate", "I")));
         frontendIsdbtSettings.layerSettings[i].numOfSegment =
-                env->GetIntField(layer, env->GetFieldID(layerClazz, "mNumOfSegments", "I"));
-        env->DeleteLocalRef(layer);
+                env->GetIntField(layer.get(), env->GetFieldID(layerClazz, "mNumOfSegments", "I"));
     }
 
     frontendSettings.set<FrontendSettings::Tag::isdbt>(frontendIsdbtSettings);
@@ -3498,7 +3449,8 @@
                     env->GetIntField(settings, env->GetFieldID(clazz, "mGuardInterval", "I")));
     FrontendDtmbTimeInterleaveMode interleaveMode =
             static_cast<FrontendDtmbTimeInterleaveMode>(
-                    env->GetIntField(settings, env->GetFieldID(clazz, "mTimeInterleaveMode", "I")));
+                    env->GetIntField(settings, env->GetFieldID(clazz, "mTimeInterleaveMode",
+                                                               "I")));
 
     FrontendDtmbSettings frontendDtmbSettings{
             .frequency = freq,
@@ -3515,7 +3467,8 @@
     return frontendSettings;
 }
 
-static DemuxIpAddress getDemuxIpAddress(JNIEnv *env, const jobject& config, const char* className) {
+static DemuxIpAddress getDemuxIpAddress(JNIEnv *env, const jobject& config,
+                                        const char* className) {
     jclass clazz = env->FindClass(className);
 
     jbyteArray jsrcIpAddress = static_cast<jbyteArray>(
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index 6b1b6b1..01c998d 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -163,17 +163,19 @@
     jmethodID mRestartEventInitID;
     jfieldID mMediaEventFieldContextID;
     bool mSharedFilter;
-    void getSectionEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
-    void getMediaEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
-    void getPesEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
-    void getTsRecordEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
-    void getMmtpRecordEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
-    void getDownloadEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
-    void getIpPayloadEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
-    void getTemiEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
-    void getScramblingStatusEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
-    void getIpCidChangeEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
-    void getRestartEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+    void getSectionEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+    void getMediaEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+    void getPesEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+    void getTsRecordEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+    void getMmtpRecordEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+    void getDownloadEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+    void getIpPayloadEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+    void getTemiEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
+    void getScramblingStatusEvent(const jobjectArray& arr, const int size,
+                                  const DemuxFilterEvent& event);
+    void getIpCidChangeEvent(const jobjectArray& arr, const int size,
+                             const DemuxFilterEvent& event);
+    void getRestartEvent(const jobjectArray& arr, const int size, const DemuxFilterEvent& event);
 };
 
 struct JTuner;
diff --git a/media/jni/soundpool/Stream.cpp b/media/jni/soundpool/Stream.cpp
index 4194a22..45dde74 100644
--- a/media/jni/soundpool/Stream.cpp
+++ b/media/jni/soundpool/Stream.cpp
@@ -282,8 +282,6 @@
             priority, loop, rate, playerIId);
 
     // initialize track
-    const audio_stream_type_t streamType =
-            AudioSystem::attributesToStreamType(*mStreamManager->getAttributes());
     const int32_t channelCount = sound->getChannelCount();
     const auto sampleRate = (uint32_t)lround(double(sound->getSampleRate()) * rate);
     size_t frameCount = 0;
@@ -328,8 +326,8 @@
         attributionSource.token = sp<BBinder>::make();
         mCallback =  sp<StreamCallback>::make(this, toggle),
         // TODO b/182469354 make consistent with AudioRecord, add util for native source
-        mAudioTrack = new AudioTrack(streamType, sampleRate, sound->getFormat(),
-                channelMask, sound->getIMemory(), AUDIO_OUTPUT_FLAG_FAST,
+        mAudioTrack = new AudioTrack(AUDIO_STREAM_DEFAULT, sampleRate, sound->getFormat(),
+                channelMask, sound->getIMemory(), AUDIO_OUTPUT_FLAG_NONE,
                 mCallback,
                 0 /*default notification frames*/, AUDIO_SESSION_ALLOCATE,
                 AudioTrack::TRANSFER_DEFAULT,
diff --git a/media/jni/soundpool/StreamManager.cpp b/media/jni/soundpool/StreamManager.cpp
index acd4bad..52060f1 100644
--- a/media/jni/soundpool/StreamManager.cpp
+++ b/media/jni/soundpool/StreamManager.cpp
@@ -109,7 +109,10 @@
         int32_t streams, size_t threads, const audio_attributes_t& attributes,
         std::string opPackageName)
     : StreamMap(streams)
-    , mAttributes(attributes)
+    , mAttributes([attributes](){
+        audio_attributes_t attr = attributes;
+        attr.flags = static_cast<audio_flags_mask_t>(attr.flags | AUDIO_FLAG_LOW_LATENCY);
+        return attr; }())
     , mOpPackageName(std::move(opPackageName))
     , mLockStreamManagerStop(streams == 1 || kForceLockStreamManagerStop)
 {
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 27666caa..b3628fa 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -69,7 +69,7 @@
 
     int updateTargetWorkDuration(int64_t targetDurationNanos);
     int reportActualWorkDuration(int64_t actualDurationNanos);
-    int sendHint(int32_t hint);
+    int sendHint(SessionHint hint);
     int setThreads(const int32_t* threadIds, size_t size);
     int getThreadIds(int32_t* const threadIds, size_t* size);
 
@@ -243,7 +243,7 @@
     return 0;
 }
 
-int APerformanceHintSession::sendHint(int32_t hint) {
+int APerformanceHintSession::sendHint(SessionHint hint) {
     if (hint < 0 || hint >= static_cast<int32_t>(mLastHintSentTimestamp.size())) {
         ALOGE("%s: invalid session hint %d", __FUNCTION__, hint);
         return EINVAL;
@@ -335,7 +335,7 @@
     delete session;
 }
 
-int APerformanceHint_sendHint(void* session, int32_t hint) {
+int APerformanceHint_sendHint(void* session, SessionHint hint) {
     return reinterpret_cast<APerformanceHintSession*>(session)->sendHint(hint);
 }
 
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index 321a7dd..791adfd 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -127,7 +127,7 @@
     result = APerformanceHint_reportActualWorkDuration(session, -1L);
     EXPECT_EQ(EINVAL, result);
 
-    int hintId = 2;
+    SessionHint hintId = SessionHint::CPU_LOAD_RESET;
     EXPECT_CALL(*iSession, sendHint(Eq(hintId))).Times(Exactly(1));
     result = APerformanceHint_sendHint(session, hintId);
     EXPECT_EQ(0, result);
@@ -140,7 +140,7 @@
     result = APerformanceHint_sendHint(session, hintId);
     EXPECT_EQ(0, result);
 
-    result = APerformanceHint_sendHint(session, -1);
+    result = APerformanceHint_sendHint(session, static_cast<SessionHint>(-1));
     EXPECT_EQ(EINVAL, result);
 
     EXPECT_CALL(*iSession, close()).Times(Exactly(1));
diff --git a/packages/CarrierDefaultApp/res/values-ja/strings.xml b/packages/CarrierDefaultApp/res/values-ja/strings.xml
index 2bcdaac..f5d85d5 100644
--- a/packages/CarrierDefaultApp/res/values-ja/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ja/strings.xml
@@ -16,7 +16,7 @@
     <string name="ssl_error_continue" msgid="1138548463994095584">"ブラウザから続行"</string>
     <string name="performance_boost_notification_channel" msgid="3475440855635538592">"パフォーマンス ブースト"</string>
     <string name="performance_boost_notification_title" msgid="3126203390685781861">"ご利用の携帯通信会社の 5G オプション"</string>
-    <string name="performance_boost_notification_detail" msgid="216569851036236346">"アプリのパフォーマンスを向上させるためのオプションを確認するには、%s のウェブサイトにアクセスしてください"</string>
+    <string name="performance_boost_notification_detail" msgid="216569851036236346">"アプリの性能を向上させるためのオプションは、%s のウェブサイトにアクセスして確認してください"</string>
     <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"後で"</string>
     <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"管理"</string>
     <string name="slice_purchase_app_label" msgid="7170191659233241166">"パフォーマンス ブーストを購入してください。"</string>
diff --git a/packages/CarrierDefaultApp/res/values-mr/strings.xml b/packages/CarrierDefaultApp/res/values-mr/strings.xml
index a2b3812..2a6b9d9 100644
--- a/packages/CarrierDefaultApp/res/values-mr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-mr/strings.xml
@@ -12,7 +12,7 @@
     <string name="mobile_data_status_notification_channel_name" msgid="833999690121305708">"मोबाइल डेटा स्थिती"</string>
     <string name="action_bar_label" msgid="4290345990334377177">"मोबाइल नेटवर्कमध्ये साइन इन करा"</string>
     <string name="ssl_error_warning" msgid="3127935140338254180">"तुम्ही ज्या नेटवर्कमध्‍ये सामील होण्याचा प्रयत्न करत आहात त्यात सुरक्षितता समस्या आहेत."</string>
-    <string name="ssl_error_example" msgid="6188711843183058764">"उदाहरणार्थ, लॉग इन पेज दर्शवलेल्या संस्थेच्या मालकीचे नसू शकते."</string>
+    <string name="ssl_error_example" msgid="6188711843183058764">"उदाहरणार्थ, लॉग इन पेज कदाचित दर्शवलेल्या संस्थेशी संबंधित नसेल."</string>
     <string name="ssl_error_continue" msgid="1138548463994095584">"तरीही ब्राउझरद्वारे सुरू ठेवा"</string>
     <string name="performance_boost_notification_channel" msgid="3475440855635538592">"परफॉर्मन्स बूस्ट"</string>
     <string name="performance_boost_notification_title" msgid="3126203390685781861">"तुमच्या वाहकाकडून 5G पर्याय"</string>
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java
index b8887390..946185a 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/SlicePurchaseActivity.java
@@ -24,6 +24,7 @@
 import android.os.Bundle;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.webkit.WebView;
@@ -183,7 +184,14 @@
         setContentView(mWebView);
 
         // Load the URL
-        mWebView.loadUrl(mUrl.toString());
+        String userData = mIntent.getStringExtra(SlicePurchaseController.EXTRA_USER_DATA);
+        if (TextUtils.isEmpty(userData)) {
+            logd("Starting WebView with url: " + mUrl.toString());
+            mWebView.loadUrl(mUrl.toString());
+        } else {
+            logd("Starting WebView with url: " + mUrl.toString() + ", userData=" + userData);
+            mWebView.postUrl(mUrl.toString(), userData.getBytes());
+        }
     }
 
     private static void logd(@NonNull String s) {
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index 081e71a..4df4177 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
     <string name="confirmation_title" msgid="4593465730772390351">"Да се разреши ли на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да осъществява достъп до устройството &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"часовник"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Изберете устройство (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), което да се управлява от &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Изберете <xliff:g id="PROFILE_NAME">%1$s</xliff:g> за управление от &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="summary_watch" msgid="898569637110705523">"Това приложение е необходимо за управление на <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ще получи право да синхронизира различна информация, като например името на обаждащия се, да взаимодейства с известията ви и достъп до разрешенията за телефона, SMS съобщенията, контактите, календара, списъците с обажданията и устройствата в близост."</string>
     <string name="summary_watch_single_device" msgid="3173948915947011333">"Това приложение ще получи право да синхронизира различна информация, като например името на обаждащия се, и достъп до следните разрешения за вашия <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"Разрешавате ли на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да управлява устройството &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index 0a1ef7b..735b620 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -35,7 +35,7 @@
     <string name="summary_computer" msgid="3798467601598297062"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play পরিষেবা"</string>
     <string name="helper_summary_computer" msgid="8774832742608187072">"আপনার ফোনের ফটো, মিডিয়া এবং তথ্য অ্যাক্সেস করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string>
-    <string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;কে এই অ্যাকশন করতে দেবেন?"</string>
+    <string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;-কে এই কাজটি করতে দেবেন?"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"আশেপাশের ডিভাইসে অ্যাপ ও অন্যান্য সিস্টেম ফিচার স্ট্রিম করার জন্য আপনার <xliff:g id="DEVICE_NAME">%2$s</xliff:g>-এর হয়ে <xliff:g id="APP_NAME">%1$s</xliff:g> অনুমতি চেয়ে অনুরোধ করছে"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইস"</string>
     <string name="summary_generic_single_device" msgid="4181180669689590417">"এই অ্যাপ, আপনার ফোন এবং <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ডিভাইসের মধ্যে তথ্য সিঙ্ক করতে পারবে, যেমন কোনও কলারের নাম"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index da158e0..2de0838 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"Prateći upravitelj uređaja"</string>
     <string name="confirmation_title" msgid="4593465730772390351">"Dozvoliti aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa uređaju &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"sat"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Odaberite uređaj \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Odaberite profil \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="summary_watch" msgid="898569637110705523">"Ova aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikaciji <xliff:g id="APP_NAME">%2$s</xliff:g> će biti dozvoljeni sinhroniziranje informacija, kao što je ime osobe koja upućuje poziv, interakcija s obavještenjima i pristup odobrenjima za Telefon, SMS, Kontakte, Kalendar, Zapisnike poziva i Uređaje u blizini."</string>
     <string name="summary_watch_single_device" msgid="3173948915947011333">"Aplikaciji će biti dozvoljeni sinhroniziranje informacija, kao što je ime osobe koja upućuje poziv i pristup ovim odobrenjima na uređaju <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"Dozvoliti aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da upravlja uređajem &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index fbfbac7..7151823 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"Správce doprovodných zařízení"</string>
     <string name="confirmation_title" msgid="4593465730772390351">"Povolit aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; přístup k &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Vyberte zařízení <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, které chcete spravovat pomocí aplikace &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Vyberte <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, které chcete spravovat pomocí aplikace &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="summary_watch" msgid="898569637110705523">"Tato aplikace je nutná ke správě zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude moci synchronizovat údaje, jako je jméno volajícího, interagovat s vašimi oznámeními a získat přístup k vašim oprávněním k telefonu, SMS, kontaktům, kalendáři, seznamům hovorů a zařízením v okolí."</string>
     <string name="summary_watch_single_device" msgid="3173948915947011333">"Tato aplikace bude moci synchronizovat údaje, jako je jméno volajícího, a získat přístup k těmto oprávněním v <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"Povolit aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; spravovat zařízení &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index 2b4eb80..a4f29e3 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -24,7 +24,7 @@
     <string name="summary_watch_single_device" msgid="3173948915947011333">"<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>n informazioa sinkronizatu (esate baterako, deitzaileen izenak) eta baimen hauek erabili ahalko ditu aplikazioak"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; kudeatzeko baimena eman nahi diozu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari?"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"betaurrekoak"</string>
-    <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailua kudeatzeko behar da aplikazioa. Jakinarazpenekin interakzioan aritzeko, eta telefonoa, SMSak, kontaktuak, mikrofonoa eta inguruko gailuak erabiltzeko baimena izango du <xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioak."</string>
+    <string name="summary_glasses_multi_device" msgid="615259525961937348">"Aplikazioa \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" izeneko gailua kudeatzeko behar da. Jakinarazpenekin interakzioan aritzeko, eta telefonoa, SMSak, kontaktuak, mikrofonoa eta inguruko gailuak erabiltzeko baimena izango du <xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioak."</string>
     <string name="summary_glasses_single_device" msgid="3000909894067413398">"<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>n baimen hauek erabili ahalko ditu aplikazioak:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Eman informazioa telefonotik hartzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Gailu baterako baino gehiagotarako zerbitzuak"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index 9f0adfe..d6c1a13 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -24,7 +24,7 @@
     <string name="summary_watch_single_device" msgid="3173948915947011333">"به این برنامه اجازه داده می‌شود اطلاعاتی مثل نام تماس‌گیرنده را همگام‌سازی کند و به این اجازه‌ها در <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> شما دسترسی داشته باشد"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"‏به &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; اجازه داده شود &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; را مدیریت کند؟"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"عینک"</string>
-    <string name="summary_glasses_multi_device" msgid="615259525961937348">"این برنامه برای مدیریت <xliff:g id="DEVICE_NAME">%1$s</xliff:g> لازم است. به <xliff:g id="APP_NAME">%2$s</xliff:g> اجازه داده می‌شود با اعلان‌های شما تعامل داشته باشد و به اجازه‌های «تلفن»، «پیامک»، «مخاطبین»، «میکروفون»، و «دستگاه‌های اطراف» دسترسی داشته باشد."</string>
+    <string name="summary_glasses_multi_device" msgid="615259525961937348">"این برنامه برای مدیریت <xliff:g id="DEVICE_NAME">%1$s</xliff:g> لازم است. به <xliff:g id="APP_NAME">%2$s</xliff:g> اجازه داده می‌شود با اعلان‌های شما تعامل داشته باشد و به اجازه‌های تلفنتان، پیامک، «مخاطبین»، «میکروفون»، و «دستگاه‌های اطراف» دسترسی داشته باشد."</string>
     <string name="summary_glasses_single_device" msgid="3000909894067413398">"این برنامه مجاز می‌شود به این اجازه‌ها در <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> شما دسترسی پیدا کند"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"‏اجازه دادن به &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; برای دسترسی به اطلاعات تلفن"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"سرویس‌های بین‌دستگاهی"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index 12bf0d3..72122cb 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -24,7 +24,7 @@
     <string name="summary_watch_single_device" msgid="3173948915947011333">"Sovellus saa luvan synkronoida tietoja (esimerkiksi soittajan nimen) ja pääsyn näihin lupiin laitteella (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>)"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"Salli, että &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; saa ylläpitää laitetta: &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"lasit"</string>
-    <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> edellyttää ylläpitoon tätä sovellusta. <xliff:g id="APP_NAME">%2$s</xliff:g> saa luvan hallinnoida ilmoituksiasi sekä pääsyn puhelimeen, tekstiviesteihin, yhteystietoihin, mikrofoniin ja lähellä olevat laitteet ‑lupiin."</string>
+    <string name="summary_glasses_multi_device" msgid="615259525961937348">"Tätä sovellusta tarvitaan kohteen <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ylläpitoon. <xliff:g id="APP_NAME">%2$s</xliff:g> saa luvan hallinnoida ilmoituksiasi sekä pääsyn puhelimeen, tekstiviesteihin, yhteystietoihin, mikrofoniin ja lähellä olevat laitteet ‑lupiin."</string>
     <string name="summary_glasses_single_device" msgid="3000909894067413398">"Tämä sovellus saa käyttää näitä lupia laitteella (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>)"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Salli, että &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; saa pääsyn näihin puhelimesi tietoihin"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Laitteidenväliset palvelut"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index d769dc7..6b3ed28 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -24,7 +24,7 @@
     <string name="summary_watch_single_device" msgid="3173948915947011333">"Cette application sera autorisée à synchroniser des informations, comme le nom de l\'appelant, et à accéder à ces autorisations sur votre <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à gérer &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"lunettes"</string>
-    <string name="summary_glasses_multi_device" msgid="615259525961937348">"Cette application est nécessaire pour gérer <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> sera autorisée à interagir avec vos notifications et à accéder à vos autorisations pour le téléphone, les messages texte, les contacts, le microphone et les appareils à proximité."</string>
+    <string name="summary_glasses_multi_device" msgid="615259525961937348">"Cette application est nécessaire pour gérer vos <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. L\'application <xliff:g id="APP_NAME">%2$s</xliff:g> sera autorisée à interagir avec vos notifications et à accéder à vos autorisations pour le téléphone, les messages texte, les contacts, le microphone et les appareils à proximité."</string>
     <string name="summary_glasses_single_device" msgid="3000909894067413398">"Cette application pourra accéder à ces autorisations sur votre <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Autorisez &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations à partir de votre téléphone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Services multiappareils"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index 1d3f4f9..dd8e831 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -24,7 +24,7 @@
     <string name="summary_watch_single_device" msgid="3173948915947011333">"यह ऐप्लिकेशन, आपके <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> पर इन अनुमतियों को ऐक्सेस करने के साथ-साथ कॉल करने वाले व्यक्ति के नाम जैसी जानकारी सिंक कर पाएगा"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"क्या &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; मैनेज करने की अनुमति देनी है?"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"चश्मा"</string>
-    <string name="summary_glasses_multi_device" msgid="615259525961937348">"यह ऐप्लिकेशन, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> को मैनेज करने के लिए ज़रूरी है. <xliff:g id="APP_NAME">%2$s</xliff:g> को डिवाइस की सूचनाओं पर कार्रवाई करने की अनुमति होगी. इसे आपके फ़ोन, मैसेज, संपर्कों, माइक्रोफ़ोन, और आस-पास मौजूद डिवाइसों को ऐक्सेस करने की अनुमति भी होगी."</string>
+    <string name="summary_glasses_multi_device" msgid="615259525961937348">"यह ऐप्लिकेशन, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> मैनेज करने के लिए ज़रूरी है. <xliff:g id="APP_NAME">%2$s</xliff:g> को डिवाइस की सूचनाओं पर कार्रवाई करने की अनुमति होगी. इसे आपके फ़ोन, मैसेज, संपर्कों, माइक्रोफ़ोन, और आस-पास मौजूद डिवाइसों को ऐक्सेस करने की अनुमति भी होगी."</string>
     <string name="summary_glasses_single_device" msgid="3000909894067413398">"यह ऐप्लिकेशन, आपके <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> पर इन अनुमतियों को ऐक्सेस कर पाएगा"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिवाइस से जुड़ी सेवाएं"</string>
@@ -69,7 +69,7 @@
     <string name="permission_notification_summary" msgid="884075314530071011">"इससे सभी सूचनाएं देखी जा सकती हैं. इनमें संपर्क, मैसेज, और फ़ोटो जैसी जानकारी शामिल होती है"</string>
     <string name="permission_app_streaming_summary" msgid="606923325679670624">"अपने फ़ोन पर मौजूद ऐप्लिकेशन स्ट्रीम करें"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
-    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"अपने फ़ोन से ऐप्लिकेशन और दूसरे सिस्टम की सुविधाओं को स्ट्रीम करें"</string>
+    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"अपने फ़ोन से ऐप्लिकेशन और सिस्टम की दूसरी सुविधाओं को स्ट्रीम करें"</string>
     <string name="device_type" product="default" msgid="8268703872070046263">"फ़ोन"</string>
     <string name="device_type" product="tablet" msgid="5038791954983067774">"टैबलेट"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index 1e64bbd..d32a319 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -35,7 +35,7 @@
     <string name="summary_computer" msgid="3798467601598297062"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Usluge za Google Play"</string>
     <string name="helper_summary_computer" msgid="8774832742608187072">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> za pristup fotografijama, medijskim sadržajima i obavijestima na telefonu"</string>
-    <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Dopustiti &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; da izvede tu radnju?"</string>
+    <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Želite li uređaju &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; dopustiti da izvrši tu radnju?"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_NAME">%2$s</xliff:g> za emitiranje aplikacija i drugih značajki sustava na uređajima u blizini"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
     <string name="summary_generic_single_device" msgid="4181180669689590417">"Ta će aplikacija moći sinkronizirati podatke između vašeg telefona i uređaja <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, primjerice ime pozivatelja"</string>
@@ -69,7 +69,7 @@
     <string name="permission_notification_summary" msgid="884075314530071011">"Može čitati sve obavijesti, uključujući informacije kao što su kontakti, poruke i fotografije"</string>
     <string name="permission_app_streaming_summary" msgid="606923325679670624">"Streaming aplikacija vašeg telefona"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
-    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Emitiranje aplikacija i drugih značajki sustava s vašeg telefona"</string>
+    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Emitirajte stream aplikacija i drugih značajki sustava s vašeg telefona"</string>
     <string name="device_type" product="default" msgid="8268703872070046263">"telefonu"</string>
     <string name="device_type" product="tablet" msgid="5038791954983067774">"tabletu"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index 992acd2..ec736197 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -23,7 +23,7 @@
     <string name="summary_watch" msgid="898569637110705523">"Aplikasi ini diperlukan untuk mengelola <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> akan diizinkan menyinkronkan info, seperti nama penelepon, berinteraksi dengan notifikasi, dan mengakses izin Telepon, SMS, Kontak, Kalender, Log panggilan, dan Perangkat di sekitar."</string>
     <string name="summary_watch_single_device" msgid="3173948915947011333">"Aplikasi ini akan diizinkan menyinkronkan info, seperti nama penelepon, dan mengakses izin ini di <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> Anda"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"Izinkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengelola &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
-    <string name="profile_name_glasses" msgid="8488394059007275998">"glasses"</string>
+    <string name="profile_name_glasses" msgid="8488394059007275998">"kacamata pintar"</string>
     <string name="summary_glasses_multi_device" msgid="615259525961937348">"Aplikasi ini diperlukan untuk mengelola <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> akan diizinkan berinteraksi dengan notifikasi dan mengakses izin Ponsel, SMS, Kontak, Mikrofon, dan Perangkat di sekitar."</string>
     <string name="summary_glasses_single_device" msgid="3000909894067413398">"Aplikasi ini akan diizinkan mengakses izin ini di <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> Anda"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Izinkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengakses informasi ini dari ponsel Anda"</string>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index f3e9ec2..9f7679b 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -69,7 +69,7 @@
     <string name="permission_notification_summary" msgid="884075314530071011">"Puoi leggere tutte le notifiche, incluse le informazioni come contatti, messaggi e foto"</string>
     <string name="permission_app_streaming_summary" msgid="606923325679670624">"Trasmetti in streaming le app del tuo telefono"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
-    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Consente di trasmettere in streaming app e altre funzionalità di sistema dal telefono"</string>
+    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Trasmettere in streaming app e altre funzionalità di sistema dal telefono"</string>
     <string name="device_type" product="default" msgid="8268703872070046263">"telefono"</string>
     <string name="device_type" product="tablet" msgid="5038791954983067774">"tablet"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index 8d7d1e9..573b8a7 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -24,7 +24,7 @@
     <string name="summary_watch_single_device" msgid="3173948915947011333">"האפליקציה הזו תוכל לסנכרן מידע, כמו השם של מישהו שמתקשר, ולגשת להרשאות האלה ב<xliff:g id="DEVICE_TYPE">%1$s</xliff:g> שלך"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"‏מתן הרשאה לאפליקציה ‎&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&amp;g;‎‏ לנהל את ‎&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;‎‏"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"משקפיים"</string>
-    <string name="summary_glasses_multi_device" msgid="615259525961937348">"‏האפליקציה הזו נחוצה כדי לנהל את <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. האפליקציה <xliff:g id="APP_NAME">%2$s</xliff:g> תוכל לבצע פעולות בהתראות ותקבל הרשאות גישה לטלפון, ל-SMS לאנשי הקשר, למיקרופון ולמכשירים בקרבת מקום."</string>
+    <string name="summary_glasses_multi_device" msgid="615259525961937348">"‏האפליקציה הזו נחוצה כדי לנהל את \'<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\'. האפליקציה <xliff:g id="APP_NAME">%2$s</xliff:g> תוכל לבצע פעולות בהתראות ותקבל הרשאות גישה לטלפון, ל-SMS, לאנשי הקשר, למיקרופון ולמכשירים בקרבת מקום."</string>
     <string name="summary_glasses_single_device" msgid="3000909894067413398">"האפליקציה הזו תוכל לגשת להרשאות האלה ב<xliff:g id="DEVICE_TYPE">%1$s</xliff:g> שלך"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"‏מתן אישור לאפליקציה &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; לגשת למידע הזה מהטלפון שלך"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"שירותים למספר מכשירים"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 025bc3c..8128d8a 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"부속 기기 관리자"</string>
     <string name="confirmation_title" msgid="4593465730772390351">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;에서 &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;에 액세스하도록 허용하시겠습니까?"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"시계"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;에서 관리할 <xliff:g id="PROFILE_NAME">%1$s</xliff:g>을(를) 선택"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;에서 관리할 <xliff:g id="PROFILE_NAME">%1$s</xliff:g>를 선택"</string>
     <string name="summary_watch" msgid="898569637110705523">"이 앱은 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 기기를 관리하는 데 필요합니다. <xliff:g id="APP_NAME">%2$s</xliff:g>에서 정보(예: 발신자 이름)를 동기화하고, 알림과 상호작용하고, 전화, SMS, 연락처, 캘린더, 통화 기록 및 근처 기기에 액세스할 수 있게 됩니다."</string>
     <string name="summary_watch_single_device" msgid="3173948915947011333">"이 앱이 정보(예: 발신자 이름)를 동기화하고 <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>에서 이러한 권한에 액세스할 수 있게 됩니다."</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;에서 &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;? 기기를 관리하도록 허용"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index 7e9104f..568a1739 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -36,7 +36,7 @@
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play кызматтары"</string>
     <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан телефондогу сүрөттөрдү, медиа файлдарды жана билдирмелерди колдонууга уруксат сурап жатат"</string>
     <string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; түзмөгүнө бул аракетти аткарууга уруксат бересизби?"</string>
-    <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан жакын жердеги түзмөктөрдө колдонмолорду жана тутумдун башка функцияларын алып ойнотууга уруксат сурап жатат"</string>
+    <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан жакын жердеги түзмөктөрдө колдонмолорду жана системанын башка функцияларын алып ойнотууга уруксат сурап жатат"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string>
     <string name="summary_generic_single_device" msgid="4181180669689590417">"Бул колдонмо маалыматты шайкештире алат, мисалы, чалып жаткан кишинин атын телефон жана <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгү менен шайкештирет"</string>
     <string name="summary_generic" msgid="1761976003668044801">"Бул колдонмо маалыматты шайкештире алат, мисалы, чалып жаткан кишинин атын телефон жана тандалган түзмөк менен шайкештирет"</string>
@@ -69,7 +69,7 @@
     <string name="permission_notification_summary" msgid="884075314530071011">"Бардык билдирмелерди, анын ичинде байланыштар, билдирүүлөр жана сүрөттөр сыяктуу маалыматты окуй алат"</string>
     <string name="permission_app_streaming_summary" msgid="606923325679670624">"Телефондогу колдонмолорду алып ойнотуу"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
-    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Телефонуңуздагы колдонмолорду жана тутумдун башка функцияларын алып ойнотуу"</string>
+    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Телефонуңуздагы колдонмолорду жана системанын башка функцияларын алып ойнотуу"</string>
     <string name="device_type" product="default" msgid="8268703872070046263">"телефон"</string>
     <string name="device_type" product="tablet" msgid="5038791954983067774">"планшет"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index 7e115c9..7d053a7 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -36,7 +36,7 @@
     <string name="helper_title_computer" msgid="4671071173916176037">"Услуги на Google Play"</string>
     <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> за да пристапува до фотографиите, аудиовизуелните содржини и известувањата на телефонот"</string>
     <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Ќе дозволите &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; да го преземе ова дејство?"</string>
-    <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_NAME">%2$s</xliff:g> за да стримува апликации и други системски карактеристики на уредите во близина"</string>
+    <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_NAME">%2$s</xliff:g> за да стримува апликации и други системски функции на уредите во близина"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"уред"</string>
     <string name="summary_generic_single_device" msgid="4181180669689590417">"Оваа апликација ќе може да ги синхронизира податоците како што се имињата на јавувачите помеѓу вашиот телефон и <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
     <string name="summary_generic" msgid="1761976003668044801">"Оваа апликација ќе може да ги синхронизира податоците како што се имињата на јавувачите помеѓу вашиот телефон и избраниот уред"</string>
@@ -69,7 +69,7 @@
     <string name="permission_notification_summary" msgid="884075314530071011">"може да ги чита сите известувања, вклучително и податоци како контакти, пораки и фотографии"</string>
     <string name="permission_app_streaming_summary" msgid="606923325679670624">"Стримувајте ги апликациите на телефонот"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
-    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Апликации за стриминг и други системски карактеристики од вашиот телефон"</string>
+    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Апликации за стриминг и други системски функции од вашиот телефон"</string>
     <string name="device_type" product="default" msgid="8268703872070046263">"Телефон"</string>
     <string name="device_type" product="tablet" msgid="5038791954983067774">"Таблет"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index 9580474..7c79cb4 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -24,7 +24,7 @@
     <string name="summary_watch_single_device" msgid="3173948915947011333">"Deze app kan informatie synchroniseren (zoals de naam van iemand die belt) en krijgt toegang tot deze rechten op je <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toestaan &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; te beheren?"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"brillen"</string>
-    <string name="summary_glasses_multi_device" msgid="615259525961937348">"Deze app is nodig om <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te beheren. <xliff:g id="APP_NAME">%2$s</xliff:g> mag interactie hebben met je meldingen en krijgt toegang tot de rechten Telefoon, Sms, Contacten, Microfoon en Apparaten in de buurt."</string>
+    <string name="summary_glasses_multi_device" msgid="615259525961937348">"Deze app is nodig om <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te beheren. <xliff:g id="APP_NAME">%2$s</xliff:g> mag interactie hebben met je meldingen en krijgt toegang tot de rechten voor Telefoon, Sms, Contacten, Microfoon en Apparaten in de buurt."</string>
     <string name="summary_glasses_single_device" msgid="3000909894067413398">"Deze app krijgt toegang tot deze rechten op je <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang geven tot deze informatie op je telefoon"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device-services"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index b1e5643..1432a45 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"Menedżer urządzeń towarzyszących"</string>
     <string name="confirmation_title" msgid="4593465730772390351">"Zezwolić na dostęp aplikacji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; do tego urządzenia (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;)?"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"zegarek"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Wybierz profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, którym ma zarządzać aplikacja &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Wybierz <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, którym ma zarządzać aplikacja &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="summary_watch" msgid="898569637110705523">"Ta aplikacja jest niezbędna do zarządzania urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacja <xliff:g id="APP_NAME">%2$s</xliff:g> będzie mogła synchronizować informacje takie jak nazwa osoby dzwoniącej, korzystać z powiadomień oraz uprawnień dotyczących telefonu, SMS-ów, kontaktów, kalendarza, rejestrów połączeń i Urządzeń w pobliżu."</string>
     <string name="summary_watch_single_device" msgid="3173948915947011333">"Aplikacja będzie mogła synchronizować informacje takie jak nazwa dzwoniącego oraz korzystać z tych uprawnień na Twoim urządzeniu (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>)"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"Zezwolić na dostęp aplikacji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; do urządzenia &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index 15980b9..c45cda6 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -35,7 +35,7 @@
     <string name="summary_computer" msgid="3798467601598297062"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
     <string name="helper_summary_computer" msgid="8774832742608187072">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone"</string>
-    <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; realize essa ação?"</string>
+    <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; realize esta ação?"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para fazer streaming de apps e de outros recursos do sistema para dispositivos por perto"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="summary_generic_single_device" msgid="4181180669689590417">"O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
@@ -69,7 +69,7 @@
     <string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contatos, mensagens e fotos"</string>
     <string name="permission_app_streaming_summary" msgid="606923325679670624">"Fazer transmissão dos apps no seu smartphone"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
-    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Faça streaming de apps e outros recursos do sistema pelo smartphone"</string>
+    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Fazer streaming de apps e outros recursos do sistema pelo smartphone"</string>
     <string name="device_type" product="default" msgid="8268703872070046263">"smartphone"</string>
     <string name="device_type" product="tablet" msgid="5038791954983067774">"tablet"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
index 0ee0904..8619ff4 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
@@ -35,7 +35,7 @@
     <string name="summary_computer" msgid="3798467601598297062"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Serviços do Google Play"</string>
     <string name="helper_summary_computer" msgid="8774832742608187072">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para aceder às fotos, ao conteúdo multimédia e às notificações do seu telemóvel"</string>
-    <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; realize esta ação?"</string>
+    <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; faça esta ação?"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para fazer stream de apps e outras funcionalidades do sistema para dispositivos próximos"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="summary_generic_single_device" msgid="4181180669689590417">"Esta app vai poder sincronizar informações, como o nome do autor de uma chamada, entre o telemóvel e o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index 15980b9..c45cda6 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -35,7 +35,7 @@
     <string name="summary_computer" msgid="3798467601598297062"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
     <string name="helper_summary_computer" msgid="8774832742608187072">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone"</string>
-    <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; realize essa ação?"</string>
+    <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; realize esta ação?"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para fazer streaming de apps e de outros recursos do sistema para dispositivos por perto"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
     <string name="summary_generic_single_device" msgid="4181180669689590417">"O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
@@ -69,7 +69,7 @@
     <string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contatos, mensagens e fotos"</string>
     <string name="permission_app_streaming_summary" msgid="606923325679670624">"Fazer transmissão dos apps no seu smartphone"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
-    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Faça streaming de apps e outros recursos do sistema pelo smartphone"</string>
+    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Fazer streaming de apps e outros recursos do sistema pelo smartphone"</string>
     <string name="device_type" product="default" msgid="8268703872070046263">"smartphone"</string>
     <string name="device_type" product="tablet" msgid="5038791954983067774">"tablet"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index cfc15a9..562e474 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"Upravitelj spremljevalnih naprav"</string>
     <string name="confirmation_title" msgid="4593465730772390351">"Želite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dovoliti dostop do naprave &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ura"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Izbira naprave »<xliff:g id="PROFILE_NAME">%1$s</xliff:g>«, ki jo bo upravljala aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Izbira profila »<xliff:g id="PROFILE_NAME">%1$s</xliff:g>«, ki ga bo upravljala aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="summary_watch" msgid="898569637110705523">"Ta aplikacija je potrebna za upravljanje naprave »<xliff:g id="DEVICE_NAME">%1$s</xliff:g>«. Aplikaciji <xliff:g id="APP_NAME">%2$s</xliff:g> bodo omogočene sinhronizacija podatkov, na primer imena klicatelja, interakcija z obvestili in uporaba dovoljenj Telefon, SMS, Stiki, Koledar, Dnevniki klicev in Naprave v bližini."</string>
     <string name="summary_watch_single_device" msgid="3173948915947011333">"Ta aplikacija bo lahko sinhronizirala podatke, na primer ime klicatelja, in dostopala do teh dovoljenj v napravi »<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>«."</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"Želite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dovoliti upravljanje naprave &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index 0bb8010..8e32ec7 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"Menaxheri i pajisjes shoqëruese"</string>
     <string name="confirmation_title" msgid="4593465730772390351">"T\'i lejohet &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; qasja te &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ora inteligjente"</string>
-    <string name="chooser_title" msgid="2262294130493605839">"Zgjidh \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" që do të menaxhohet nga &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="chooser_title" msgid="2262294130493605839">"Zgjidh që <xliff:g id="PROFILE_NAME">%1$s</xliff:g> të menaxhohet nga &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="summary_watch" msgid="898569637110705523">"Ky aplikacion nevojitet për të menaxhuar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> do të lejohet të sinkronizojë informacione, si p.sh. emrin e dikujt që po telefonon, të ndërveprojë me njoftimet e tua dhe të ketë qasje te lejet e \"Telefonit\", \"SMS-ve\", \"Kontakteve\", \"Kalendarit\", \"Evidencave të telefonatave\" dhe \"Pajisjeve në afërsi\"."</string>
     <string name="summary_watch_single_device" msgid="3173948915947011333">"Këtij aplikacioni do t\'i lejohet të sinkronizojë informacione, si p.sh. emrin e dikujt që po telefonon, si dhe të ketë qasje në këto leje në <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"Të lejohet që &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; të menaxhojë &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index a31d891..d049953 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -35,7 +35,7 @@
     <string name="summary_computer" msgid="3798467601598297062"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play சேவைகள்"</string>
     <string name="helper_summary_computer" msgid="8774832742608187072">"உங்கள் மொபைலில் உள்ள படங்கள், மீடியா, அறிவிப்புகள் ஆகியவற்றை அணுக உங்கள் <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் அனுமதியைக் கோருகிறது"</string>
-    <string name="title_nearby_device_streaming" msgid="7269956847378799794">"இந்தச் செயலைச் செய்ய &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&amp;gt சாதனத்தை அனுமதிக்கவா?"</string>
+    <string name="title_nearby_device_streaming" msgid="7269956847378799794">"இந்தச் செயலைச் செய்ய &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ஐ அனுமதிக்கவா?"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"அருகிலுள்ள சாதனங்களுக்கு ஆப்ஸையும் பிற சிஸ்டம் அம்சங்களையும் ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DEVICE_NAME">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதி கோருகிறது"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"சாதனம்"</string>
     <string name="summary_generic_single_device" msgid="4181180669689590417">"அழைப்பவரின் பெயர் போன்ற தகவலை உங்கள் மொபைல் மற்றும் <xliff:g id="DEVICE_NAME">%1$s</xliff:g> சாதனத்திற்கு இடையில் இந்த ஆப்ஸால் ஒத்திசைக்க முடியும்"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index 6358f6e..c5229ab 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -35,7 +35,7 @@
     <string name="summary_computer" msgid="3798467601598297062"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Hizmetleri"</string>
     <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g>, telefonunuzdaki fotoğraf, medya ve bildirimlere erişmek için <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
-    <string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; cihazının bu işlem yapmasına izin verilsin mi?"</string>
+    <string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; cihazının bu işlemi yapmasına izin verilsin mi?"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması <xliff:g id="DEVICE_NAME">%2$s</xliff:g> cihazınız adına uygulamaları ve diğer sistem özelliklerini yakındaki cihazlara aktarmak için izin istiyor"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
     <string name="summary_generic_single_device" msgid="4181180669689590417">"Bu uygulama, arayan kişinin adı gibi bilgileri telefonunuz ve <xliff:g id="DEVICE_NAME">%1$s</xliff:g> adlı cihaz arasında senkronize edebilir"</string>
@@ -60,16 +60,16 @@
     <string name="permission_app_streaming" msgid="6009695219091526422">"Uygulamalar"</string>
     <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Yayınlama"</string>
     <string name="permission_phone_summary" msgid="6684396967861278044">"Telefon aramaları yapabilir ve telefon aramalarını yönetebilir"</string>
-    <string name="permission_call_logs_summary" msgid="6186103394658755022">"Telefon arama kaydını okuma ve yazma"</string>
+    <string name="permission_call_logs_summary" msgid="6186103394658755022">"Telefon arama kaydını okuyabilir ve yazabilir"</string>
     <string name="permission_sms_summary" msgid="3508442683678912017">"SMS mesajları gönderebilir ve görüntüleyebilir"</string>
     <string name="permission_contacts_summary" msgid="675861979475628708">"Kişilerinize erişebilir"</string>
     <string name="permission_calendar_summary" msgid="6460000922511766226">"Takviminize erişebilir"</string>
     <string name="permission_microphone_summary" msgid="3692091540613093394">"Ses kaydedebilir"</string>
     <string name="permission_nearby_devices_summary" msgid="931940524460876655">"Yakındaki cihazları keşfedip bağlanabilir ve bu cihazların göreli konumunu belirleyebilir"</string>
     <string name="permission_notification_summary" msgid="884075314530071011">"Kişiler, mesajlar ve fotoğraflar da dahil olmak üzere tüm bildirimleri okuyabilir"</string>
-    <string name="permission_app_streaming_summary" msgid="606923325679670624">"Telefonunuzun uygulamalarını yayınlama"</string>
+    <string name="permission_app_streaming_summary" msgid="606923325679670624">"Telefonunuzun uygulamalarını yayınlayabilir"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
-    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Telefonunuzdan uygulamaları ve diğer sistem özelliklerini yayınlayın"</string>
+    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Telefonunuzdan uygulamaları ve diğer sistem özelliklerini yayınlayabilir"</string>
     <string name="device_type" product="default" msgid="8268703872070046263">"telefon"</string>
     <string name="device_type" product="tablet" msgid="5038791954983067774">"tablet"</string>
 </resources>
diff --git a/packages/CredentialManager/res/values-am/strings.xml b/packages/CredentialManager/res/values-am/strings.xml
index b2628fb..475dcf7 100644
--- a/packages/CredentialManager/res/values-am/strings.xml
+++ b/packages/CredentialManager/res/values-am/strings.xml
@@ -24,7 +24,7 @@
     <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>
-    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"በይለፍ ቃል ይበልጥ ደህንነቱ የተጠበቀ"</string>
+    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"በይለፍ ቁልፎች ይበልጥ ደህንነቱ የተጠበቀ"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"በይለፍ ቁልፎች ውስብስብ የይለፍ ቁልፎችን መፍጠር ወይም ማስታወስ አያስፈልግዎትም"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"የይለፍ ቁልፎች የእርስዎን የጣት አሻራ፣ መልክ ወይም የማያ ገፅ መቆለፊያ በመጠቀም የሚፈጥሯቸው የተመሰጠሩ ዲጂታል ቆልፎች ናቸው"</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"በሌሎች መሣሪያዎች ላይ መግባት እንዲችሉ በሚስጥር ቁልፍ አስተዳዳሪ ላይ ይቀመጣሉ"</string>
diff --git a/packages/CredentialManager/res/values-az/strings.xml b/packages/CredentialManager/res/values-az/strings.xml
index 209c9c2..d0f8bb0 100644
--- a/packages/CredentialManager/res/values-az/strings.xml
+++ b/packages/CredentialManager/res/values-az/strings.xml
@@ -24,19 +24,19 @@
     <string name="string_learn_more" msgid="4541600451688392447">"Ətraflı məlumat"</string>
     <string name="content_description_show_password" msgid="3283502010388521607">"Parolu göstərin"</string>
     <string name="content_description_hide_password" msgid="6841375971631767996">"Parolu gizlədin"</string>
-    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Giriş açarları ilə daha təhlükəsiz"</string>
-    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Giriş açarları ilə mürəkkəb parollar yaratmağa və ya yadda saxlamağa ehtiyac yoxdur"</string>
+    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Açarlar ilə daha təhlükəsiz"</string>
+    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Açarlar ilə mürəkkəb parollar yaratmağa və ya yadda saxlamağa ehtiyac yoxdur"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Giriş açarları barmaq izi, üz və ya ekran kilidindən istifadə edərək yaratdığınız şifrələnmiş rəqəmsal açarlardır"</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Onlar parol menecerində saxlanılır ki, digər cihazlarda daxil ola biləsiniz"</string>
-    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Giriş açarları haqqında ətraflı"</string>
+    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Açarlar haqqında ətraflı"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Parolsuz texnologiya"</string>
-    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Giriş açarları parollara etibar etmədən daxil olmağa imkan verir. Kimliyinizi doğrulamaq və giriş açarı yaratmaq üçün sadəcə barmaq izi, üz tanıma, PIN və ya sürüşdürmə modelindən istifadə etməlisiniz."</string>
+    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Giriş açarları parollara etibar etmədən daxil olmağa imkan verir. Kimliyinizi doğrulamaq və açar yaratmaq üçün sadəcə barmaq izi, üz tanıma, PIN və ya sürüşdürmə modelindən istifadə etməlisiniz."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"İctimai açar kriptoqrafiyası"</string>
-    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (Google, Apple, Microsoft və s. daxildir) və W3C standartlarına əsaslanaraq giriş açarları kriptoqrafik açar cütlərindən istifadə edir. İstifadəçi adı və parollar üçün istifadə etdiyimiz simvol sətrindən fərqli olaraq, tətbiq və ya vebsayt üçün şəxsi-ictimai açar cütü yaradılır. Şəxsi açar cihazınızda və ya parol menecerinizdə təhlükəsiz şəkildə saxlanılır və kimliyinizi təsdiq edir. İctimai açar tətbiq və ya vebsayt serveri ilə paylaşılır. Müvafiq açarlarla dərhal qeydiyyatdan keçə və daxil ola bilərsiniz."</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (Google, Apple, Microsoft və s. daxildir) və W3C standartlarına əsaslanaraq açarlar kriptoqrafik açar cütlərindən istifadə edir. İstifadəçi adı və parollar üçün istifadə etdiyimiz simvol sətrindən fərqli olaraq, tətbiq və ya vebsayt üçün şəxsi-ictimai açar cütü yaradılır. Şəxsi açar cihazınızda və ya parol menecerinizdə təhlükəsiz şəkildə saxlanılır və kimliyinizi təsdiq edir. İctimai açar tətbiq və ya vebsayt serveri ilə paylaşılır. Müvafiq açarlarla dərhal qeydiyyatdan keçə və daxil ola bilərsiniz."</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"Təkmilləşdirilmiş hesab təhlükəsizliyi"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"Hər bir açar eksklüziv olaraq onların yaradıldığı tətbiq və ya vebsaytla əlaqələndirilib, ona görə də heç vaxt səhvən saxta tətbiqə və ya vebsayta daxil ola bilməzsiniz. Üstəlik, yalnız ictimai açarları saxlayan serverlərlə hekinq daha çətindir."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Rahat keçid"</string>
-    <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsuz gələcəyə doğru irəlilədikcə parollar hələ də giriş açarları ilə yanaşı əlçatan olacaq."</string>
+    <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsuz gələcəyə doğru irəlilədikcə parollar hələ də açarlar ilə yanaşı əlçatan olacaq."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> elementinin saxlanacağı yeri seçin"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Məlumatlarınızı yadda saxlamaq və növbəti dəfə daha sürətli daxil olmaq üçün parol meneceri seçin"</string>
     <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> üçün giriş açarı yaradılsın?"</string>
@@ -44,7 +44,7 @@
     <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> üçün giriş məlumatları yadda saxlansın?"</string>
     <string name="passkey" msgid="632353688396759522">"açar"</string>
     <string name="password" msgid="6738570945182936667">"parol"</string>
-    <string name="passkeys" msgid="5733880786866559847">"giriş açarları"</string>
+    <string name="passkeys" msgid="5733880786866559847">"açarlar"</string>
     <string name="passwords" msgid="5419394230391253816">"parollar"</string>
     <string name="sign_ins" msgid="4710739369149469208">"girişlər"</string>
     <string name="sign_in_info" msgid="2627704710674232328">"Giriş məlumatları"</string>
@@ -53,13 +53,13 @@
     <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Parol başqa cihazda yadda saxlansın?"</string>
     <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Giriş başqa cihazda yadda saxlansın?"</string>
     <string name="use_provider_for_all_title" msgid="4201020195058980757">"Bütün girişlər üçün <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> istifadə edilsin?"</string>
-    <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> üçün bu parol meneceri asanlıqla daxil olmağınız məqsədilə parol və giriş açarlarını saxlayacaq"</string>
+    <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> üçün bu parol meneceri asanlıqla daxil olmağınız məqsədilə parol və açarları saxlayacaq"</string>
     <string name="set_as_default" msgid="4415328591568654603">"Defolt olaraq seçin"</string>
     <string name="settings" msgid="6536394145760913145">"Ayarlar"</string>
     <string name="use_once" msgid="9027366575315399714">"Bir dəfə istifadə edin"</string>
-    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> parol • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> giriş açarı"</string>
+    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> parol • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> açar"</string>
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> parol"</string>
-    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> giriş açarı"</string>
+    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> açarları"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> giriş məlumatları"</string>
     <string name="passkey_before_subtitle" msgid="2448119456208647444">"Giriş açarı"</string>
     <string name="another_device" msgid="5147276802037801217">"Digər cihaz"</string>
diff --git a/packages/CredentialManager/res/values-bg/strings.xml b/packages/CredentialManager/res/values-bg/strings.xml
index e60420a..ef4dd54c 100644
--- a/packages/CredentialManager/res/values-bg/strings.xml
+++ b/packages/CredentialManager/res/values-bg/strings.xml
@@ -24,19 +24,19 @@
     <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>
-    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"По-сигурно с помощта на кодове за достъп"</string>
-    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Когато използвате кодове за достъп, не е необходимо да създавате, нито да помните сложни пароли"</string>
-    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Кодовете за достъп са шифровани дигитални ключове, които създавате посредством отпечатъка, лицето си или опцията си за заключване на екрана"</string>
+    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"По-сигурно с помощта на ключове за достъп"</string>
+    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Когато използвате ключове за достъп, не е необходимо да създавате, нито да помните сложни пароли"</string>
+    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Ключовете за достъп са шифровани дигитални ключове, които създавате посредством отпечатъка, лицето си или опцията си за заключване на екрана"</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Данните се запазват в мениджър на пароли, за да можете да влизате в профила си на други устройства"</string>
-    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Още за кодовете за достъп"</string>
+    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Още за ключовете за достъп"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Заменяща паролите технология"</string>
-    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Кодовете за достъп ви дават възможност да влизате в профила си без парола. Трябва само да използвате отпечатъка, лицето, ПИН кода или фигурата си, за да потвърдите самоличността си и да създадете код за достъп."</string>
+    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Ключовете за достъп ви дават възможност да влизате в профила си без парола. Трябва само да използвате отпечатъка, лицето, ПИН кода или фигурата си, за да потвърдите самоличността си и да създадете код за достъп."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"Криптография с публичен ключ"</string>
-    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Според съюза FIDO (Google, Apple, Microsoft и др.) и стандартите на W3C кодовете за достъп ползват двойки криптографски ключове. Вместо потребителско име и парола за дадено приложение или уебсайт се създава двойка ключове – частен и публичен. Първият се съхранява надеждно на устройството ви или в мениджъра на пароли и служи за потвърждаване на самоличността ви. Вторият се споделя със съответния сървър. С двойката ключове можете да се регистрирате и да влезете в профила си незабавно."</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Според съюза FIDO (Google, Apple, Microsoft и др.) и стандартите на W3C ключовете за достъп ползват двойки криптографски ключове. Вместо потребителско име и парола за дадено приложение или уебсайт се създава двойка ключове – частен и публичен. Първият се съхранява надеждно на устройството ви или в мениджъра на пароли и служи за потвърждаване на самоличността ви. Вторият се споделя със съответния сървър. С двойката ключове можете да се регистрирате и да влезете в профила си незабавно."</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"Подобрена сигурност на профила"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"Всеки ключ е свързан само с приложението или уебсайта, за които е създаден. Затова не е възможно да влезете в измамно приложение или уебсайт по погрешка. Освен това сървърите съхраняват само публичните ключове, което значително затруднява опитите за хакерство."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Безпроблемен преход"</string>
-    <string name="seamless_transition_detail" msgid="4475509237171739843">"Паролите ще продължат да са налице заедно с кодовете за достъп по пътя ни към бъдеще без пароли."</string>
+    <string name="seamless_transition_detail" msgid="4475509237171739843">"Паролите ще продължат да са налице заедно с ключовете за достъп по пътя ни към бъдеще без пароли."</string>
     <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="5220979185879006862">"Да се създаде ли код за достъп за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -44,7 +44,7 @@
     <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Да се запазят ли данните за вход за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"код за достъп"</string>
     <string name="password" msgid="6738570945182936667">"парола"</string>
-    <string name="passkeys" msgid="5733880786866559847">"кодове за достъп"</string>
+    <string name="passkeys" msgid="5733880786866559847">"ключове за достъп"</string>
     <string name="passwords" msgid="5419394230391253816">"пароли"</string>
     <string name="sign_ins" msgid="4710739369149469208">"данни за вход"</string>
     <string name="sign_in_info" msgid="2627704710674232328">"данните за вход"</string>
@@ -53,13 +53,13 @@
     <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Паролата да се запази ли на друго устройство?"</string>
     <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Данните за вход да се запазят ли на друго устройство?"</string>
     <string name="use_provider_for_all_title" msgid="4201020195058980757">"Да се използва ли <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> за всичките ви данни за вход?"</string>
-    <string name="use_provider_for_all_description" msgid="1998772715863958997">"Мениджърът на пароли за <xliff:g id="USERNAME">%1$s</xliff:g> ще съхранява вашите пароли и кодове за достъп, за да влизате лесно в профила си"</string>
+    <string name="use_provider_for_all_description" msgid="1998772715863958997">"Мениджърът на пароли за <xliff:g id="USERNAME">%1$s</xliff:g> ще съхранява вашите пароли и ключове за достъп, за да влизате лесно в профила си"</string>
     <string name="set_as_default" msgid="4415328591568654603">"Задаване като основно"</string>
     <string name="settings" msgid="6536394145760913145">"Настройки"</string>
     <string name="use_once" msgid="9027366575315399714">"Еднократно използване"</string>
-    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> пароли • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> кода за достъп"</string>
+    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> пароли • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> ключа за достъп"</string>
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> пароли"</string>
-    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> кода за достъп"</string>
+    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> ключа за достъп"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"Идентификационни данни: <xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g>"</string>
     <string name="passkey_before_subtitle" msgid="2448119456208647444">"Код за достъп"</string>
     <string name="another_device" msgid="5147276802037801217">"Друго устройство"</string>
diff --git a/packages/CredentialManager/res/values-cs/strings.xml b/packages/CredentialManager/res/values-cs/strings.xml
index d63b24f..9fe5a49 100644
--- a/packages/CredentialManager/res/values-cs/strings.xml
+++ b/packages/CredentialManager/res/values-cs/strings.xml
@@ -32,7 +32,7 @@
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Technologie bez hesel"</string>
     <string name="passwordless_technology_detail" msgid="6853928846532955882">"Přístupové klíče umožňují přihlašovat se bez hesel. Stačí pomocí otisku prstu, rozpoznání obličeje, kódu PIN nebo gesta ověřit svou totožnost a vytvořit přístupový klíč."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"Kryptografie s veřejným klíčem"</string>
-    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Podle pokynů FIDO Alliance (která zahrnuje společnosti Google, Apple, Microsoft a další) a standardů W3C používají přístupové klíče páry kryptografických klíčů. Na rozdíl od uživatelského jména a řetězce znaků, které používáme pro hesla, se pro aplikaci nebo web vytváří pár klíčů (soukromého a veřejného). Soukromý klíč je bezpečně uložen ve vašem zařízení nebo správci hesel a potvrzuje vaši identitu. Veřejný klíč je sdílen s aplikací nebo webovým serverem. Pomocí odpovídajících klíčů se můžete okamžitě zaregistrovat a přihlásit."</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Podle pokynů FIDO Alliance (zahrnující mj. firmy Google, Apple a Microsoft) a standardů W3C používají přístupové klíče páry kryptografických klíčů. Na rozdíl od jména uživatele a řetězce znaků používaného pro heslo se pro aplikaci nebo web vytváří soukromý a veřejný klíč. Soukromý klíč se bezpečně uloží do zařízení nebo správce hesel a potvrzuje vaši identitu. Veřejný klíč se sdílí s aplikací nebo webovým serverem. Pomocí odpovídajících klíčů se můžete rychle zaregistrovat a přihlásit."</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"Vylepšené zabezpečení účtu"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"Každý klíč je propojen výhradně s aplikací nebo webem, pro které byl vytvořen, takže se nikdy nemůžete omylem přihlásit k podvodné aplikaci nebo webu. Protože na serverech jsou uloženy pouze veřejné klíče, je hackování navíc mnohem obtížnější."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Bezproblémový přechod"</string>
diff --git a/packages/CredentialManager/res/values-es/strings.xml b/packages/CredentialManager/res/values-es/strings.xml
index 5fdfa5d..fb0cbf9 100644
--- a/packages/CredentialManager/res/values-es/strings.xml
+++ b/packages/CredentialManager/res/values-es/strings.xml
@@ -28,7 +28,7 @@
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Con las llaves de acceso, no tienes que crear ni recordar contraseñas complicadas"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Las llaves de acceso son claves digitales cifradas que puedes crear con tu huella digital, cara o bloqueo de pantalla"</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Se guardan en un gestor de contraseñas para que puedas iniciar sesión en otros dispositivos"</string>
-    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Más información sobre llaves de acceso"</string>
+    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Más información sobre las llaves de acceso"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Tecnología sin contraseñas"</string>
     <string name="passwordless_technology_detail" msgid="6853928846532955882">"Las llaves de acceso te permiten iniciar sesión sin necesidad de contraseñas. Solo necesitas usar la huella digital, el reconocimiento facial, el PIN o patrón para verificar tu identidad y crear una llave de acceso."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"Criptografía de claves públicas"</string>
@@ -57,9 +57,9 @@
     <string name="set_as_default" msgid="4415328591568654603">"Fijar como predeterminado"</string>
     <string name="settings" msgid="6536394145760913145">"Ajustes"</string>
     <string name="use_once" msgid="9027366575315399714">"Usar una vez"</string>
-    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> contraseñas • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> llaves de acceso"</string>
+    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Contraseñas: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Llaves de acceso: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> contraseñas"</string>
-    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> llaves de acceso"</string>
+    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"Llaves de acceso: <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g>"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> credenciales"</string>
     <string name="passkey_before_subtitle" msgid="2448119456208647444">"Llave de acceso"</string>
     <string name="another_device" msgid="5147276802037801217">"Otro dispositivo"</string>
diff --git a/packages/CredentialManager/res/values-fa/strings.xml b/packages/CredentialManager/res/values-fa/strings.xml
index cee37bb..8e4113d 100644
--- a/packages/CredentialManager/res/values-fa/strings.xml
+++ b/packages/CredentialManager/res/values-fa/strings.xml
@@ -30,7 +30,7 @@
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"گذرکلیدها در «مدیر گذرواژه» ذخیره می‌شود تا بتوانید در دستگاه‌های دیگر به سیستم وارد شوید"</string>
     <string name="more_about_passkeys_title" msgid="7797903098728837795">"اطلاعات بیشتر درباره گذرکلیدها"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"فناوری بی‌گذرواژه"</string>
-    <string name="passwordless_technology_detail" msgid="6853928846532955882">"گذرکلیدها به شما اجازه می‌دهند بدون اتکا به گذرواژه به سیستم وارد شوید. برای به‌تأیید رساندن هویت خود و ایجاد گذرکلید، کافی است از اثر انگشت، تشخیص چهره، پین، یا الگوی کشیدنی استفاده کنید."</string>
+    <string name="passwordless_technology_detail" msgid="6853928846532955882">"گذرکلیدها به شما اجازه می‌دهند بدون اتکا به گذرواژه به سیستم وارد شوید. برای به‌تأیید رساندن هویت و ایجاد گذرکلید، کافی است از اثر انگشت، تشخیص چهره، پین، یا الگوی کشیدنی استفاده کنید."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"رمزنگاری کلید عمومی"</string>
     <string name="public_key_cryptography_detail" msgid="6937631710280562213">"‏براساس «اتحاد FIDO» (که شامل Google،‏ Apple،‏ Microsoft، و غیره می‌شود) و استانداردهای W3C، گذرکلیدها از جفت کلیدهای رمزنگاری‌شده استفاده می‌کنند. برخلاف نام کاربری و رشته نویسه‌هایی که برای گذرواژه‌ها استفاده می‌کنیم، یک جفت کلید خصوصی-عمومی برای برنامه یا وب‌سایت ایجاد می‌شود. کلید خصوصی به‌طور امن در دستگاه یا مدیر گذرواژه شما ذخیره می‌شود و هویت شما را تأیید می‌کند. کلید عمومی با سرور وب‌سایت یا برنامه هم‌رسانی می‌شود. با کلیدهای مربوطه می‌توانید بی‌درنگ ثبت‌نام کنید و به سیستم وارد شوید."</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"بهبود امنیت حساب"</string>
diff --git a/packages/CredentialManager/res/values-fr-rCA/strings.xml b/packages/CredentialManager/res/values-fr-rCA/strings.xml
index 3e72a11..de78b38 100644
--- a/packages/CredentialManager/res/values-fr-rCA/strings.xml
+++ b/packages/CredentialManager/res/values-fr-rCA/strings.xml
@@ -36,7 +36,7 @@
     <string name="improved_account_security_title" msgid="1069841917893513424">"Sécurité accrue du compte"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"Chaque clé est exclusivement liée à l\'application ou au site Web pour lequel elle a été créée, de sorte que vous ne pourrez jamais vous connecter par erreur à une application ou à un site Web frauduleux. En outre, comme les serveurs ne conservent que les clés publiques, le piratage informatique est beaucoup plus difficile."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Transition fluide"</string>
-    <string name="seamless_transition_detail" msgid="4475509237171739843">"À mesure que nous nous dirigeons vers un avenir sans mot de passe, les mots de passe seront toujours utilisés parallèlement aux clés d\'accès."</string>
+    <string name="seamless_transition_detail" msgid="4475509237171739843">"À mesure que nous nous dirigeons vers un avenir sans mot de passe, ils resteront toujours utilisés parallèlement aux clés d\'accès."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Choisir où enregistrer vos <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Sélectionnez un gestionnaire de mots de passe pour enregistrer vos renseignements et vous connecter plus rapidement la prochaine fois"</string>
     <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Créer une clé d\'accès pour <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
diff --git a/packages/CredentialManager/res/values-hr/strings.xml b/packages/CredentialManager/res/values-hr/strings.xml
index 9565e31..4425e24 100644
--- a/packages/CredentialManager/res/values-hr/strings.xml
+++ b/packages/CredentialManager/res/values-hr/strings.xml
@@ -32,7 +32,7 @@
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Tehnologija bez upotrebe zaporke"</string>
     <string name="passwordless_technology_detail" msgid="6853928846532955882">"Pristupni ključevi omogućuju prijavu bez upotrebe zaporki. Treba vam samo otisak prsta, prepoznavanje lica, PIN ili uzorak pokreta prstom da biste potvrdili svoj identitet i izradili pristupni ključ."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"Kriptografija javnog ključa"</string>
-    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Na temelju organizacije FIDO Alliance (koja uključuje Google, Apple, Microsoft i mnoge druge) i standarda W3C pristupni ključevi koriste kriptografske ključeve. Za razliku od korisničkog imena i niza znakova za zaporke, privatno-javni ključ izrađen je za aplikaciju ili web-lokaciju. Privatni ključ pohranjen je na vašem uređaju ili upravitelju zaporki i potvrđuje vaš identitet. Javni se ključ dijeli s poslužiteljem aplikacije ili web-lokacije. Uz odgovarajuće ključeve možete se odmah registrirati i prijaviti."</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Prema standardima FIDO Alliancea (koja uključuje Google, Apple, Microsoft i mnoge druge) i W3C-a pristupni ključevi koriste kriptografske ključeve. Za razliku od korisničkog imena i niza znakova za zaporke, privatno-javni ključ izrađen je za aplikaciju ili web-lokaciju. Privatni ključ pohranjen je na vašem uređaju ili upravitelju zaporki i potvrđuje vaš identitet. Javni se ključ dijeli s poslužiteljem aplikacije ili web-lokacije. Uz odgovarajuće ključeve možete se odmah registrirati i prijaviti."</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"Poboljšana sigurnost računa"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"Svaki je ključ povezan isključivo s aplikacijom ili web-lokacijom za koju je izrađen, stoga se nikad ne možete pogreškom prijaviti u prijevarnu aplikaciju ili na web-lokaciju. Osim toga, kad je riječ o poslužiteljima na kojem se nalaze samo javni ključevi, hakiranje je mnogo teže."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Besprijekorni prijelaz"</string>
diff --git a/packages/CredentialManager/res/values-kk/strings.xml b/packages/CredentialManager/res/values-kk/strings.xml
index 4ed616a..cb68444 100644
--- a/packages/CredentialManager/res/values-kk/strings.xml
+++ b/packages/CredentialManager/res/values-kk/strings.xml
@@ -44,7 +44,7 @@
     <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> үшін кіру мәліметін сақтау керек пе?"</string>
     <string name="passkey" msgid="632353688396759522">"Кіру кілті"</string>
     <string name="password" msgid="6738570945182936667">"құпия сөз"</string>
-    <string name="passkeys" msgid="5733880786866559847">"Кіру кілттері"</string>
+    <string name="passkeys" msgid="5733880786866559847">"кіру кілттері"</string>
     <string name="passwords" msgid="5419394230391253816">"Құпия сөздер"</string>
     <string name="sign_ins" msgid="4710739369149469208">"кіру әрекеттері"</string>
     <string name="sign_in_info" msgid="2627704710674232328">"кіру мәліметі"</string>
diff --git a/packages/CredentialManager/res/values-km/strings.xml b/packages/CredentialManager/res/values-km/strings.xml
index 2ebb384..d361ad9 100644
--- a/packages/CredentialManager/res/values-km/strings.xml
+++ b/packages/CredentialManager/res/values-km/strings.xml
@@ -57,7 +57,7 @@
     <string name="set_as_default" msgid="4415328591568654603">"កំណត់ជាលំនាំដើម"</string>
     <string name="settings" msgid="6536394145760913145">"ការកំណត់"</string>
     <string name="use_once" msgid="9027366575315399714">"ប្រើម្ដង"</string>
-    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"ពាក្យសម្ងាត់ <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • កូដសម្ងាត់<xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
+    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"ពាក្យសម្ងាត់ <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • កូដសម្ងាត់ <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"ពាក្យសម្ងាត់ <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>"</string>
     <string name="more_options_usage_passkeys" msgid="5390320437243042237">"កូដសម្ងាត់ <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g>"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"ព័ត៌មានផ្ទៀងផ្ទាត់ <xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-ky/strings.xml b/packages/CredentialManager/res/values-ky/strings.xml
index af332e1..b4c5670 100644
--- a/packages/CredentialManager/res/values-ky/strings.xml
+++ b/packages/CredentialManager/res/values-ky/strings.xml
@@ -53,7 +53,7 @@
     <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Сырсөздү башка түзмөктө сактайсызбы?"</string>
     <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Кирүү маалыматын башка түзмөктө сактайсызбы?"</string>
     <string name="use_provider_for_all_title" msgid="4201020195058980757">"<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> бардык аккаунттарга кирүү үчүн колдонулсунбу?"</string>
-    <string name="use_provider_for_all_description" msgid="1998772715863958997">"Сырсөздөрүңүздү жана ачкычтарыңызды <xliff:g id="USERNAME">%1$s</xliff:g> аккаунтуңуздагы сырсөздөрдү башкаргычка сактап коюп, каалаган убакта колдоно берсеңиз болот"</string>
+    <string name="use_provider_for_all_description" msgid="1998772715863958997">"Сырсөздөрүңүздү жана киргизүүчү ачкычтарыңызды <xliff:g id="USERNAME">%1$s</xliff:g> аккаунтуңуздагы сырсөздөрдү башкаргычка сактап коюп, каалаган убакта колдоно берсеңиз болот"</string>
     <string name="set_as_default" msgid="4415328591568654603">"Демейки катары коюу"</string>
     <string name="settings" msgid="6536394145760913145">"Параметрлер"</string>
     <string name="use_once" msgid="9027366575315399714">"Бир жолу колдонуу"</string>
diff --git a/packages/CredentialManager/res/values-lt/strings.xml b/packages/CredentialManager/res/values-lt/strings.xml
index 173b2b1..d5f5f7f 100644
--- a/packages/CredentialManager/res/values-lt/strings.xml
+++ b/packages/CredentialManager/res/values-lt/strings.xml
@@ -24,19 +24,19 @@
     <string name="string_learn_more" msgid="4541600451688392447">"Sužinokite daugiau"</string>
     <string name="content_description_show_password" msgid="3283502010388521607">"Rodyti slaptažodį"</string>
     <string name="content_description_hide_password" msgid="6841375971631767996">"Slėpti slaptažodį"</string>
-    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Saugiau naudojant slaptažodžius"</string>
-    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Naudojant „passkey“ nereikės kurti ir prisiminti sudėtingų slaptažodžių"</string>
-    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"„Passkey“ šifruojami skaitiniais raktais, kuriuos sukuriate naudodami piršto atspaudą, veidą ar ekrano užraktą"</string>
+    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Saugiau naudojant prieigos raktus"</string>
+    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Naudojant prieigos raktus nereikės kurti ir prisiminti sudėtingų slaptažodžių"</string>
+    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Prieigos raktai šifruojami skaitiniais raktais, kuriuos sukuriate naudodami piršto atspaudą, veidą ar ekrano užraktą"</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Jie saugomi slaptažodžių tvarkyklėje, kad galėtumėte prisijungti kituose įrenginiuose"</string>
-    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Daugiau apie slaptuosius raktus („passkey“)"</string>
+    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Daugiau apie prieigos raktus („passkey“)"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Technologijos be slaptažodžių"</string>
-    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Naudodami slaptuosius raktus galite prisijungti be slaptažodžių. Tiesiog naudokite piršto atspaudą, atpažinimą pagal veidą, PIN kodą arba perbraukiamą atrakinimo piešinį, kad patvirtintumėte tapatybę ir sukurtumėte slaptąjį raktą."</string>
+    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Naudodami prieigos raktus galite prisijungti be slaptažodžių. Tiesiog naudokite piršto atspaudą, atpažinimą pagal veidą, PIN kodą arba perbraukiamą atrakinimo piešinį, kad patvirtintumėte tapatybę ir sukurtumėte prieigos raktą."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"Viešojo rakto kriptografija"</string>
-    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Pagal FIDO aljansą (kuriam priklauso „Google“, „Apple“, „Microsoft“ ir kt.) bei W3C standartus, slaptiesiems raktams naudojamos kriptografinių raktų poros. Priešingai nei naudotojo vardas ir eilutė simbolių, naudojamų slaptažodžiams, privataus ir viešojo raktų pora sukuriama programai ar svetainei. Tapatybę patvirtinantis privatusis raktas saugomas įrenginyje ar Slaptažodžių tvarkyklėje. Viešasis raktas bendrinamas su programos ar svetainės serveriu. Naudodami atitinkamus raktus galite akimirksniu užsiregistruoti ir prisijungti."</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Pagal FIDO aljansą (kuriam priklauso „Google“, „Apple“, „Microsoft“ ir kt.) bei W3C standartus, prieigos raktams naudojamos kriptografinių raktų poros. Priešingai nei naudotojo vardas ir eilutė simbolių, naudojamų slaptažodžiams, privataus ir viešojo raktų pora sukuriama programai ar svetainei. Tapatybę patvirtinantis privatusis raktas saugomas įrenginyje ar Slaptažodžių tvarkyklėje. Viešasis raktas bendrinamas su programos ar svetainės serveriu. Naudodami atitinkamus raktus galite akimirksniu užsiregistruoti ir prisijungti."</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"Geresnė paskyros sauga"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"Kiekvienas raktas išskirtinai susietas su programa ar svetaine, kuriai buvo sukurtas, todėl niekada per klaidą neprisijungsite prie apgavikiškos programos ar svetainės. Be to, viešieji raktai laikomi tik serveriuose, todėl įsilaužti tampa gerokai sudėtingiau."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Sklandus perėjimas"</string>
-    <string name="seamless_transition_detail" msgid="4475509237171739843">"Kol stengiamės padaryti, kad ateityje nereikėtų naudoti slaptažodžių, jie vis dar bus pasiekiami kartu su slaptaisiais raktais."</string>
+    <string name="seamless_transition_detail" msgid="4475509237171739843">"Kol stengiamės padaryti, kad ateityje nereikėtų naudoti slaptažodžių, jie vis dar bus pasiekiami kartu su prieigos raktais."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Pasirinkite, kur išsaugoti „<xliff:g id="CREATETYPES">%1$s</xliff:g>“"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Pasirinkite slaptažodžių tvarkyklę, kurią naudodami galėsite išsaugoti informaciją ir kitą kartą prisijungti greičiau"</string>
     <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Sukurti „passkey“, skirtą „<xliff:g id="APPNAME">%1$s</xliff:g>“?"</string>
@@ -44,7 +44,7 @@
     <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Išsaugoti prisijungimo prie „<xliff:g id="APPNAME">%1$s</xliff:g>“ informaciją?"</string>
     <string name="passkey" msgid="632353688396759522">"„passkey“"</string>
     <string name="password" msgid="6738570945182936667">"slaptažodis"</string>
-    <string name="passkeys" msgid="5733880786866559847">"passkey"</string>
+    <string name="passkeys" msgid="5733880786866559847">"prieigos raktas"</string>
     <string name="passwords" msgid="5419394230391253816">"slaptažodžiai"</string>
     <string name="sign_ins" msgid="4710739369149469208">"prisijungimo informacija"</string>
     <string name="sign_in_info" msgid="2627704710674232328">"prisijungimo informaciją"</string>
@@ -53,13 +53,13 @@
     <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Išsaugoti slaptažodį kitame įrenginyje?"</string>
     <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Išsaugoti prisijungimo duomenis kitame įrenginyje?"</string>
     <string name="use_provider_for_all_title" msgid="4201020195058980757">"Naudoti <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> visada prisijungiant?"</string>
-    <string name="use_provider_for_all_description" msgid="1998772715863958997">"Šioje <xliff:g id="USERNAME">%1$s</xliff:g> Slaptažodžių tvarkyklėje bus saugomi jūsų slaptažodžiai ir „passkey“, kad galėtumėte lengvai prisijungti"</string>
+    <string name="use_provider_for_all_description" msgid="1998772715863958997">"Šioje <xliff:g id="USERNAME">%1$s</xliff:g> Slaptažodžių tvarkyklėje bus saugomi jūsų slaptažodžiai ir prieigos raktai, kad galėtumėte lengvai prisijungti"</string>
     <string name="set_as_default" msgid="4415328591568654603">"Nustatyti kaip numatytąjį"</string>
     <string name="settings" msgid="6536394145760913145">"Nustatymai"</string>
     <string name="use_once" msgid="9027366575315399714">"Naudoti vieną kartą"</string>
-    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Slaptažodžių: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • „Passkey“: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
+    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Slaptažodžių: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Prieigos raktų: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"slaptažodžių: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>"</string>
-    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"„passkey“: <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g>"</string>
+    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"Prieigos raktai: <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g>"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"Prisijungimo duomenų: <xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g>"</string>
     <string name="passkey_before_subtitle" msgid="2448119456208647444">"Slaptažodis"</string>
     <string name="another_device" msgid="5147276802037801217">"Kitas įrenginys"</string>
diff --git a/packages/CredentialManager/res/values-mk/strings.xml b/packages/CredentialManager/res/values-mk/strings.xml
index 9bea6ac..0755c9c 100644
--- a/packages/CredentialManager/res/values-mk/strings.xml
+++ b/packages/CredentialManager/res/values-mk/strings.xml
@@ -59,7 +59,7 @@
     <string name="use_once" msgid="9027366575315399714">"Употребете еднаш"</string>
     <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Лозинки: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Криптографски клучеви: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> лозинки"</string>
-    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> криптографски клучеви"</string>
+    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"Криптографски клучеви: <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g>"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"Акредитиви: <xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g>"</string>
     <string name="passkey_before_subtitle" msgid="2448119456208647444">"Криптографски клуч"</string>
     <string name="another_device" msgid="5147276802037801217">"Друг уред"</string>
diff --git a/packages/CredentialManager/res/values-mn/strings.xml b/packages/CredentialManager/res/values-mn/strings.xml
index 03da287..e37155a 100644
--- a/packages/CredentialManager/res/values-mn/strings.xml
+++ b/packages/CredentialManager/res/values-mn/strings.xml
@@ -24,19 +24,19 @@
     <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>
-    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Passkey-тэй байхад илүү аюулгүй"</string>
-    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Passkey-н тусламжтай та нарийн төвөгтэй нууц үг үүсгэх эсвэл санах шаардлагагүй"</string>
-    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Passkey нь таны хурууны хээ, царай эсвэл дэлгэцийн түгжээгээ ашиглан үүсгэсэн шифрлэгдсэн дижитал түлхүүр юм"</string>
+    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Нэвтрэх түлхүүртэй байхад илүү аюулгүй"</string>
+    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Нэвтрэх түлхүүрийн тусламжтай та нарийн төвөгтэй нууц үг үүсгэх эсвэл санах шаардлагагүй"</string>
+    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Нэвтрэх түлхүүр нь таны хурууны хээ, царай эсвэл дэлгэцийн түгжээгээ ашиглан үүсгэсэн шифрлэгдсэн дижитал түлхүүр юм"</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Тэдгээрийг нууц үгний менежерт хадгалдаг бөгөөд ингэснээр та бусад төхөөрөмжид нэвтрэх боломжтой"</string>
-    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Passkey-н талаарх дэлгэрэнгүй"</string>
+    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Нэвтрэх түлхүүрийн талаарх дэлгэрэнгүй"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Нууц үггүй технологи"</string>
-    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Passkey нь танд нууц үгэнд найдалгүйгээр нэвтрэх боломжийг олгодог. Та хувийн мэдээллээ баталгаажуулах болон passkey үүсгэхийн тулд ердөө хурууны хээ, царай танилт, ПИН эсвэл шудрах хээгээ ашиглах шаардлагатай."</string>
+    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Нэвтрэх түлхүүр нь танд нууц үгэнд найдалгүйгээр нэвтрэх боломжийг олгодог. Та хувийн мэдээллээ баталгаажуулах болон нэвтрэх түлхүүр үүсгэхийн тулд ердөө хурууны хээ, царай танилт, ПИН эсвэл шудрах хээгээ ашиглах шаардлагатай."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"Нийтийн түлхүүрийн криптограф"</string>
-    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Passkey нь FIDO Холбоо (Google, Apple, Microsoft ба бусад багтдаг) болон W3C стандартад тулгуурлан криптограф түлхүүрийн хослолыг ашигладаг. Хэрэглэгчийн нэр, бидний нууц үгэнд ашигладаг тэмдэгтийн мөрөөс ялгаатай хувийн-нийтийн түлхүүрийн хослолыг апп эсвэл вебсайтад үүсгэдэг. Хувийн түлхүүрийг таны төхөөрөмж эсвэл нууц үгний менежерт аюулгүй хадгалдаг бөгөөд үүнийг таны хувийн мэдээллийг баталгаажуулахад ашигладаг. Нийтийн түлхүүрийг апп эсвэл вебсайтын сервертэй хуваалцдаг. Харгалзах түлхүүрээр та даруй бүртгүүлэх, нэвтрэх боломжтой."</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Нэвтрэх түлхүүр нь FIDO Холбоо (Google, Apple, Microsoft ба бусад багтдаг) болон W3C стандартад тулгуурлан криптограф түлхүүрийн хослолыг ашигладаг. Хэрэглэгчийн нэр, бидний нууц үгэнд ашигладаг тэмдэгтийн мөрөөс ялгаатай хувийн-нийтийн түлхүүрийн хослолыг апп эсвэл вебсайтад үүсгэдэг. Хувийн түлхүүрийг таны төхөөрөмж эсвэл нууц үгний менежерт аюулгүй хадгалдаг бөгөөд үүнийг таны хувийн мэдээллийг баталгаажуулахад ашигладаг. Нийтийн түлхүүрийг апп эсвэл вебсайтын сервертэй хуваалцдаг. Харгалзах түлхүүрээр та даруй бүртгүүлэх, нэвтрэх боломжтой."</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"Бүртгэлийн сайжруулсан аюулгүй байдал"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"Түлхүүр тус бүрийг тэдгээрийг зориулж үүсгэсэн апп эсвэл вебсайттай нь тусгайлан холбодог бөгөөд ингэснээр та залилан мэхэлсэн апп эсвэл вебсайтад санамсаргүй байдлаар хэзээ ч нэвтрэхгүй. Түүнчлэн зөвхөн нийтийн түлхүүрийг хадгалж буй серверүүдийг хакердахад илүү хэцүү байдаг."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Саадгүй шилжилт"</string>
-    <string name="seamless_transition_detail" msgid="4475509237171739843">"Бид нууц үггүй ирээдүй рүү урагшлахын хэрээр нууц үг нь passkey-н хамтаар боломжтой хэвээр байх болно."</string>
+    <string name="seamless_transition_detail" msgid="4475509237171739843">"Бид нууц үггүй ирээдүй рүү урагшлахын хэрээр нууц үг нь нэвтрэх түлхүүрийн хамтаар боломжтой хэвээр байх болно."</string>
     <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="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g>-д passkey үүсгэх үү?"</string>
@@ -44,7 +44,7 @@
     <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g>-н нэвтрэх мэдээллийг хадгалах уу?"</string>
     <string name="passkey" msgid="632353688396759522">"passkey"</string>
     <string name="password" msgid="6738570945182936667">"нууц үг"</string>
-    <string name="passkeys" msgid="5733880786866559847">"passkeys"</string>
+    <string name="passkeys" msgid="5733880786866559847">"нэвтрэх түлхүүрүүд"</string>
     <string name="passwords" msgid="5419394230391253816">"нууц үг"</string>
     <string name="sign_ins" msgid="4710739369149469208">"нэвтрэлт"</string>
     <string name="sign_in_info" msgid="2627704710674232328">"нэвтрэх мэдээлэл"</string>
@@ -53,13 +53,13 @@
     <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Өөр төхөөрөмжид нууц үг хадгалах уу?"</string>
     <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Өөр төхөөрөмжид нэвтрэлт хадгалах уу?"</string>
     <string name="use_provider_for_all_title" msgid="4201020195058980757">"<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>-г бүх нэвтрэлтдээ ашиглах уу?"</string>
-    <string name="use_provider_for_all_description" msgid="1998772715863958997">"Танд хялбархан нэвтрэхэд туслахын тулд <xliff:g id="USERNAME">%1$s</xliff:g>-н энэ нууц үгний менежер таны нууц үг болон passkey-г хадгална"</string>
+    <string name="use_provider_for_all_description" msgid="1998772715863958997">"Танд хялбархан нэвтрэхэд туслахын тулд <xliff:g id="USERNAME">%1$s</xliff:g>-н энэ нууц үгний менежер таны нууц үг болон нэвтрэх түлхүүрийг хадгална"</string>
     <string name="set_as_default" msgid="4415328591568654603">"Өгөгдмөлөөр тохируулах"</string>
     <string name="settings" msgid="6536394145760913145">"Тохиргоо"</string>
     <string name="use_once" msgid="9027366575315399714">"Нэг удаа ашиглах"</string>
-    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> нууц үг • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> passkey"</string>
+    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> нууц үг • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> нэвтрэх түлхүүр"</string>
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> нууц үг"</string>
-    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> passkey"</string>
+    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> нэвтрэх түлхүүр"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> мандат үнэмлэх"</string>
     <string name="passkey_before_subtitle" msgid="2448119456208647444">"Passkey"</string>
     <string name="another_device" msgid="5147276802037801217">"Өөр төхөөрөмж"</string>
diff --git a/packages/CredentialManager/res/values-ms/strings.xml b/packages/CredentialManager/res/values-ms/strings.xml
index da87fcd..b933f3e 100644
--- a/packages/CredentialManager/res/values-ms/strings.xml
+++ b/packages/CredentialManager/res/values-ms/strings.xml
@@ -36,7 +36,7 @@
     <string name="improved_account_security_title" msgid="1069841917893513424">"Keselamatan akaun yang dipertingkatkan"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"Setiap kunci dipautkan secara eksklusif dengan apl atau laman web kunci dicipta, jadi anda tidak boleh log masuk ke apl atau laman web penipuan secara tidak sengaja. Selain itu, dengan pelayan yang hanya menyimpan kunci awam, penggodaman menjadi jauh lebih sukar."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Peralihan yang lancar"</string>
-    <string name="seamless_transition_detail" msgid="4475509237171739843">"Semasa kita bergerak menuju ke arah masa depan tanpa kata laluan, kata laluan masih akan tersedia bersama dengan kunci laluan."</string>
+    <string name="seamless_transition_detail" msgid="4475509237171739843">"Meskipun masa depan kita nanti tidak memerlukan kata laluan, kata laluan masih akan tersedia bersama dengan kunci laluan."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Pilih tempat untuk menyimpan <xliff:g id="CREATETYPES">%1$s</xliff:g> anda"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Pilih Password Manager untuk menyimpan maklumat anda dan log masuk lebih pantas pada kali seterusnya"</string>
     <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Cipta kunci laluan untuk <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -59,7 +59,7 @@
     <string name="use_once" msgid="9027366575315399714">"Gunakan sekali"</string>
     <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> kata laluan • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> kunci laluan"</string>
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"Kata laluan <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>"</string>
-    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"Kunci laluan <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g>"</string>
+    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> kunci laluan"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> bukti kelayakan"</string>
     <string name="passkey_before_subtitle" msgid="2448119456208647444">"Kunci laluan"</string>
     <string name="another_device" msgid="5147276802037801217">"Peranti lain"</string>
diff --git a/packages/CredentialManager/res/values-nb/strings.xml b/packages/CredentialManager/res/values-nb/strings.xml
index a041c81..33b0b3ae 100644
--- a/packages/CredentialManager/res/values-nb/strings.xml
+++ b/packages/CredentialManager/res/values-nb/strings.xml
@@ -24,19 +24,19 @@
     <string name="string_learn_more" msgid="4541600451688392447">"Finn ut mer"</string>
     <string name="content_description_show_password" msgid="3283502010388521607">"Vis passordet"</string>
     <string name="content_description_hide_password" msgid="6841375971631767996">"Skjul passordet"</string>
-    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Tryggere med tilgangsnøkler"</string>
-    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Med tilgangsnøkler trenger du ikke å lage eller huske kompliserte passord"</string>
-    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Tilgangsnøkler er krypterte digitale nøkler du oppretter med fingeravtrykket, ansiktet eller skjermlåsen"</string>
+    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Tryggere med passnøkler"</string>
+    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Med passnøkler trenger du ikke å lage eller huske kompliserte passord"</string>
+    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Passnøkler er krypterte digitale nøkler du oppretter med fingeravtrykket, ansiktet eller skjermlåsen"</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"De lagres i et verktøy for passordlagring, slik at du kan logge på andre enheter"</string>
-    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Mer om tilgangsnøkler"</string>
+    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Mer om passnøkler"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Passordfri teknologi"</string>
-    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Med tilgangsnøkler kan du logge på uten å bruke passord. Du trenger bare å bruke et fingeravtrykk, ansiktsgjenkjenning, en PIN-kode eller et sveipemønster for å bekrefte hvem du er, og lage en tilgangsnøkkel."</string>
+    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Med passnøkler kan du logge på uten å bruke passord. Du trenger bare å bruke et fingeravtrykk, ansiktsgjenkjenning, en PIN-kode eller et sveipemønster for å bekrefte hvem du er, og lage en passnøkkel."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"Kryptografi for offentlige nøkler"</string>
-    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Tilgangsnøkler er basert på FIDO Alliance (med bl.a. Google, Apple og Microsoft) og W3C-standardene og bruker kryptografiske nøkkelpar. I stedet for brukernavn og strenger med tegn som brukes som passord, opprettes det et privat-offentlig nøkkelpar per app eller nettsted. Den private nøkkelen lagres trygt på enheten eller i passordlagringen og bekrefter hvem du er. Den offentlige nøkkelen deles med app- eller nettstedstjeneren. Med korresponderende nøkler kan du raskt registrere deg og logge på."</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Passnøkler er basert på FIDO Alliance (med bl.a. Google, Apple og Microsoft) og W3C-standardene og bruker kryptografiske nøkkelpar. I stedet for brukernavn og strenger med tegn som brukes som passord, opprettes det et privat-offentlig nøkkelpar per app eller nettsted. Den private nøkkelen lagres trygt på enheten eller i passordlagringen og bekrefter hvem du er. Den offentlige nøkkelen deles med app- eller nettstedstjeneren. Med korresponderende nøkler kan du raskt registrere deg og logge på."</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"Forbedret kontosikkerhet"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"Hver nøkkel er eksklusivt tilknyttet appen eller nettstedet den er laget for. Dermed kan du aldri logge på falske apper eller nettsteder ved et uhell. Og siden tjenerne bare har offentlige nøkler, blir det mye vanskeligere å hacke deg."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Sømløs overgang"</string>
-    <string name="seamless_transition_detail" msgid="4475509237171739843">"Vi går mot en fremtid uten passord, men passord fortsetter å være tilgjengelige ved siden av tilgangsnøkler."</string>
+    <string name="seamless_transition_detail" msgid="4475509237171739843">"Vi går mot en fremtid uten passord, men passord fortsetter å være tilgjengelige ved siden av passnøkler."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Velg hvor du vil lagre <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Velg et verktøy for passordlagring for å lagre informasjonen din og logge på raskere neste gang"</string>
     <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vil du opprette en tilgangsnøkkel for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -44,7 +44,7 @@
     <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Vil du lagre påloggingsinformasjon for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"tilgangsnøkkel"</string>
     <string name="password" msgid="6738570945182936667">"passord"</string>
-    <string name="passkeys" msgid="5733880786866559847">"tilgangsnøkler"</string>
+    <string name="passkeys" msgid="5733880786866559847">"passnøkler"</string>
     <string name="passwords" msgid="5419394230391253816">"passord"</string>
     <string name="sign_ins" msgid="4710739369149469208">"pålogginger"</string>
     <string name="sign_in_info" msgid="2627704710674232328">"påloggingsinformasjon"</string>
@@ -53,13 +53,13 @@
     <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Vil du lagre passordet på en annen enhet?"</string>
     <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Vil du lagre pålogging på en annen enhet?"</string>
     <string name="use_provider_for_all_title" msgid="4201020195058980757">"Vil du bruke <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> for alle pålogginger?"</string>
-    <string name="use_provider_for_all_description" msgid="1998772715863958997">"Dette verktøyet for passordlagring for <xliff:g id="USERNAME">%1$s</xliff:g> lagrer passord og tilgangsnøkler, så det blir lett å logge på"</string>
+    <string name="use_provider_for_all_description" msgid="1998772715863958997">"Dette verktøyet for passordlagring for <xliff:g id="USERNAME">%1$s</xliff:g> lagrer passord og passnøkler, så det blir lett å logge på"</string>
     <string name="set_as_default" msgid="4415328591568654603">"Angi som standard"</string>
     <string name="settings" msgid="6536394145760913145">"Innstillinger"</string>
     <string name="use_once" msgid="9027366575315399714">"Bruk én gang"</string>
-    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> passord • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> tilgangsnøkler"</string>
+    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> passord • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> passnøkler"</string>
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> passord"</string>
-    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> tilgangsnøkler"</string>
+    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> passnøkler"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g>-legitimasjon"</string>
     <string name="passkey_before_subtitle" msgid="2448119456208647444">"Tilgangsnøkkel"</string>
     <string name="another_device" msgid="5147276802037801217">"En annen enhet"</string>
diff --git a/packages/CredentialManager/res/values-or/strings.xml b/packages/CredentialManager/res/values-or/strings.xml
index 5670dcb..150ef0b 100644
--- a/packages/CredentialManager/res/values-or/strings.xml
+++ b/packages/CredentialManager/res/values-or/strings.xml
@@ -36,7 +36,7 @@
     <string name="improved_account_security_title" msgid="1069841917893513424">"ଉନ୍ନତ ଆକାଉଣ୍ଟ ସୁରକ୍ଷା"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"ପ୍ରତ୍ୟେକ କୀ\'କୁ ସେହି ଆପ କିମ୍ବା ୱେବସାଇଟ ସହ ଏକ୍ସକ୍ଲୁସିଭ ଭାବେ ଲିଙ୍କ କରାଯାଏ ଯେଉଁଥିପାଇଁ ଏହାକୁ ତିଆରି କରାଯାଇଛି, ଫଳରେ ଆପଣ ଭୁଲବଶତଃ କୌଣସି ପ୍ରତାରଣାମୂଳକ ଆପ କିମ୍ବା ୱେବସାଇଟରେ କେବେ ବି ସାଇନ ଇନ କରିପାରିବେ ନାହିଁ। ଏହା ସହ, କେବଳ ସର୍ଭରଗୁଡ଼ିକ ସାର୍ବଜନୀନ କୀ ରଖୁଥିବା ଯୋଗୁଁ ଏହାକୁ ହେକ କରିବା ବହୁତ କଷ୍ଟକର।"</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"ବାଧାରହିତ ଟ୍ରାଞ୍ଜିସନ"</string>
-    <string name="seamless_transition_detail" msgid="4475509237171739843">"ଆମେ ଏକ ପାସୱାର୍ଡ ବିହୀନ ଭବିଷ୍ୟତ ଆଡ଼କୁ ମୁଭ କରୁଥିବା ଯୋଗୁଁ ଏବେ ବି ପାସକୀଗୁଡ଼ିକ ସହିତ ପାସୱାର୍ଡ ଉପଲବ୍ଧ ହେବ।"</string>
+    <string name="seamless_transition_detail" msgid="4475509237171739843">"ଆମେ ଏକ ପାସୱାର୍ଡବିହୀନ ଭବିଷ୍ୟତ ଆଡ଼କୁ ମୁଭ କରୁଥିବା ଯୋଗୁଁ ଏବେ ବି ପାସକୀଗୁଡ଼ିକ ସହିତ ପାସୱାର୍ଡ ଉପଲବ୍ଧ ହେବ।"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"ଆପଣଙ୍କ <xliff:g id="CREATETYPES">%1$s</xliff:g> କେଉଁଠାରେ ସେଭ କରିବେ ତାହା ବାଛନ୍ତୁ"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"ଆପଣଙ୍କ ସୂଚନା ସେଭ କରି ପରବର୍ତ୍ତୀ ସମୟରେ ଶୀଘ୍ର ସାଇନ ଇନ କରିବା ପାଇଁ ଏକ Password Manager ଚୟନ କରନ୍ତୁ"</string>
     <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> ପାଇଁ ପାସକୀ ତିଆରି କରିବେ?"</string>
diff --git a/packages/CredentialManager/res/values-pt-rBR/strings.xml b/packages/CredentialManager/res/values-pt-rBR/strings.xml
index 5a838ae..93459e6 100644
--- a/packages/CredentialManager/res/values-pt-rBR/strings.xml
+++ b/packages/CredentialManager/res/values-pt-rBR/strings.xml
@@ -26,7 +26,7 @@
     <string name="content_description_hide_password" msgid="6841375971631767996">"Ocultar senha"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Mais segurança com as chaves de acesso"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Com as chaves de acesso, você não precisa criar nem se lembrar de senhas complexas"</string>
-    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"As chaves de acesso são chaves digitais criptografadas que você cria usando a impressão digital, o rosto ou o bloqueio de tela"</string>
+    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"As chaves de acesso são chaves digitais criptografadas que você cria usando a impressão digital, o rosto ou o bloqueio de tela."</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Elas são salvas em um gerenciador de senhas para que você possa fazer login em outros dispositivos"</string>
     <string name="more_about_passkeys_title" msgid="7797903098728837795">"Saiba mais sobre chaves de acesso"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Tecnologia sem senha"</string>
diff --git a/packages/CredentialManager/res/values-pt/strings.xml b/packages/CredentialManager/res/values-pt/strings.xml
index 5a838ae..93459e6 100644
--- a/packages/CredentialManager/res/values-pt/strings.xml
+++ b/packages/CredentialManager/res/values-pt/strings.xml
@@ -26,7 +26,7 @@
     <string name="content_description_hide_password" msgid="6841375971631767996">"Ocultar senha"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Mais segurança com as chaves de acesso"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Com as chaves de acesso, você não precisa criar nem se lembrar de senhas complexas"</string>
-    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"As chaves de acesso são chaves digitais criptografadas que você cria usando a impressão digital, o rosto ou o bloqueio de tela"</string>
+    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"As chaves de acesso são chaves digitais criptografadas que você cria usando a impressão digital, o rosto ou o bloqueio de tela."</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Elas são salvas em um gerenciador de senhas para que você possa fazer login em outros dispositivos"</string>
     <string name="more_about_passkeys_title" msgid="7797903098728837795">"Saiba mais sobre chaves de acesso"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Tecnologia sem senha"</string>
diff --git a/packages/CredentialManager/res/values-sl/strings.xml b/packages/CredentialManager/res/values-sl/strings.xml
index c0a9064..16ba222 100644
--- a/packages/CredentialManager/res/values-sl/strings.xml
+++ b/packages/CredentialManager/res/values-sl/strings.xml
@@ -44,7 +44,7 @@
     <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Želite shraniti podatke za prijavo za aplikacijo <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"ključ za dostop"</string>
     <string name="password" msgid="6738570945182936667">"geslo"</string>
-    <string name="passkeys" msgid="5733880786866559847">"ključev za dostop"</string>
+    <string name="passkeys" msgid="5733880786866559847">"ključi za dostop"</string>
     <string name="passwords" msgid="5419394230391253816">"gesel"</string>
     <string name="sign_ins" msgid="4710739369149469208">"prijave"</string>
     <string name="sign_in_info" msgid="2627704710674232328">"podatkov za prijavo"</string>
diff --git a/packages/CredentialManager/res/values-sq/strings.xml b/packages/CredentialManager/res/values-sq/strings.xml
index d70cf4d..40f8dc4 100644
--- a/packages/CredentialManager/res/values-sq/strings.xml
+++ b/packages/CredentialManager/res/values-sq/strings.xml
@@ -26,7 +26,7 @@
     <string name="content_description_hide_password" msgid="6841375971631767996">"Fshih fjalëkalimin"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Më e sigurt me çelësat e kalimit"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Me çelësat e kalimit, nuk ka nevojë të krijosh ose të mbash mend fjalëkalime të ndërlikuara"</string>
-    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Çelësat e kalimit kanë çelësa dixhitalë të enkriptuar që ti i krijon duke përdorur gjurmën e gishtit, fytyrën ose kyçjen e ekranit"</string>
+    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Çelësat e kalimit janë çelësa dixhitalë të enkriptuar që ti i krijon duke përdorur gjurmën e gishtit, fytyrën ose kyçjen e ekranit"</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Ata ruhen te një menaxher fjalëkalimesh, në mënyrë që të mund të identifikohesh në pajisje të tjera"</string>
     <string name="more_about_passkeys_title" msgid="7797903098728837795">"Më shumë rreth çelësave të kalimit"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Teknologji pa fjalëkalime"</string>
diff --git a/packages/CredentialManager/res/values-sw/strings.xml b/packages/CredentialManager/res/values-sw/strings.xml
index 56e743d..ffb4fa0 100644
--- a/packages/CredentialManager/res/values-sw/strings.xml
+++ b/packages/CredentialManager/res/values-sw/strings.xml
@@ -57,7 +57,7 @@
     <string name="set_as_default" msgid="4415328591568654603">"Weka iwe chaguomsingi"</string>
     <string name="settings" msgid="6536394145760913145">"Mipangilio"</string>
     <string name="use_once" msgid="9027366575315399714">"Tumia mara moja"</string>
-    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Manenosiri <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • funguo <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> za siri"</string>
+    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Manenosiri <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Funguo <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> za siri"</string>
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"Manenosiri <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>"</string>
     <string name="more_options_usage_passkeys" msgid="5390320437243042237">"Funguo <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> za siri"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"Kitambulisho cha <xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-ta/strings.xml b/packages/CredentialManager/res/values-ta/strings.xml
index fba0f3c..750b67d 100644
--- a/packages/CredentialManager/res/values-ta/strings.xml
+++ b/packages/CredentialManager/res/values-ta/strings.xml
@@ -59,7 +59,7 @@
     <string name="use_once" msgid="9027366575315399714">"ஒருமுறை பயன்படுத்தவும்"</string>
     <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> கடவுச்சொற்கள் • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> கடவுச்சாவிகள்"</string>
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> கடவுச்சொற்கள்"</string>
-    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> கடவுக்குறியீடுகள்"</string>
+    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> கடவுச்சாவிகள்"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> அனுமதிச் சான்றுகள்"</string>
     <string name="passkey_before_subtitle" msgid="2448119456208647444">"கடவுச்சாவி"</string>
     <string name="another_device" msgid="5147276802037801217">"மற்றொரு சாதனம்"</string>
diff --git a/packages/CredentialManager/res/values-te/strings.xml b/packages/CredentialManager/res/values-te/strings.xml
index 047d498..064ee96 100644
--- a/packages/CredentialManager/res/values-te/strings.xml
+++ b/packages/CredentialManager/res/values-te/strings.xml
@@ -32,7 +32,7 @@
     <string name="passwordless_technology_title" msgid="2497513482056606668">"పాస్‌వర్డ్ రహిత టెక్నాలజీ"</string>
     <string name="passwordless_technology_detail" msgid="6853928846532955882">"పాస్‌వర్డ్‌లపై ఆధారపడకుండా సైన్ ఇన్ చేయడానికి పాస్-కీలు మిమ్మల్ని అనుమతిస్తాయి. మీ గుర్తింపును వెరిఫై చేసి, పాస్-కీని క్రియేట్ చేయడానికి మీరు మీ వేలిముద్ర, ముఖ గుర్తింపు, PIN, లేదా స్వైప్ ఆకృతిని ఉపయోగించాలి."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"పబ్లిక్ కీ క్రిప్టోగ్రఫీ"</string>
-    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (దీనిలో Google, Apple, Microsoft, మరిన్ని ఉన్నాయి), W3C ప్రమాణాల ప్రకారం, పాస్‌కీలు క్రిప్టోగ్రాఫిక్ కీల జతలను ఉపయోగిస్తాయి. మనం పాస్‌వర్డ్‌ల కోసం ఉపయోగించే యూజర్‌నేమ్, అక్షరాల స్ట్రింగ్ కాకుండా, యాప్ లేదా సైట్ కోసం ప్రైవేట్-పబ్లిక్ కీల జత క్రియేట్ చేయబడుతుంది. ప్రైవేట్ కీ మీ డివైజ్/పాస్‌వర్డ్ మేనేజర్‌లో సురక్షితంగా స్టోర్ చేయబడుతుంది, ఇది మీ గుర్తింపును నిర్ధారిస్తుంది. పబ్లిక్ కీ, యాప్/వెబ్‌సైట్ సర్వర్‌తో షేర్ చేయబడుతుంది. సంబంధిత కీలతో, తక్షణమే రిజిస్టర్ చేసుకొని, సైన్ ఇన్ చేయవచ్చు."</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (దీనిలో Google, Apple, Microsoft, మరిన్ని ఉన్నాయి), W3C ప్రమాణాల ప్రకారం, పాస్‌కీలు క్రిప్టోగ్రాఫిక్ కీల జతలను ఉపయోగిస్తాయి. మనం పాస్‌వర్డ్‌ల కోసం ఉపయోగించే యూజర్‌నేమ్, అక్షరాల స్ట్రింగ్ కాకుండా, యాప్/సైట్ కోసం ప్రైవేట్-పబ్లిక్ కీల జత క్రియేట్ చేయబడుతుంది. ప్రైవేట్ కీ మీ డివైజ్/పాస్‌వర్డ్ మేనేజర్‌లో సురక్షితంగా స్టోర్ చేయబడుతుంది, ఇది మీ గుర్తింపును నిర్ధారిస్తుంది. పబ్లిక్ కీ, యాప్/వెబ్‌సైట్ సర్వర్‌తో షేర్ చేయబడుతుంది. సంబంధిత కీలతో, తక్షణమే రిజిస్టర్ చేసుకొని, సైన్ ఇన్ చేయవచ్చు."</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"మెరుగైన ఖాతా సెక్యూరిటీ"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"ప్రతి కీ దానిని క్రియేట్ చేసిన యాప్ లేదా వెబ్‌సైట్‌తో ప్రత్యేకంగా లింక్ చేయబడి ఉంటుంది, కాబట్టి మీరు పొరపాటున కూడా మోసపూరిత యాప్ లేదా వెబ్‌సైట్‌కు సైన్ ఇన్ చేయలేరు. అంతే కాకుండా, సర్వర్‌లు పబ్లిక్ కీలను మాత్రమే స్టోర్ చేయడం వల్ల, హ్యాకింగ్ చేయడం చాలా కష్టం."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"అవాంతరాలు లేని పరివర్తన"</string>
diff --git a/packages/CredentialManager/res/values-tl/strings.xml b/packages/CredentialManager/res/values-tl/strings.xml
index 6cd134d..e33f1bf 100644
--- a/packages/CredentialManager/res/values-tl/strings.xml
+++ b/packages/CredentialManager/res/values-tl/strings.xml
@@ -32,7 +32,7 @@
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Teknolohiyang hindi gumagamit ng password"</string>
     <string name="passwordless_technology_detail" msgid="6853928846532955882">"Sa pamamagitan ng mga passkey, makakapag-sign in ka nang hindi umaasa sa mga password. Kailangan mo lang gamitin ang iyong fingerprint, pagkilala ng mukha, PIN, o swipe pattern para i-verify ang pagkakakilanlan mo at gumawa ng passkey."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"Cryptography ng pampublikong key"</string>
-    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Batay sa FIDO Alliance (na kinabibilangan ng Google, Apple, Microsoft, atbp) at W3C standards, gumagamit ang passkeys ng cryptographic key pairs. Hindi tulad ng username at string ng characters na ginagamit sa password, para sa app o website ginagawa ang private-public key pair. Ligtas na naka-store sa device o password manager ang private key at kinukumpirma nito ang identity. Naka-share sa app o website server ang public key. Gamit ang key, instant kang makakapag-register at makakapag-sign in."</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Batay sa FIDO Alliance (na kinabibilangan ng Google, Apple, Microsoft, atbp) at W3C standards, gumagamit ang mga passkey ng cryptographic key pairs. Hindi tulad ng username at string ng characters na ginagamit sa password, para sa app o website ginagawa ang private-public key pair. Ligtas na naka-store sa device o password manager ang private key at kinukumpirma nito ang identity. Naka-share sa app o website server ang public key. Gamit ang key, instant kang makakapag-register at makakapag-sign in."</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"Pinahusay na seguridad sa account"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"Eksklusibong naka-link sa app o website kung para saan ginawa ang bawat key, kaya hindi ka makakapag-sign in sa isang mapanlokong app o website nang hindi sinasadya. Bukod pa rito, dahil mga pampublikong key lang ang itinatabi ng mga server, lubos na mas mahirap ang pag-hack."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Madaling transition"</string>
diff --git a/packages/CredentialManager/res/values-tr/strings.xml b/packages/CredentialManager/res/values-tr/strings.xml
index a3b72d5..30d1773 100644
--- a/packages/CredentialManager/res/values-tr/strings.xml
+++ b/packages/CredentialManager/res/values-tr/strings.xml
@@ -24,19 +24,19 @@
     <string name="string_learn_more" msgid="4541600451688392447">"Daha fazla bilgi"</string>
     <string name="content_description_show_password" msgid="3283502010388521607">"Şifreyi göster"</string>
     <string name="content_description_hide_password" msgid="6841375971631767996">"Şifreyi gizle"</string>
-    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Şifre anahtarlarıyla daha yüksek güvenlik"</string>
-    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Şifre anahtarı kullandığınızda karmaşık şifreler oluşturmanız veya bunları hatırlamanız gerekmez"</string>
-    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Şifre anahtarları; parmak iziniz, yüzünüz veya ekran kilidinizi kullanarak oluşturduğunuz şifrelenmiş dijital anahtarlardır"</string>
+    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Geçiş anahtarlarıyla daha yüksek güvenlik"</string>
+    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Geçiş anahtarı kullandığınızda karmaşık şifreler oluşturmanız veya bunları hatırlamanız gerekmez"</string>
+    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Geçiş anahtarları; parmak iziniz, yüzünüz veya ekran kilidinizi kullanarak oluşturduğunuz şifrelenmiş dijital anahtarlardır"</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Diğer cihazlarda oturum açabilmeniz için şifre anahtarları bir şifre yöneticisine kaydedilir"</string>
-    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Şifre anahtarları hakkında daha fazla bilgi"</string>
+    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Geçiş anahtarları hakkında daha fazla bilgi"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Şifresiz teknoloji"</string>
-    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Şifre anahtarları, şifre kullanmadan oturum açmanıza olanak tanır. Kimliğinizi doğrulayıp şifre anahtarı oluşturmak için parmak iziniz, yüz tanıma özelliği, PIN veya kaydırma deseni kullanmanız yeterlidir."</string>
+    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Geçiş anahtarları, şifre kullanmadan oturum açmanıza olanak tanır. Kimliğinizi doğrulayıp geçiş anahtarı oluşturmak için parmak iziniz, yüz tanıma özelliği, PIN veya kaydırma deseni kullanmanız yeterlidir."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"Ortak anahtar kriptografisi"</string>
-    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Şifre anahtarları, FIDO Alliance (Google, Apple, Microsoft ve daha pek çok şirket yer alır) ve W3C standartları uyarınca şifreleme anahtarı çiftleri kullanır. Şifrelerde kullandığımız kullanıcı adı ve karakter dizisinden farklı olarak bir uygulama veya web sitesi için özel-ortak anahtar çifti oluşturulur. Özel anahtar, cihazınızda ya da şifre yöneticinizde güvenle saklanır ve kimliğinizi doğrular. Ortak anahtar, uygulama veya web sitesi sunucusuyla paylaşılır. İlgili anahtarları kullanarak anında kaydolabilir ve oturum açabilirsiniz."</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Geçiş anahtarları, FIDO Alliance (Google, Apple, Microsoft ve daha pek çok şirket yer alır) ve W3C standartları uyarınca şifreleme anahtarı çiftleri kullanır. Şifrelerde kullandığımız kullanıcı adı ve karakter dizisinden farklı olarak bir uygulama veya web sitesi için özel-ortak anahtar çifti oluşturulur. Özel anahtar, cihazınızda ya da şifre yöneticinizde güvenle saklanır ve kimliğinizi doğrular. Ortak anahtar, uygulama veya web sitesi sunucusuyla paylaşılır. İlgili anahtarları kullanarak anında kaydolabilir ve oturum açabilirsiniz."</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"Daha iyi hesap güvenliği"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"Her anahtar, oluşturulduğu uygulama veya web sitesiyle özel olarak bağlantılı olduğu için sahte bir uygulamaya veya web sitesine hiçbir zaman yanlışlıkla giriş yapamazsınız. Ayrıca, sunucularda yalnızca ortak anahtarlar saklandığı için saldırıya uğramak daha zordur."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Sorunsuz geçiş"</string>
-    <string name="seamless_transition_detail" msgid="4475509237171739843">"Şifresiz bir geleceğe doğru ilerlerken şifreler, şifre anahtarlarıyla birlikte kullanılmaya devam edecektir."</string>
+    <string name="seamless_transition_detail" msgid="4475509237171739843">"Şifresiz bir geleceğe doğru ilerlerken şifreler, geçiş anahtarlarıyla birlikte kullanılmaya devam edecektir."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> kaydedileceği yeri seçin"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Bilgilerinizi kaydedip bir dahaki sefere daha hızlı oturum açmak için bir şifre yöneticisi seçin"</string>
     <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> için şifre anahtarı oluşturulsun mu?"</string>
@@ -44,7 +44,7 @@
     <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> için oturum açma bilgileri kaydedilsin mi?"</string>
     <string name="passkey" msgid="632353688396759522">"Şifre anahtarı"</string>
     <string name="password" msgid="6738570945182936667">"Şifre"</string>
-    <string name="passkeys" msgid="5733880786866559847">"Şifre anahtarlarınızın"</string>
+    <string name="passkeys" msgid="5733880786866559847">"Geçiş anahtarlarınızın"</string>
     <string name="passwords" msgid="5419394230391253816">"şifreler"</string>
     <string name="sign_ins" msgid="4710739369149469208">"oturum aç"</string>
     <string name="sign_in_info" msgid="2627704710674232328">"Oturum açma bilgileri"</string>
@@ -53,13 +53,13 @@
     <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Şifre başka bir cihaza kaydedilsin mi?"</string>
     <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Oturum açma bilgileri başka bir cihaza kaydedilsin mi?"</string>
     <string name="use_provider_for_all_title" msgid="4201020195058980757">"Tüm oturum açma işlemlerinizde <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> kullanılsın mı?"</string>
-    <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> için bu şifre yöneticisi, şifrelerinizi ve şifre anahtarlarınızı saklayarak kolayca oturum açmanıza yardımcı olur"</string>
+    <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> için bu şifre yöneticisi, şifrelerinizi ve geçiş anahtarlarınızı saklayarak kolayca oturum açmanıza yardımcı olur"</string>
     <string name="set_as_default" msgid="4415328591568654603">"Varsayılan olarak ayarla"</string>
     <string name="settings" msgid="6536394145760913145">"Ayarlar"</string>
     <string name="use_once" msgid="9027366575315399714">"Bir kez kullanın"</string>
-    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> şifre • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> şifre anahtarı"</string>
+    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> şifre • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> geçiş anahtarı"</string>
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> şifre"</string>
-    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> şifre anahtarı"</string>
+    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> geçiş anahtarı"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> kimlik bilgileri"</string>
     <string name="passkey_before_subtitle" msgid="2448119456208647444">"Şifre anahtarı"</string>
     <string name="another_device" msgid="5147276802037801217">"Başka bir cihaz"</string>
diff --git a/packages/CredentialManager/res/values-uk/strings.xml b/packages/CredentialManager/res/values-uk/strings.xml
index c672385..78a5a5b 100644
--- a/packages/CredentialManager/res/values-uk/strings.xml
+++ b/packages/CredentialManager/res/values-uk/strings.xml
@@ -36,7 +36,7 @@
     <string name="improved_account_security_title" msgid="1069841917893513424">"Підвищена безпека облікового запису"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"Кожен ключ зв’язано виключно з додатком або веб-сайтом, для якого його створено, тому ви ніколи не зможете помилково ввійти в шахрайський додаток чи на шахрайський веб-сайт. Крім того, коли на серверах зберігаються лише відкриті ключі, зламати захист набагато складніше."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Плавний перехід"</string>
-    <string name="seamless_transition_detail" msgid="4475509237171739843">"На шляху до безпарольного майбутнього паролі й надалі будуть використовуватися паралельно з ключами."</string>
+    <string name="seamless_transition_detail" msgid="4475509237171739843">"На шляху до безпарольного майбутнього паролі й надалі будуть використовуватися паралельно з ключами доступу."</string>
     <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="5220979185879006862">"Створити ключ доступу для додатка <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
diff --git a/packages/CredentialManager/res/values-uz/strings.xml b/packages/CredentialManager/res/values-uz/strings.xml
index 5797121..a0785b6 100644
--- a/packages/CredentialManager/res/values-uz/strings.xml
+++ b/packages/CredentialManager/res/values-uz/strings.xml
@@ -25,18 +25,18 @@
     <string name="content_description_show_password" msgid="3283502010388521607">"Parolni koʻrsatish"</string>
     <string name="content_description_hide_password" msgid="6841375971631767996">"Parolni berkitish"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Kalitlar orqali qulay"</string>
-    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Kodlar yordami tufayli murakkab parollarni yaratish va eslab qolish shart emas"</string>
-    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Kodlar – bu barmoq izi, yuz yoki ekran qulfi yordamida yaratilgan shifrlangan raqamli identifikator."</string>
+    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Kalitlar yordami tufayli murakkab parollarni yaratish va eslab qolish shart emas"</string>
+    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Kalitlar – bu barmoq izi, yuz yoki ekran qulfi yordamida yaratilgan shifrlangan raqamli identifikator."</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Ular parollar menejerida saqlanadi va ulardan boshqa qurilmalarda hisobga kirib foydalanish mumkin"</string>
-    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Kodlar haqida batafsil"</string>
+    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Kalitlar haqida batafsil"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Parolsiz texnologiya"</string>
-    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Kodlar parollarga tayanmasdan tizimga kirish imkonini beradi. Shaxsingizni tasdiqlash va kod yaratish uchun barmoq izi, yuzni tanish, PIN kod yoki grafik kalitni surishdan foydalanishingiz kifoya."</string>
+    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Kalitlar tizimga parol ishlatmasdan kirish imkonini beradi. Shaxsingizni tasdiqlash va kod yaratish uchun barmoq izi, yuzni tanish, PIN kod yoki grafik kalitni surishdan foydalanishingiz kifoya."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"Ochiq kalit kriptografiyasi"</string>
     <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO Alliance (Google, Apple, Microsoft va boshqalar) va W3C standartlari asosida kodlar kriptografik kalitlar juftligidan foydalanadi. Parollarda ishlatiladigan foydalanuvchi nomi va belgilardan farqli ravishda, ilova yoki veb-sayt uchun maxfiy ochiq kalitlar juftligi yaratiladi. Maxfiy kalit qurilmangizda yoki parollar menejerida xavfsiz saqlanadi va u shaxsingizni tasdiqlaydi. Ochiq kalit ilova yoki veb-sayt serveriga ulashiladi. Mos kalitlar bilan darhol registratsiya va tizimga kirish mumkin."</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"Hisob xavfsizligi yaxshilandi"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"Har bir kalit faqat ular uchun yaratilgan ilova yoki veb-sayt bilan ulangan, shuning uchun siz hech qachon xatolik bilan soxta ilova yoki veb-saytga kira olmaysiz. Shuningdek, serverlar bilan faqat ochiq kalitlarni saqlagan holda, buzib kirish ancha qiyinroq boʻladi."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Uzluksiz oʻtish"</string>
-    <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsiz kelajak sari borayotganimizda, parollar kodlar bilan birga ishlatilishda davom etadi."</string>
+    <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsiz kelajak sari harakatlanar ekanmiz, parollar kalitlar bilan birga ishlatilishda davom etadi."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Bu <xliff:g id="CREATETYPES">%1$s</xliff:g> qayerga saqlanishini tanlang"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Maʼlumotlaringizni saqlash va keyingi safar tez kirish uchun parollar menejerini tanlang"</string>
     <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> uchun kod yaratilsinmi?"</string>
@@ -44,7 +44,7 @@
     <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> uchun kirish maʼlumoti saqlansinmi?"</string>
     <string name="passkey" msgid="632353688396759522">"kalit"</string>
     <string name="password" msgid="6738570945182936667">"parol"</string>
-    <string name="passkeys" msgid="5733880786866559847">"kodlar"</string>
+    <string name="passkeys" msgid="5733880786866559847">"kalitlar"</string>
     <string name="passwords" msgid="5419394230391253816">"parollar"</string>
     <string name="sign_ins" msgid="4710739369149469208">"kirishlar"</string>
     <string name="sign_in_info" msgid="2627704710674232328">"kirish maʼlumoti"</string>
@@ -57,7 +57,7 @@
     <string name="set_as_default" msgid="4415328591568654603">"Birlamchi deb belgilash"</string>
     <string name="settings" msgid="6536394145760913145">"Sozlamalar"</string>
     <string name="use_once" msgid="9027366575315399714">"Bir marta ishlatish"</string>
-    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> ta parol • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> ta kod"</string>
+    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> ta parol • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> ta kalit"</string>
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> ta parol"</string>
     <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> ta kalit"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> hisobi maʼlumotlari"</string>
diff --git a/packages/CredentialManager/res/values-vi/strings.xml b/packages/CredentialManager/res/values-vi/strings.xml
index 67b0e88..2cbfce8 100644
--- a/packages/CredentialManager/res/values-vi/strings.xml
+++ b/packages/CredentialManager/res/values-vi/strings.xml
@@ -24,19 +24,19 @@
     <string name="string_learn_more" msgid="4541600451688392447">"Tìm hiểu thêm"</string>
     <string name="content_description_show_password" msgid="3283502010388521607">"Hiện mật khẩu"</string>
     <string name="content_description_hide_password" msgid="6841375971631767996">"Ẩn mật khẩu"</string>
-    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"An toàn hơn nhờ khoá đăng nhập"</string>
-    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Mã xác thực giúp bạn tránh được việc phải tạo và ghi nhớ mật khẩu phức tạp"</string>
-    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Mã xác thực là các khoá kỹ thuật số được mã hoá mà bạn tạo bằng cách dùng vân tay, khuôn mặt hoặc phương thức khoá màn hình của mình"</string>
+    <string name="passkey_creation_intro_title" msgid="4251037543787718844">"An toàn hơn nhờ khoá truy cập"</string>
+    <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Khoá truy cập giúp bạn tránh được việc phải tạo và ghi nhớ mật khẩu phức tạp"</string>
+    <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Khoá truy cập là các khoá kỹ thuật số được mã hoá mà bạn tạo bằng cách dùng vân tay, khuôn mặt hoặc phương thức khoá màn hình của mình"</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"Thông tin này được lưu vào trình quản lý mật khẩu nên bạn có thể đăng nhập trên các thiết bị khác"</string>
-    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Xem thêm thông tin về khoá đăng nhập"</string>
+    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Xem thêm thông tin về khoá truy cập"</string>
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Công nghệ không dùng mật khẩu"</string>
-    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Khoá đăng nhập cho phép bạn đăng nhập mà không cần dựa vào mật khẩu. Bạn chỉ cần dùng vân tay, tính năng nhận dạng khuôn mặt, mã PIN hoặc hình mở khoá để xác minh danh tính và tạo khoá đăng nhập."</string>
+    <string name="passwordless_technology_detail" msgid="6853928846532955882">"Khoá truy cập cho phép bạn đăng nhập mà không cần dựa vào mật khẩu. Bạn chỉ cần dùng vân tay, tính năng nhận dạng khuôn mặt, mã PIN hoặc hình mở khoá để xác minh danh tính và tạo khoá truy cập."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"Mã hoá khoá công khai"</string>
-    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Dựa trên Liên minh FIDO (bao gồm Google, Apple, Microsoft, v.v.) và tiêu chuẩn W3C, khoá đăng nhập sử dụng cặp khoá mã hoá. Khác với tên người dùng và chuỗi ký tự chúng tôi dùng cho mật khẩu, một cặp khoá riêng tư – công khai được tạo cho một ứng dụng hoặc trang web. Khoá riêng tư được lưu trữ an toàn trên thiết bị hoặc trình quản lý mật khẩu và xác nhận danh tính của bạn. Khoá công khai được chia sẻ với máy chủ ứng dụng hoặc trang web. Với khoá tương ứng, bạn có thể đăng ký và đăng nhập tức thì."</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Dựa trên Liên minh FIDO (bao gồm Google, Apple, Microsoft, v.v.) và tiêu chuẩn W3C, khoá truy cập sử dụng cặp khoá mã hoá. Khác với tên người dùng và chuỗi ký tự chúng tôi dùng cho mật khẩu, một cặp khoá riêng tư – công khai được tạo cho một ứng dụng hoặc trang web. Khoá riêng tư được lưu trữ an toàn trên thiết bị hoặc trình quản lý mật khẩu và xác nhận danh tính của bạn. Khoá công khai được chia sẻ với máy chủ ứng dụng hoặc trang web. Với khoá tương ứng, bạn có thể đăng ký và đăng nhập tức thì."</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"Cải thiện tính bảo mật của tài khoản"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"Mỗi khoá được liên kết riêng với ứng dụng hoặc trang web mà khoá đó được tạo. Vì vậy, bạn sẽ không bao giờ đăng nhập nhầm vào một ứng dụng hoặc trang web lừa đảo. Ngoài ra, với các máy chủ chỉ lưu giữ khoá công khai, việc xâm nhập càng khó hơn nhiều."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Chuyển đổi liền mạch"</string>
-    <string name="seamless_transition_detail" msgid="4475509237171739843">"Trong quá trình chúng tôi hướng đến tương lai không dùng mật khẩu, bạn vẫn sẽ dùng được mật khẩu cùng với khoá đăng nhập."</string>
+    <string name="seamless_transition_detail" msgid="4475509237171739843">"Trong quá trình chúng tôi hướng đến tương lai không dùng mật khẩu, bạn vẫn sẽ dùng được mật khẩu cùng với khoá truy cập."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Chọn vị trí lưu <xliff:g id="CREATETYPES">%1$s</xliff:g> của bạn"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Hãy chọn một trình quản lý mật khẩu để lưu thông tin của bạn và đăng nhập nhanh hơn vào lần tới"</string>
     <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Tạo khoá đăng nhập cho <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -44,7 +44,7 @@
     <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Lưu thông tin đăng nhập cho <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"khoá đăng nhập"</string>
     <string name="password" msgid="6738570945182936667">"mật khẩu"</string>
-    <string name="passkeys" msgid="5733880786866559847">"khoá đăng nhập"</string>
+    <string name="passkeys" msgid="5733880786866559847">"khoá truy cập"</string>
     <string name="passwords" msgid="5419394230391253816">"mật khẩu"</string>
     <string name="sign_ins" msgid="4710739369149469208">"thông tin đăng nhập"</string>
     <string name="sign_in_info" msgid="2627704710674232328">"thông tin đăng nhập"</string>
@@ -53,13 +53,13 @@
     <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Lưu mật khẩu trên một thiết bị khác?"</string>
     <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Lưu thông tin đăng nhập trên một thiết bị khác?"</string>
     <string name="use_provider_for_all_title" msgid="4201020195058980757">"Dùng <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> cho mọi thông tin đăng nhập của bạn?"</string>
-    <string name="use_provider_for_all_description" msgid="1998772715863958997">"Trình quản lý mật khẩu này cho <xliff:g id="USERNAME">%1$s</xliff:g> sẽ lưu trữ mật khẩu và khoá đăng nhập để bạn dễ dàng đăng nhập"</string>
+    <string name="use_provider_for_all_description" msgid="1998772715863958997">"Trình quản lý mật khẩu này cho <xliff:g id="USERNAME">%1$s</xliff:g> sẽ lưu trữ mật khẩu và khoá truy cập để bạn dễ dàng đăng nhập"</string>
     <string name="set_as_default" msgid="4415328591568654603">"Đặt làm mặc định"</string>
     <string name="settings" msgid="6536394145760913145">"Cài đặt"</string>
     <string name="use_once" msgid="9027366575315399714">"Dùng một lần"</string>
-    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> mật khẩu • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> khoá đăng nhập"</string>
+    <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> mật khẩu • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> khoá truy cập"</string>
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> mật khẩu"</string>
-    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> khoá đăng nhập"</string>
+    <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> khoá truy cập"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> thông tin xác thực"</string>
     <string name="passkey_before_subtitle" msgid="2448119456208647444">"Mã xác thực"</string>
     <string name="another_device" msgid="5147276802037801217">"Thiết bị khác"</string>
diff --git a/packages/InputDevices/res/values-bg/strings.xml b/packages/InputDevices/res/values-bg/strings.xml
index 7abfcd4..1ee9565 100644
--- a/packages/InputDevices/res/values-bg/strings.xml
+++ b/packages/InputDevices/res/values-bg/strings.xml
@@ -38,7 +38,7 @@
     <string name="keyboard_layout_turkish" msgid="7736163250907964898">"турски"</string>
     <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"Турски (тип F)"</string>
     <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"украински"</string>
-    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"Арабска клавиатурна подредба"</string>
+    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"арабска клавиатурна подредба"</string>
     <string name="keyboard_layout_greek" msgid="7289253560162386040">"Гръцка клавиатурна подредба"</string>
     <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Ивритска клавиатурна подредба"</string>
     <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Литовска клавиатурна подредба"</string>
diff --git a/packages/InputDevices/res/values-et/strings.xml b/packages/InputDevices/res/values-et/strings.xml
index c835522..87c486f 100644
--- a/packages/InputDevices/res/values-et/strings.xml
+++ b/packages/InputDevices/res/values-et/strings.xml
@@ -3,7 +3,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="8016145283189546017">"Sisendseadmed"</string>
     <string name="keyboard_layouts_label" msgid="6688773268302087545">"Androidi klaviatuur"</string>
-    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Inglise (Ühendkuningriik)"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Inglise (ÜK)"</string>
     <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Inglise (USA)"</string>
     <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Inglise (USA), rahvusvaheline stiil"</string>
     <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Inglise (USA), Colemaki stiil"</string>
diff --git a/packages/InputDevices/res/values-hi/strings.xml b/packages/InputDevices/res/values-hi/strings.xml
index c3291a0..892fbc5 100644
--- a/packages/InputDevices/res/values-hi/strings.xml
+++ b/packages/InputDevices/res/values-hi/strings.xml
@@ -38,7 +38,7 @@
     <string name="keyboard_layout_turkish" msgid="7736163250907964898">"तुर्किये"</string>
     <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"Turkish F"</string>
     <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"यूक्रेनियाई"</string>
-    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"अरबी"</string>
+    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"ऐरेबिक"</string>
     <string name="keyboard_layout_greek" msgid="7289253560162386040">"ग्रीक"</string>
     <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"हिब्रू"</string>
     <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"लिथुआनियाई"</string>
diff --git a/packages/InputDevices/res/values-km/strings.xml b/packages/InputDevices/res/values-km/strings.xml
index e06ce2c8..fd63ab33c 100644
--- a/packages/InputDevices/res/values-km/strings.xml
+++ b/packages/InputDevices/res/values-km/strings.xml
@@ -45,7 +45,7 @@
     <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"អេស្ប៉ាញ (ឡាតាំង​)"</string>
     <string name="keyboard_layout_latvian" msgid="4405417142306250595">"ឡាតវីយ៉ា"</string>
     <string name="keyboard_layout_persian" msgid="3920643161015888527">"ពីស៊ាន"</string>
-    <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"អាហ្សឺបៃហ្សង់"</string>
+    <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"អាស៊ែបៃហ្សង់"</string>
     <string name="keyboard_layout_polish" msgid="1121588624094925325">"ប៉ូឡូញ"</string>
     <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"បេឡារុស"</string>
     <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"មុងហ្គោលី"</string>
diff --git a/packages/InputDevices/res/values-mr/strings.xml b/packages/InputDevices/res/values-mr/strings.xml
index c04006d..6382f6f 100644
--- a/packages/InputDevices/res/values-mr/strings.xml
+++ b/packages/InputDevices/res/values-mr/strings.xml
@@ -24,11 +24,11 @@
     <string name="keyboard_layout_danish" msgid="8036432066627127851">"डॅनिश"</string>
     <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"नॉर्वेजियन"</string>
     <string name="keyboard_layout_swedish" msgid="732959109088479351">"स्वीडिश"</string>
-    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"फिन्निश"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"फिनिश"</string>
     <string name="keyboard_layout_croatian" msgid="4172229471079281138">"क्रोएशियन"</string>
     <string name="keyboard_layout_czech" msgid="1349256901452975343">"झेक"</string>
     <string name="keyboard_layout_czech_qwerty" msgid="3331402534128515501">"Czech QWERTY शैली"</string>
-    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"एस्टोनियन"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"इस्टोनियन"</string>
     <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"हंगेरियन"</string>
     <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"आइसलँडिक"</string>
     <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"ब्राझिलियन"</string>
diff --git a/packages/InputDevices/res/values-or/strings.xml b/packages/InputDevices/res/values-or/strings.xml
index 52556ef..5b6aaea 100644
--- a/packages/InputDevices/res/values-or/strings.xml
+++ b/packages/InputDevices/res/values-or/strings.xml
@@ -3,8 +3,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="8016145283189546017">"ଇନପୁଟ୍‌ ଡିଭାଇସ୍"</string>
     <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android କୀ’ବୋର୍ଡ"</string>
-    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"ଇଂରାଜୀ (ୟୁକେ)"</string>
-    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"ଇଂରାଜୀ (ୟୁଏସ୍‍)"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"ଇଂରାଜୀ (ଯୁକ୍ତରାଜ୍ୟ)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"ଇଂରାଜୀ (ଯୁକ୍ତରାଷ୍ଟ୍ର)"</string>
     <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"ଇଂରାଜୀ (ୟୁଏସ୍‍), ଇଣ୍ଟରନେସନାଲ୍‍ ଷ୍ଟାଇଲ୍‍"</string>
     <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"ଇଂରାଜୀ (ୟୁଏସ୍‍), କୋଲେମକ୍‍ ଷ୍ଟାଇଲ୍‍"</string>
     <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"ଇଂରାଜୀ (ୟୁଏସ୍‍), ଡଭୋରାକ୍‌ ଷ୍ଟାଇଲ୍‍"</string>
@@ -21,14 +21,14 @@
     <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"ବୁଲଗାରିଆନ୍‍"</string>
     <string name="keyboard_layout_bulgarian_phonetic" msgid="7568914730360106653">"ବୁଲଗେରିଆନ୍, ଫୋନେଟିକ୍"</string>
     <string name="keyboard_layout_italian" msgid="6497079660449781213">"ଇଟାଲିୟାନ୍‌"</string>
-    <string name="keyboard_layout_danish" msgid="8036432066627127851">"ଡାନିଶ୍‍"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"ଡେନିସ"</string>
     <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"ନରୱେଜିଆନ୍"</string>
     <string name="keyboard_layout_swedish" msgid="732959109088479351">"ସ୍ଵେଡିଶ୍‌"</string>
-    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"ଫିନ୍ନିଶ୍‍"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"ଫିନ୍ନିସ"</string>
     <string name="keyboard_layout_croatian" msgid="4172229471079281138">"କ୍ରୋଆଶିଆନ୍"</string>
     <string name="keyboard_layout_czech" msgid="1349256901452975343">"ଚେକ୍"</string>
     <string name="keyboard_layout_czech_qwerty" msgid="3331402534128515501">"ଚେକ୍ QWERTY ଷ୍ଟାଇଲ୍"</string>
-    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"ଇଷ୍ଟୋନିଆନ୍"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"ଏଷ୍ଟୋନିଆନ"</string>
     <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"ହଙ୍ଗେରିଆନ୍"</string>
     <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"ଆଇସଲାଣ୍ଡିକ୍"</string>
     <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"ବ୍ରାଜିଲିୟାନ୍"</string>
@@ -38,14 +38,14 @@
     <string name="keyboard_layout_turkish" msgid="7736163250907964898">"ତୁର୍କିସ୍"</string>
     <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"ତୁର୍କିଶ୍ F"</string>
     <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ୟୁକ୍ରାନିଆନ୍"</string>
-    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"ଆରବିକ୍‍"</string>
+    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"ଆରବିକ"</string>
     <string name="keyboard_layout_greek" msgid="7289253560162386040">"ଗ୍ରୀକ୍"</string>
     <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"ହିବ୍ର୍ୟୁ"</string>
     <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"ଲିଥୁଆନିଆନ୍"</string>
     <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"ସ୍ପାନିଶ୍‍ (ଲାଟିନ୍‌)"</string>
     <string name="keyboard_layout_latvian" msgid="4405417142306250595">"ଲାଟିଭିଆନ୍‍"</string>
     <string name="keyboard_layout_persian" msgid="3920643161015888527">"ପାର୍ସିଆନ୍‌"</string>
-    <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"ଆଜେର୍‌ବୈଜାନି"</string>
+    <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"ଆଜରବୈଜାନି"</string>
     <string name="keyboard_layout_polish" msgid="1121588624094925325">"ପଲିଶ୍"</string>
     <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"ବେଲାରୁସିଆନ୍"</string>
     <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"ମଙ୍ଗୋଲିଆନ୍"</string>
diff --git a/packages/InputDevices/res/values-pa/strings.xml b/packages/InputDevices/res/values-pa/strings.xml
index f261fb52..988b449 100644
--- a/packages/InputDevices/res/values-pa/strings.xml
+++ b/packages/InputDevices/res/values-pa/strings.xml
@@ -3,8 +3,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="8016145283189546017">"ਇਨਪੁੱਟ ਡੀਵਾਈਸਾਂ"</string>
     <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android ਕੀ-ਬੋਰਡ"</string>
-    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"ਅੰਗ੍ਰੇਜ਼ੀ (ਯੂਕੇ)"</string>
-    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"ਅੰਗ੍ਰੇਜੀ (ਅਮ੍ਰੀਕਾ)"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"ਅੰਗਰੇਜ਼ੀ (ਯੂ.ਕੇ.)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"ਅੰਗਰੇਜ਼ੀ (ਯੂ.ਐੱਸ.)"</string>
     <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"ਅੰਗ੍ਰੇਜ਼ੀ (ਅਮਰੀਕਾ), ਅੰਤਰਰਾਸ਼ਟਰੀ ਸਟਾਈਲ"</string>
     <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"ਅੰਗ੍ਰੇਜ਼ੀ (ਅਮਰੀਕਾ), ਕੋਲਮਾਰਕ ਸਟਾਈਲ"</string>
     <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"ਅੰਗ੍ਰੇਜ਼ੀ (ਅਮਰੀਕਾ), ਵੋਰਕ ਸਟਾਈਲ"</string>
@@ -28,7 +28,7 @@
     <string name="keyboard_layout_croatian" msgid="4172229471079281138">"ਕਰੋਆਟੀਆਈ"</string>
     <string name="keyboard_layout_czech" msgid="1349256901452975343">"ਚੈਕ"</string>
     <string name="keyboard_layout_czech_qwerty" msgid="3331402534128515501">"ਚੈੱਕ QWERTY ਸਟਾਈਲ"</string>
-    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"ਇਸਟੋਨੀਅਨ"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"ਇਸਤੋਨੀਆਈ"</string>
     <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"ਹੰਗੇਰੀਅਨ"</string>
     <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"ਆਈਸਲੈਂਡੀ"</string>
     <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"ਬ੍ਰਾਜ਼ਿਲਿਆਈ"</string>
@@ -45,7 +45,7 @@
     <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"ਸਪੇਨੀ (ਲਾਤੀਨੀ)"</string>
     <string name="keyboard_layout_latvian" msgid="4405417142306250595">"ਲਾਤਵੀਅਨ"</string>
     <string name="keyboard_layout_persian" msgid="3920643161015888527">"ਫ਼ਾਰਸੀ"</string>
-    <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"ਅਜ਼ੇਰਬੈਜਾਨੀ"</string>
+    <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"ਅਜ਼ਰਬਾਈਜਾਨੀ"</string>
     <string name="keyboard_layout_polish" msgid="1121588624094925325">"ਪੋਲਿਸ਼"</string>
     <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"ਬੇਲਾਰੂਸੀ"</string>
     <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"ਮੰਗੋਲੀਆਈ"</string>
diff --git a/packages/InputDevices/res/values-sk/strings.xml b/packages/InputDevices/res/values-sk/strings.xml
index f87a9e9..5b239d4 100644
--- a/packages/InputDevices/res/values-sk/strings.xml
+++ b/packages/InputDevices/res/values-sk/strings.xml
@@ -38,7 +38,7 @@
     <string name="keyboard_layout_turkish" msgid="7736163250907964898">"turecké"</string>
     <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"Turečtina F"</string>
     <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ukrajinské"</string>
-    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"Arabčina"</string>
+    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"arabské"</string>
     <string name="keyboard_layout_greek" msgid="7289253560162386040">"Gréčtina"</string>
     <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Hebrejčina"</string>
     <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Litovčina"</string>
diff --git a/packages/InputDevices/res/values-sl/strings.xml b/packages/InputDevices/res/values-sl/strings.xml
index 09b3c31..334326c 100644
--- a/packages/InputDevices/res/values-sl/strings.xml
+++ b/packages/InputDevices/res/values-sl/strings.xml
@@ -38,7 +38,7 @@
     <string name="keyboard_layout_turkish" msgid="7736163250907964898">"turška"</string>
     <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"Turščina F"</string>
     <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ukrajinska"</string>
-    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"arabščina"</string>
+    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"arabska"</string>
     <string name="keyboard_layout_greek" msgid="7289253560162386040">"grščina"</string>
     <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"hebrejščina"</string>
     <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"litovščina"</string>
diff --git a/packages/InputDevices/res/values-th/strings.xml b/packages/InputDevices/res/values-th/strings.xml
index 5f60c3d..131c536 100644
--- a/packages/InputDevices/res/values-th/strings.xml
+++ b/packages/InputDevices/res/values-th/strings.xml
@@ -38,7 +38,7 @@
     <string name="keyboard_layout_turkish" msgid="7736163250907964898">"ตุรกี"</string>
     <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"ภาษาตุรกี F"</string>
     <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ยูเครน"</string>
-    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"ภาษาอารบิค"</string>
+    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"อารบิค"</string>
     <string name="keyboard_layout_greek" msgid="7289253560162386040">"กรีก"</string>
     <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"ฮิบรู"</string>
     <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"ลิทัวเนีย"</string>
diff --git a/packages/InputDevices/res/values-tr/strings.xml b/packages/InputDevices/res/values-tr/strings.xml
index 2877cb7..1a84d0ac 100644
--- a/packages/InputDevices/res/values-tr/strings.xml
+++ b/packages/InputDevices/res/values-tr/strings.xml
@@ -45,7 +45,7 @@
     <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"İspanyolca (Latin)"</string>
     <string name="keyboard_layout_latvian" msgid="4405417142306250595">"Letonca"</string>
     <string name="keyboard_layout_persian" msgid="3920643161015888527">"Farsça"</string>
-    <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"Azerice"</string>
+    <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"Azerbaycan dili"</string>
     <string name="keyboard_layout_polish" msgid="1121588624094925325">"Lehçe"</string>
     <string name="keyboard_layout_belarusian" msgid="7619281752698687588">"Belarusça"</string>
     <string name="keyboard_layout_mongolian" msgid="7678483495823936626">"Moğolca"</string>
diff --git a/packages/InputDevices/res/values-uk/strings.xml b/packages/InputDevices/res/values-uk/strings.xml
index 3b0de34..5368f2c 100644
--- a/packages/InputDevices/res/values-uk/strings.xml
+++ b/packages/InputDevices/res/values-uk/strings.xml
@@ -38,7 +38,7 @@
     <string name="keyboard_layout_turkish" msgid="7736163250907964898">"турецька"</string>
     <string name="keyboard_layout_turkish_f" msgid="9130320856010776018">"Турецька-F"</string>
     <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"українська"</string>
-    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"Арабська"</string>
+    <string name="keyboard_layout_arabic" msgid="5671970465174968712">"арабська"</string>
     <string name="keyboard_layout_greek" msgid="7289253560162386040">"Грецька"</string>
     <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Іврит"</string>
     <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Литовська"</string>
diff --git a/packages/PrintSpooler/res/values-ne/strings.xml b/packages/PrintSpooler/res/values-ne/strings.xml
index be7af70..13c3886 100644
--- a/packages/PrintSpooler/res/values-ne/strings.xml
+++ b/packages/PrintSpooler/res/values-ne/strings.xml
@@ -49,7 +49,7 @@
     <string name="print_options_collapsed" msgid="7455930445670414332">"कोल्याप्स गरेका विकल्पहरू प्रिन्ट गर्नुहोस्"</string>
     <string name="search" msgid="5421724265322228497">"खोज्नुहोस्"</string>
     <string name="all_printers_label" msgid="3178848870161526399">"सबै प्रिन्टरहरू"</string>
-    <string name="add_print_service_label" msgid="5356702546188981940">"सेवा थप्नुहोस्"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"सेवा हाल्नुहोस्"</string>
     <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"खोज बाकस देखाइयो"</string>
     <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"खोज बाकस लुकाइयो"</string>
     <string name="print_add_printer" msgid="1088656468360653455">"प्रिन्टर थप्नुहोस्"</string>
diff --git a/packages/SettingsLib/ActivityEmbedding/OWNERS b/packages/SettingsLib/ActivityEmbedding/OWNERS
index 7022402..6f1ab9b 100644
--- a/packages/SettingsLib/ActivityEmbedding/OWNERS
+++ b/packages/SettingsLib/ActivityEmbedding/OWNERS
@@ -1,5 +1,4 @@
 # Default reviewers for this and subdirectories.
-arcwang@google.com
-chiujason@google.com
+sunnyshao@google.com
 
 # Emergency approvers in case the above are not available
diff --git a/packages/SettingsLib/BannerMessagePreference/res/layout-v31/settingslib_banner_message.xml b/packages/SettingsLib/BannerMessagePreference/res/layout-v31/settingslib_banner_message.xml
index 6f504ef..9d53e39 100644
--- a/packages/SettingsLib/BannerMessagePreference/res/layout-v31/settingslib_banner_message.xml
+++ b/packages/SettingsLib/BannerMessagePreference/res/layout-v31/settingslib_banner_message.xml
@@ -50,6 +50,8 @@
         android:id="@+id/banner_title"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_gravity="start"
+        android:textAlignment="viewStart"
         android:paddingTop="0dp"
         android:paddingBottom="4dp"
         android:textAppearance="@style/Banner.Title.SettingsLib"/>
@@ -58,6 +60,8 @@
         android:id="@+id/banner_subtitle"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_gravity="start"
+        android:textAlignment="viewStart"
         android:paddingTop="0dp"
         android:paddingBottom="4dp"
         android:textAppearance="@style/Banner.Subtitle.SettingsLib"
@@ -67,6 +71,8 @@
         android:id="@+id/banner_summary"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_gravity="start"
+        android:textAlignment="viewStart"
         android:paddingTop="4dp"
         android:paddingBottom="8dp"
         android:textAppearance="@style/Banner.Summary.SettingsLib"/>
diff --git a/packages/SettingsLib/FooterPreference/res/layout-v31/preference_footer.xml b/packages/SettingsLib/FooterPreference/res/layout-v31/preference_footer.xml
index 42700b3..470a83d 100644
--- a/packages/SettingsLib/FooterPreference/res/layout-v31/preference_footer.xml
+++ b/packages/SettingsLib/FooterPreference/res/layout-v31/preference_footer.xml
@@ -50,6 +50,8 @@
             android:id="@android:id/title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_gravity="start"
+            android:textAlignment="viewStart"
             android:paddingTop="16dp"
             android:paddingBottom="8dp"
             android:textColor="?android:attr/textColorSecondary"
@@ -60,6 +62,8 @@
             android:text="@string/settingslib_learn_more_text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_gravity="start"
+            android:textAlignment="viewStart"
             android:paddingBottom="8dp"
             android:clickable="true"
             android:visibility="gone"
diff --git a/packages/SettingsLib/FooterPreference/res/layout-v33/preference_footer.xml b/packages/SettingsLib/FooterPreference/res/layout-v33/preference_footer.xml
index a2f2510..4b5fd44 100644
--- a/packages/SettingsLib/FooterPreference/res/layout-v33/preference_footer.xml
+++ b/packages/SettingsLib/FooterPreference/res/layout-v33/preference_footer.xml
@@ -50,6 +50,8 @@
             android:id="@android:id/title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_gravity="start"
+            android:textAlignment="viewStart"
             android:paddingTop="16dp"
             android:paddingBottom="8dp"
             android:textColor="?android:attr/textColorSecondary"
@@ -62,6 +64,8 @@
             android:text="@string/settingslib_learn_more_text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_gravity="start"
+            android:textAlignment="viewStart"
             android:paddingBottom="8dp"
             android:clickable="true"
             android:visibility="gone"
diff --git a/packages/SettingsLib/MainSwitchPreference/res/color-night-v34/settingslib_main_switch_text_color.xml b/packages/SettingsLib/MainSwitchPreference/res/color-night-v34/settingslib_main_switch_text_color.xml
new file mode 100644
index 0000000..a7ccfc2
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/color-night-v34/settingslib_main_switch_text_color.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2023 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false"
+          android:color="@android:color/system_accent1_100"
+          android:alpha="?android:attr/disabledAlpha" />
+    <item android:color="@android:color/system_accent1_100"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/MainSwitchPreference/res/color-v31/settingslib_main_switch_text_color.xml b/packages/SettingsLib/MainSwitchPreference/res/color-v31/settingslib_main_switch_text_color.xml
new file mode 100644
index 0000000..de367244
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/color-v31/settingslib_main_switch_text_color.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2023 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false"
+          android:color="@android:color/black"
+          android:alpha="?android:attr/disabledAlpha" />
+    <item android:color="@android:color/black"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/MainSwitchPreference/res/color-v34/settingslib_main_switch_text_color.xml b/packages/SettingsLib/MainSwitchPreference/res/color-v34/settingslib_main_switch_text_color.xml
new file mode 100644
index 0000000..e33905b
--- /dev/null
+++ b/packages/SettingsLib/MainSwitchPreference/res/color-v34/settingslib_main_switch_text_color.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2023 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false"
+          android:color="@android:color/system_accent1_900"
+          android:alpha="?android:attr/disabledAlpha" />
+    <item android:color="@android:color/system_accent1_900"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values-v31/styles.xml b/packages/SettingsLib/MainSwitchPreference/res/values-v31/styles.xml
index 1b80cc6..b8e43fc2 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values-v31/styles.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values-v31/styles.xml
@@ -20,6 +20,6 @@
     <style name="MainSwitchText.Settingslib" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title.Inverse">
         <item name="android:textSize">20sp</item>
         <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item>
-        <item name="android:textColor">@android:color/black</item>
+        <item name="android:textColor">@color/settingslib_main_switch_text_color</item>
     </style>
 </resources>
diff --git a/packages/SettingsLib/OWNERS b/packages/SettingsLib/OWNERS
index 81340f5..b2b7b61 100644
--- a/packages/SettingsLib/OWNERS
+++ b/packages/SettingsLib/OWNERS
@@ -1,4 +1,7 @@
 # People who can approve changes for submission
+cantol@google.com
+chiujason@google.com
+cipson@google.com
 dsandler@android.com
 edgarwang@google.com
 evanlaird@google.com
diff --git a/packages/SettingsLib/ProfileSelector/res/values-sl/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-sl/strings.xml
index 83ef291..d239f44 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-sl/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-sl/strings.xml
@@ -18,5 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Osebno"</string>
-    <string name="settingslib_category_work" msgid="4867750733682444676">"Služba"</string>
+    <string name="settingslib_category_work" msgid="4867750733682444676">"Delo"</string>
 </resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/color-night-v34/settingslib_switch_track_outline_color.xml b/packages/SettingsLib/SettingsTheme/res/color-night-v34/settingslib_switch_track_outline_color.xml
new file mode 100644
index 0000000..6fab831
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color-night-v34/settingslib_switch_track_outline_color.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2023 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- Disabled status of thumb -->
+    <item android:state_enabled="false"
+          android:color="@android:color/system_neutral2_400"
+          android:alpha="?android:attr/disabledAlpha" />
+    <!-- Toggle off status of thumb -->
+    <item android:state_checked="false"
+          android:color="@android:color/system_neutral2_400" />
+    <!-- Enabled or toggle on status of thumb -->
+    <item android:color="@color/settingslib_track_on_color" />
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_switch_thumb_color.xml b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_switch_thumb_color.xml
index 8ccbb06..a9c5c03 100644
--- a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_switch_thumb_color.xml
+++ b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_switch_thumb_color.xml
@@ -17,7 +17,8 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <!-- Disabled status of thumb -->
     <item android:state_enabled="false"
-          android:color="@color/settingslib_thumb_disabled_color" />
+          android:color="@color/settingslib_thumb_disabled_color"
+          android:alpha="?android:attr/disabledAlpha" />
     <!-- Toggle off status of thumb -->
     <item android:state_checked="false"
           android:color="@color/settingslib_thumb_off_color" />
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v34/settingslib_switch_thumb_color.xml b/packages/SettingsLib/SettingsTheme/res/color-v34/settingslib_switch_thumb_color.xml
new file mode 100644
index 0000000..2bc4ddf
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color-v34/settingslib_switch_thumb_color.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2023 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- Disabled status of thumb -->
+    <item android:state_enabled="false"
+          android:color="@color/settingslib_thumb_disabled_color"
+          android:alpha="?android:attr/disabledAlpha" />
+    <!-- Toggle off status of thumb -->
+    <item android:state_checked="false"
+          android:color="@color/settingslib_thumb_off_color" />
+    <!-- Enabled or toggle on status of thumb -->
+    <item android:color="@color/settingslib_thumb_on_color" />
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color-v34/settingslib_switch_track_outline_color.xml b/packages/SettingsLib/SettingsTheme/res/color-v34/settingslib_switch_track_outline_color.xml
new file mode 100644
index 0000000..8abc1fd
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color-v34/settingslib_switch_track_outline_color.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2023 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- Disabled status of thumb -->
+    <item android:state_enabled="false"
+          android:color="@android:color/system_neutral2_500"
+          android:alpha="?android:attr/disabledAlpha" />
+    <!-- Toggle off status of thumb -->
+    <item android:state_checked="false"
+          android:color="@android:color/system_neutral2_500" />
+    <!-- Enabled or toggle on status of thumb -->
+    <item android:color="@color/settingslib_track_on_color" />
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/drawable-v34/settingslib_switch_track.xml b/packages/SettingsLib/SettingsTheme/res/drawable-v34/settingslib_switch_track.xml
new file mode 100644
index 0000000..851e413
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/drawable-v34/settingslib_switch_track.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2023 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle"
+    android:width="52dp"
+    android:height="28dp">
+
+    <solid android:color="@color/settingslib_switch_track_color" />
+    <corners android:radius="35dp" />
+    <stroke android:width="2dp" android:color="@color/settingslib_track_online_color"/>
+</shape>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v31/settingslib_preference.xml b/packages/SettingsLib/SettingsTheme/res/layout-v31/settingslib_preference.xml
index 23aa993..dda7517c 100644
--- a/packages/SettingsLib/SettingsTheme/res/layout-v31/settingslib_preference.xml
+++ b/packages/SettingsLib/SettingsTheme/res/layout-v31/settingslib_preference.xml
@@ -42,6 +42,8 @@
             android:id="@android:id/title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_gravity="start"
+            android:textAlignment="viewStart"
             android:maxLines="2"
             android:textAppearance="?android:attr/textAppearanceListItem"
             android:ellipsize="marquee"/>
diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v33/settingslib_preference.xml b/packages/SettingsLib/SettingsTheme/res/layout-v33/settingslib_preference.xml
index 70ce374..fedcc77 100644
--- a/packages/SettingsLib/SettingsTheme/res/layout-v33/settingslib_preference.xml
+++ b/packages/SettingsLib/SettingsTheme/res/layout-v33/settingslib_preference.xml
@@ -42,6 +42,8 @@
             android:id="@android:id/title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_gravity="start"
+            android:textAlignment="viewStart"
             android:maxLines="2"
             android:hyphenationFrequency="normalFast"
             android:lineBreakWordStyle="phrase"
diff --git a/packages/SettingsLib/SettingsTheme/res/values-night-v34/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-night-v34/colors.xml
new file mode 100644
index 0000000..e3645b5
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-night-v34/colors.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2023 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<resources>
+    <!-- Material next state on color-->
+    <color name="settingslib_state_on_color">@android:color/system_accent1_700</color>
+
+    <!-- Material next state off color-->
+    <color name="settingslib_state_off_color">@android:color/system_accent1_700</color>
+
+    <!-- Material next thumb disable color-->
+    <color name="settingslib_thumb_disabled_color">@color/settingslib_thumb_off_color</color>
+
+    <!-- Material next thumb off color-->
+    <color name="settingslib_thumb_on_color">@android:color/system_accent1_800</color>
+
+    <!-- Material next thumb off color-->
+    <color name="settingslib_thumb_off_color">@android:color/system_neutral2_400</color>
+
+    <!-- Material next track on color-->
+    <color name="settingslib_track_on_color">@android:color/system_accent1_200</color>
+
+    <!-- Material next track off color-->
+    <color name="settingslib_track_off_color">@android:color/system_surface_container_highest_dark
+    </color>
+</resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v34/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-v34/colors.xml
new file mode 100644
index 0000000..fdd96ec
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-v34/colors.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2023 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<resources>
+    <!-- Material next state on color-->
+    <color name="settingslib_state_on_color">@android:color/system_accent1_100</color>
+
+    <!-- Material next state off color-->
+    <color name="settingslib_state_off_color">@android:color/system_accent1_100</color>
+
+    <!-- Material next thumb disable color-->
+    <color name="settingslib_thumb_disabled_color">@color/settingslib_thumb_off_color</color>
+
+    <!-- Material next thumb off color-->
+    <color name="settingslib_thumb_on_color">@android:color/system_accent1_0</color>
+
+    <!-- Material next thumb off color-->
+    <color name="settingslib_thumb_off_color">@android:color/system_neutral2_500</color>
+
+    <!-- Material next track on color-->
+    <color name="settingslib_track_on_color">@android:color/system_accent1_600</color>
+
+    <!-- Material next track off color-->
+    <color name="settingslib_track_off_color">@android:color/system_surface_container_highest_light</color>
+
+    <!-- Material next track outline color-->
+    <color name="settingslib_track_online_color">@color/settingslib_switch_track_outline_color</color>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SearchScaffold.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SearchScaffold.kt
index f6ca0c4..67c4cdc 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SearchScaffold.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SearchScaffold.kt
@@ -73,6 +73,7 @@
     actions: @Composable RowScope.() -> Unit = {},
     content: @Composable (bottomPadding: Dp, searchQuery: State<String>) -> Unit,
 ) {
+    ActivityTitle(title)
     var isSearchMode by rememberSaveable { mutableStateOf(false) }
     val viewModel: SearchScaffoldViewModel = viewModel()
 
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsPager.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsPager.kt
index c6e13a1..79635a0 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsPager.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsPager.kt
@@ -20,12 +20,20 @@
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.pager.HorizontalPager
+import androidx.compose.foundation.pager.PagerState
 import androidx.compose.foundation.pager.rememberPagerState
 import androidx.compose.material3.TabRow
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.SideEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalConfiguration
 import com.android.settingslib.spa.framework.theme.SettingsDimension
 import kotlin.math.absoluteValue
 import kotlinx.coroutines.launch
@@ -41,7 +49,7 @@
 
     Column {
         val coroutineScope = rememberCoroutineScope()
-        val pagerState = rememberPagerState()
+        val pagerState = rememberPageStateFixed()
 
         TabRow(
             selectedTabIndex = pagerState.currentPage,
@@ -69,3 +77,41 @@
         }
     }
 }
+
+/**
+ * Gets the state of [PagerState].
+ *
+ * This is a work around.
+ *
+ * TODO: Remove this and replace with rememberPageState() after the Compose Foundation 1.5.0-alpha04
+ *       updated in the platform.
+ */
+@Composable
+@OptIn(ExperimentalFoundationApi::class)
+private fun rememberPageStateFixed(): PagerState {
+    var currentPage by rememberSaveable { mutableStateOf(0) }
+    var targetPage by rememberSaveable { mutableStateOf(-1) }
+    val pagerState = rememberPagerState()
+    val configuration = LocalConfiguration.current
+    var lastScreenWidthDp by rememberSaveable { mutableStateOf(-1) }
+    val screenWidthDp = configuration.screenWidthDp
+    LaunchedEffect(screenWidthDp) {
+        // Reset pager state to fix an issue after configuration change.
+        // When we declare android:configChanges in the manifest, the pager state is in a weird
+        // state after configuration change.
+        targetPage = currentPage
+        lastScreenWidthDp = screenWidthDp
+    }
+    LaunchedEffect(targetPage) {
+        if (targetPage != -1) {
+            pagerState.scrollToPage(targetPage)
+            targetPage = -1
+        }
+    }
+    SideEffect {
+        if (lastScreenWidthDp == screenWidthDp) {
+            currentPage = pagerState.currentPage
+        }
+    }
+    return pagerState
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffold.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffold.kt
index f4e504a..8919402 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffold.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffold.kt
@@ -16,6 +16,9 @@
 
 package com.android.settingslib.spa.widget.scaffold
 
+import android.app.Activity
+import android.content.Context
+import android.content.ContextWrapper
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.PaddingValues
@@ -25,8 +28,10 @@
 import androidx.compose.material3.Scaffold
 import androidx.compose.material3.TopAppBarDefaults
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.input.nestedscroll.nestedScroll
+import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.compose.horizontalValues
 import com.android.settingslib.spa.framework.compose.verticalValues
@@ -44,6 +49,7 @@
     actions: @Composable RowScope.() -> Unit = {},
     content: @Composable (PaddingValues) -> Unit,
 ) {
+    ActivityTitle(title)
     val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
     Scaffold(
         modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
@@ -55,6 +61,25 @@
     }
 }
 
+/**
+ * Sets a title for the activity.
+ *
+ * So the TalkBack can read out the correct page title.
+ */
+@Composable
+internal fun ActivityTitle(title: String) {
+    val context = LocalContext.current
+    LaunchedEffect(true) {
+        context.getActivity()?.title = title
+    }
+}
+
+private fun Context.getActivity(): Activity? = when (this) {
+    is Activity -> this
+    is ContextWrapper -> baseContext.getActivity()
+    else -> null
+}
+
 @Preview
 @Composable
 private fun SettingsScaffoldPreview() {
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffoldTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffoldTest.kt
index f042404..872d957 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffoldTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffoldTest.kt
@@ -16,9 +16,12 @@
 
 package com.android.settingslib.spa.widget.scaffold
 
+import android.app.Activity
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.material3.Text
+import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.SideEffect
+import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.test.assertIsDisplayed
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithText
@@ -29,12 +32,22 @@
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
 
 @RunWith(AndroidJUnit4::class)
 class SettingsScaffoldTest {
     @get:Rule
     val composeTestRule = createComposeRule()
 
+    @get:Rule
+    val mockito: MockitoRule = MockitoJUnit.rule()
+
+    @Mock
+    private lateinit var activity: Activity
+
     @Test
     fun settingsScaffold_titleIsDisplayed() {
         composeTestRule.setContent {
@@ -78,7 +91,18 @@
         assertThat(actualPaddingValues.calculateRightPadding(LayoutDirection.Rtl)).isEqualTo(0.dp)
     }
 
+    @Test
+    fun activityTitle() {
+        composeTestRule.setContent {
+            CompositionLocalProvider(LocalContext provides activity) {
+                ActivityTitle(title = TITLE)
+            }
+        }
+
+        verify(activity).title = TITLE
+    }
+
     private companion object {
-        const val TITLE = "title"
+        const val TITLE = "Title"
     }
 }
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt
index e3ea2e7..a0ff216 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppInfo.kt
@@ -76,7 +76,7 @@
     private fun AppVersion() {
         if (packageInfo.versionName == null) return
         Spacer(modifier = Modifier.height(4.dp))
-        SettingsBody(packageInfo.versionName)
+        SettingsBody(packageInfo.versionNameBidiWrapped)
     }
 
     @Composable
@@ -84,10 +84,15 @@
         if (packageInfo.versionName == null) return
         Divider()
         Box(modifier = Modifier.padding(SettingsDimension.itemPadding)) {
-            val versionName = BidiFormatter.getInstance().unicodeWrap(packageInfo.versionName)
-            SettingsBody(stringResource(R.string.version_text, versionName))
+            SettingsBody(stringResource(R.string.version_text, packageInfo.versionNameBidiWrapped))
         }
     }
+
+    private companion object {
+        /** Wrapped the version name, so its directionality still keep same when RTL. */
+        val PackageInfo.versionNameBidiWrapped: String
+            get() = BidiFormatter.getInstance().unicodeWrap(versionName)
+    }
 }
 
 @Composable
diff --git a/packages/SettingsLib/TopIntroPreference/res/layout-v33/top_intro_preference.xml b/packages/SettingsLib/TopIntroPreference/res/layout-v33/top_intro_preference.xml
index 6046d91..195d45f 100644
--- a/packages/SettingsLib/TopIntroPreference/res/layout-v33/top_intro_preference.xml
+++ b/packages/SettingsLib/TopIntroPreference/res/layout-v33/top_intro_preference.xml
@@ -30,6 +30,8 @@
         android:id="@android:id/title"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_gravity="start"
+        android:textAlignment="viewStart"
         android:clickable="false"
         android:longClickable="false"
         android:maxLines="10"
diff --git a/packages/SettingsLib/TopIntroPreference/res/layout/top_intro_preference.xml b/packages/SettingsLib/TopIntroPreference/res/layout/top_intro_preference.xml
index 4d6e1b7..bee6bc7 100644
--- a/packages/SettingsLib/TopIntroPreference/res/layout/top_intro_preference.xml
+++ b/packages/SettingsLib/TopIntroPreference/res/layout/top_intro_preference.xml
@@ -30,6 +30,8 @@
         android:id="@android:id/title"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_gravity="start"
+        android:textAlignment="viewStart"
         android:clickable="false"
         android:longClickable="false"
         android:maxLines="10"
diff --git a/packages/SettingsLib/Utils/res/values-af/strings.xml b/packages/SettingsLib/Utils/res/values-af/strings.xml
new file mode 100644
index 0000000..d3ebc1f
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-af/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Werk-<xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-am/strings.xml b/packages/SettingsLib/Utils/res/values-am/strings.xml
new file mode 100644
index 0000000..caf393c
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-am/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"የሥራ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ar/strings.xml b/packages/SettingsLib/Utils/res/values-ar/strings.xml
new file mode 100644
index 0000000..e18fe63
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ar/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"\"<xliff:g id="APP_NAME">%s</xliff:g>\" المخصّص للعمل"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-as/strings.xml b/packages/SettingsLib/Utils/res/values-as/strings.xml
new file mode 100644
index 0000000..4463586
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-as/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"কৰ্মস্থান <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-az/strings.xml b/packages/SettingsLib/Utils/res/values-az/strings.xml
new file mode 100644
index 0000000..f0f4b0e
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-az/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> iş tətbiqi"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/Utils/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..1edde54
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Poslovna aplikacija <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-be/strings.xml b/packages/SettingsLib/Utils/res/values-be/strings.xml
new file mode 100644
index 0000000..bdd1c30
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-be/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> (праца)"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-bg/strings.xml b/packages/SettingsLib/Utils/res/values-bg/strings.xml
new file mode 100644
index 0000000..c9b8768
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-bg/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> за работа"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-bn/strings.xml b/packages/SettingsLib/Utils/res/values-bn/strings.xml
new file mode 100644
index 0000000..f7c9a07
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-bn/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"অফিসের <xliff:g id="APP_NAME">%s</xliff:g> অ্যাপ"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-bs/strings.xml b/packages/SettingsLib/Utils/res/values-bs/strings.xml
new file mode 100644
index 0000000..1edde54
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-bs/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Poslovna aplikacija <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ca/strings.xml b/packages/SettingsLib/Utils/res/values-ca/strings.xml
new file mode 100644
index 0000000..11d8d5c
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ca/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> de la feina"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-cs/strings.xml b/packages/SettingsLib/Utils/res/values-cs/strings.xml
new file mode 100644
index 0000000..c9fc770
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-cs/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Pracovní aplikace <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-da/strings.xml b/packages/SettingsLib/Utils/res/values-da/strings.xml
new file mode 100644
index 0000000..6ca1760
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-da/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> – arbejde"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-de/strings.xml b/packages/SettingsLib/Utils/res/values-de/strings.xml
new file mode 100644
index 0000000..f263826
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-de/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> (geschäftlich)"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-el/strings.xml b/packages/SettingsLib/Utils/res/values-el/strings.xml
new file mode 100644
index 0000000..aa838cf
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-el/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Εφαρμογή <xliff:g id="APP_NAME">%s</xliff:g> εργασίας"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-en-rAU/strings.xml b/packages/SettingsLib/Utils/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..6b770ea
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-en-rAU/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-en-rCA/strings.xml b/packages/SettingsLib/Utils/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..6b770ea
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-en-rCA/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-en-rGB/strings.xml b/packages/SettingsLib/Utils/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..6b770ea
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-en-rGB/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-en-rIN/strings.xml b/packages/SettingsLib/Utils/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..6b770ea
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-en-rIN/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-en-rXC/strings.xml b/packages/SettingsLib/Utils/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..3abbbef
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-en-rXC/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎‎‏‎‏‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎Work ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-es-rUS/strings.xml b/packages/SettingsLib/Utils/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..4c20d68
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-es-rUS/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> de trabajo"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-es/strings.xml b/packages/SettingsLib/Utils/res/values-es/strings.xml
new file mode 100644
index 0000000..4c20d68
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-es/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> de trabajo"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-et/strings.xml b/packages/SettingsLib/Utils/res/values-et/strings.xml
new file mode 100644
index 0000000..0953870
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-et/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Töö: <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-eu/strings.xml b/packages/SettingsLib/Utils/res/values-eu/strings.xml
new file mode 100644
index 0000000..4743913
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-eu/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Laneko <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-fa/strings.xml b/packages/SettingsLib/Utils/res/values-fa/strings.xml
new file mode 100644
index 0000000..910e4f9
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-fa/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> کاری"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-fi/strings.xml b/packages/SettingsLib/Utils/res/values-fi/strings.xml
new file mode 100644
index 0000000..81b8b9a
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-fi/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> (työ)"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-fr-rCA/strings.xml b/packages/SettingsLib/Utils/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..57405f4
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-fr-rCA/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> dans le profil professionnel"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-fr/strings.xml b/packages/SettingsLib/Utils/res/values-fr/strings.xml
new file mode 100644
index 0000000..9f255ef
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-fr/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> (pro)"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-gl/strings.xml b/packages/SettingsLib/Utils/res/values-gl/strings.xml
new file mode 100644
index 0000000..32d764e
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-gl/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Aplicación <xliff:g id="APP_NAME">%s</xliff:g> do traballo"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-gu/strings.xml b/packages/SettingsLib/Utils/res/values-gu/strings.xml
new file mode 100644
index 0000000..4f25384
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-gu/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"ઑફિસ માટે <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-hi/strings.xml b/packages/SettingsLib/Utils/res/values-hi/strings.xml
new file mode 100644
index 0000000..e2e2fbf
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-hi/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"वर्क प्रोफ़ाइल वाला <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-hr/strings.xml b/packages/SettingsLib/Utils/res/values-hr/strings.xml
new file mode 100644
index 0000000..1edde54
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-hr/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Poslovna aplikacija <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-hu/strings.xml b/packages/SettingsLib/Utils/res/values-hu/strings.xml
new file mode 100644
index 0000000..72ea4ea
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-hu/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Munkahelyi <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-hy/strings.xml b/packages/SettingsLib/Utils/res/values-hy/strings.xml
new file mode 100644
index 0000000..40f6f62
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-hy/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Աշխատանքային <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-in/strings.xml b/packages/SettingsLib/Utils/res/values-in/strings.xml
new file mode 100644
index 0000000..d2dff14
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-in/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> kerja"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-is/strings.xml b/packages/SettingsLib/Utils/res/values-is/strings.xml
new file mode 100644
index 0000000..e8a3bb6
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-is/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> fyrir vinnu"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-it/strings.xml b/packages/SettingsLib/Utils/res/values-it/strings.xml
new file mode 100644
index 0000000..e7f2599
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-it/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"App <xliff:g id="APP_NAME">%s</xliff:g> di lavoro"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-iw/strings.xml b/packages/SettingsLib/Utils/res/values-iw/strings.xml
new file mode 100644
index 0000000..efbd6f1
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-iw/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> לעבודה"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ja/strings.xml b/packages/SettingsLib/Utils/res/values-ja/strings.xml
new file mode 100644
index 0000000..d27d062
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ja/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"仕事用の<xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ka/strings.xml b/packages/SettingsLib/Utils/res/values-ka/strings.xml
new file mode 100644
index 0000000..8cf1762
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ka/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"სამსახურის <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-kk/strings.xml b/packages/SettingsLib/Utils/res/values-kk/strings.xml
new file mode 100644
index 0000000..1ac0004
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-kk/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Жұмысқа арналған <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-km/strings.xml b/packages/SettingsLib/Utils/res/values-km/strings.xml
new file mode 100644
index 0000000..1c6198f
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-km/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> សម្រាប់ការងារ"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-kn/strings.xml b/packages/SettingsLib/Utils/res/values-kn/strings.xml
new file mode 100644
index 0000000..97bd006
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-kn/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"ಕೆಲಸ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ko/strings.xml b/packages/SettingsLib/Utils/res/values-ko/strings.xml
new file mode 100644
index 0000000..8b8da0f
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ko/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"직장용 <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ky/strings.xml b/packages/SettingsLib/Utils/res/values-ky/strings.xml
new file mode 100644
index 0000000..1b7a50e
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ky/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Жумуш <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-lo/strings.xml b/packages/SettingsLib/Utils/res/values-lo/strings.xml
new file mode 100644
index 0000000..533763c
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-lo/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> ບ່ອນເຮັດວຽກ"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-lt/strings.xml b/packages/SettingsLib/Utils/res/values-lt/strings.xml
new file mode 100644
index 0000000..cfe6436
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-lt/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Darbo „<xliff:g id="APP_NAME">%s</xliff:g>“"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-lv/strings.xml b/packages/SettingsLib/Utils/res/values-lv/strings.xml
new file mode 100644
index 0000000..3026f06
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-lv/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Darba lietotne <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-mk/strings.xml b/packages/SettingsLib/Utils/res/values-mk/strings.xml
new file mode 100644
index 0000000..7844e3be
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-mk/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Работна <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ml/strings.xml b/packages/SettingsLib/Utils/res/values-ml/strings.xml
new file mode 100644
index 0000000..59e5248
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ml/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"ഔദ്യോഗിക <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-mn/strings.xml b/packages/SettingsLib/Utils/res/values-mn/strings.xml
new file mode 100644
index 0000000..4fae367
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-mn/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Ажлын <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-mr/strings.xml b/packages/SettingsLib/Utils/res/values-mr/strings.xml
new file mode 100644
index 0000000..6b770ea
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-mr/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ms/strings.xml b/packages/SettingsLib/Utils/res/values-ms/strings.xml
new file mode 100644
index 0000000..017c4e1
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ms/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Kerja <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-my/strings.xml b/packages/SettingsLib/Utils/res/values-my/strings.xml
new file mode 100644
index 0000000..9533ae0
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-my/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"အလုပ်သုံး <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-nb/strings.xml b/packages/SettingsLib/Utils/res/values-nb/strings.xml
new file mode 100644
index 0000000..a513b45
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-nb/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> for jobb"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ne/strings.xml b/packages/SettingsLib/Utils/res/values-ne/strings.xml
new file mode 100644
index 0000000..54a8d69
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ne/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"कार्यालयको प्रोफाइल <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-nl/strings.xml b/packages/SettingsLib/Utils/res/values-nl/strings.xml
new file mode 100644
index 0000000..4112f0a
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-nl/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> voor werk"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-or/strings.xml b/packages/SettingsLib/Utils/res/values-or/strings.xml
new file mode 100644
index 0000000..f0d3b18
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-or/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"ୱାର୍କ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-pa/strings.xml b/packages/SettingsLib/Utils/res/values-pa/strings.xml
new file mode 100644
index 0000000..79151b2
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-pa/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"ਕੰਮ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-pl/strings.xml b/packages/SettingsLib/Utils/res/values-pl/strings.xml
new file mode 100644
index 0000000..190f6d1
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-pl/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> (aplikacja służbowa)"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-pt-rBR/strings.xml b/packages/SettingsLib/Utils/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..77ca1d1
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-pt-rBR/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"App <xliff:g id="APP_NAME">%s</xliff:g> de trabalho"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-pt-rPT/strings.xml b/packages/SettingsLib/Utils/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..e9e945b
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-pt-rPT/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> de trabalho"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-pt/strings.xml b/packages/SettingsLib/Utils/res/values-pt/strings.xml
new file mode 100644
index 0000000..77ca1d1
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-pt/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"App <xliff:g id="APP_NAME">%s</xliff:g> de trabalho"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ro/strings.xml b/packages/SettingsLib/Utils/res/values-ro/strings.xml
new file mode 100644
index 0000000..0ba1619
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ro/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> pentru lucru"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ru/strings.xml b/packages/SettingsLib/Utils/res/values-ru/strings.xml
new file mode 100644
index 0000000..d1a663f
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ru/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Рабочее приложение \"<xliff:g id="APP_NAME">%s</xliff:g>\""</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-si/strings.xml b/packages/SettingsLib/Utils/res/values-si/strings.xml
new file mode 100644
index 0000000..90a2219
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-si/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"කාර්යාල <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-sk/strings.xml b/packages/SettingsLib/Utils/res/values-sk/strings.xml
new file mode 100644
index 0000000..0066a05
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-sk/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Pracovná aplikácia <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-sl/strings.xml b/packages/SettingsLib/Utils/res/values-sl/strings.xml
new file mode 100644
index 0000000..ee567e1
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-sl/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Delovna aplikacija <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-sq/strings.xml b/packages/SettingsLib/Utils/res/values-sq/strings.xml
new file mode 100644
index 0000000..3ec7f61
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-sq/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> për punën"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-sr/strings.xml b/packages/SettingsLib/Utils/res/values-sr/strings.xml
new file mode 100644
index 0000000..ee4f289
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-sr/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Пословна апликација <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-sv/strings.xml b/packages/SettingsLib/Utils/res/values-sv/strings.xml
new file mode 100644
index 0000000..01ba419
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-sv/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> för arbetet"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-sw/strings.xml b/packages/SettingsLib/Utils/res/values-sw/strings.xml
new file mode 100644
index 0000000..0594a04
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-sw/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Ya kazini <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ta/strings.xml b/packages/SettingsLib/Utils/res/values-ta/strings.xml
new file mode 100644
index 0000000..b519e62
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ta/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"பணி <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-te/strings.xml b/packages/SettingsLib/Utils/res/values-te/strings.xml
new file mode 100644
index 0000000..e5bc92e
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-te/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"ఆఫీస్ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-th/strings.xml b/packages/SettingsLib/Utils/res/values-th/strings.xml
new file mode 100644
index 0000000..e1bc91c
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-th/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> ในโปรไฟล์งาน"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-tl/strings.xml b/packages/SettingsLib/Utils/res/values-tl/strings.xml
new file mode 100644
index 0000000..488a603
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-tl/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> para sa trabaho"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-tr/strings.xml b/packages/SettingsLib/Utils/res/values-tr/strings.xml
new file mode 100644
index 0000000..106608a
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-tr/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> (İş)"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-uk/strings.xml b/packages/SettingsLib/Utils/res/values-uk/strings.xml
new file mode 100644
index 0000000..53ec5ae
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-uk/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Робочий додаток <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-ur/strings.xml b/packages/SettingsLib/Utils/res/values-ur/strings.xml
new file mode 100644
index 0000000..301e92c
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-ur/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"ورک <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-uz/strings.xml b/packages/SettingsLib/Utils/res/values-uz/strings.xml
new file mode 100644
index 0000000..a5079cc
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-uz/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Ishga oid <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-vi/strings.xml b/packages/SettingsLib/Utils/res/values-vi/strings.xml
new file mode 100644
index 0000000..5bcdb07
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-vi/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"<xliff:g id="APP_NAME">%s</xliff:g> dành cho công việc"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-zh-rCN/strings.xml b/packages/SettingsLib/Utils/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..c0b4564
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-zh-rCN/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"工作<xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-zh-rHK/strings.xml b/packages/SettingsLib/Utils/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..07d5c8f
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-zh-rHK/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"工作設定檔入面嘅「<xliff:g id="APP_NAME">%s</xliff:g>」"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-zh-rTW/strings.xml b/packages/SettingsLib/Utils/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..ff2f6aa
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-zh-rTW/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"工作資料夾中的「<xliff:g id="APP_NAME">%s</xliff:g>」"</string>
+</resources>
diff --git a/packages/SettingsLib/Utils/res/values-zu/strings.xml b/packages/SettingsLib/Utils/res/values-zu/strings.xml
new file mode 100644
index 0000000..17b38c7
--- /dev/null
+++ b/packages/SettingsLib/Utils/res/values-zu/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="accessibility_work_profile_app_description" msgid="7426881474681968795">"Umsebenzi we-<xliff:g id="APP_NAME">%s</xliff:g>"</string>
+</resources>
diff --git a/packages/SettingsLib/res/drawable/ic_media_car.xml b/packages/SettingsLib/res/drawable/ic_media_car.xml
new file mode 100644
index 0000000..452e7bb
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_media_car.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2020 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M240,760L240,800Q240,817 228.5,828.5Q217,840 200,840L160,840Q143,840 131.5,828.5Q120,817 120,800L120,480L204,240Q210,222 225.5,211Q241,200 260,200L700,200Q719,200 734.5,211Q750,222 756,240L840,480L840,800Q840,817 828.5,828.5Q817,840 800,840L760,840Q743,840 731.5,828.5Q720,817 720,800L720,760L240,760ZM232,400L728,400L686,280L274,280L232,400ZM200,480L200,480L200,680L200,680L200,480ZM300,640Q325,640 342.5,622.5Q360,605 360,580Q360,555 342.5,537.5Q325,520 300,520Q275,520 257.5,537.5Q240,555 240,580Q240,605 257.5,622.5Q275,640 300,640ZM660,640Q685,640 702.5,622.5Q720,605 720,580Q720,555 702.5,537.5Q685,520 660,520Q635,520 617.5,537.5Q600,555 600,580Q600,605 617.5,622.5Q635,640 660,640ZM200,680L760,680L760,480L200,480L200,680Z"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_media_computer.xml b/packages/SettingsLib/res/drawable/ic_media_computer.xml
new file mode 100644
index 0000000..2aa6f8e
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_media_computer.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2020 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M80,840Q63,840 51.5,828.5Q40,817 40,800Q40,783 51.5,771.5Q63,760 80,760L880,760Q897,760 908.5,771.5Q920,783 920,800Q920,817 908.5,828.5Q897,840 880,840L80,840ZM160,720Q127,720 103.5,696.5Q80,673 80,640L80,200Q80,167 103.5,143.5Q127,120 160,120L800,120Q833,120 856.5,143.5Q880,167 880,200L880,640Q880,673 856.5,696.5Q833,720 800,720L160,720ZM160,640L800,640Q800,640 800,640Q800,640 800,640L800,200Q800,200 800,200Q800,200 800,200L160,200Q160,200 160,200Q160,200 160,200L160,640Q160,640 160,640Q160,640 160,640ZM160,640Q160,640 160,640Q160,640 160,640L160,200Q160,200 160,200Q160,200 160,200L160,200Q160,200 160,200Q160,200 160,200L160,640Q160,640 160,640Q160,640 160,640L160,640Z"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_media_game_console.xml b/packages/SettingsLib/res/drawable/ic_media_game_console.xml
new file mode 100644
index 0000000..8e422ac
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_media_game_console.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2020 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M189,800Q129,800 86.5,757Q44,714 42,653Q42,644 43,635Q44,626 46,617L130,281Q144,227 187,193.5Q230,160 285,160L675,160Q730,160 773,193.5Q816,227 830,281L914,617Q916,626 917.5,635.5Q919,645 919,654Q919,715 875.5,757.5Q832,800 771,800Q729,800 693,778Q657,756 639,718L611,660Q606,650 596,645Q586,640 575,640L385,640Q374,640 364,645Q354,650 349,660L321,718Q303,756 267,778Q231,800 189,800ZM192,720Q211,720 226.5,710Q242,700 250,683L278,626Q293,595 322,577.5Q351,560 385,560L575,560Q609,560 638,578Q667,596 683,626L711,683Q719,700 734.5,710Q750,720 769,720Q797,720 817,701.5Q837,683 838,655Q838,656 836,636L752,301Q745,274 724,257Q703,240 675,240L285,240Q257,240 235.5,257Q214,274 208,301L124,636Q122,642 122,654Q122,682 142.5,701Q163,720 192,720ZM540,440Q557,440 568.5,428.5Q580,417 580,400Q580,383 568.5,371.5Q557,360 540,360Q523,360 511.5,371.5Q500,383 500,400Q500,417 511.5,428.5Q523,440 540,440ZM620,360Q637,360 648.5,348.5Q660,337 660,320Q660,303 648.5,291.5Q637,280 620,280Q603,280 591.5,291.5Q580,303 580,320Q580,337 591.5,348.5Q603,360 620,360ZM620,520Q637,520 648.5,508.5Q660,497 660,480Q660,463 648.5,451.5Q637,440 620,440Q603,440 591.5,451.5Q580,463 580,480Q580,497 591.5,508.5Q603,520 620,520ZM700,440Q717,440 728.5,428.5Q740,417 740,400Q740,383 728.5,371.5Q717,360 700,360Q683,360 671.5,371.5Q660,383 660,400Q660,417 671.5,428.5Q683,440 700,440ZM340,500Q353,500 361.5,491.5Q370,483 370,470L370,430L410,430Q423,430 431.5,421.5Q440,413 440,400Q440,387 431.5,378.5Q423,370 410,370L370,370L370,330Q370,317 361.5,308.5Q353,300 340,300Q327,300 318.5,308.5Q310,317 310,330L310,370L270,370Q257,370 248.5,378.5Q240,387 240,400Q240,413 248.5,421.5Q257,430 270,430L310,430L310,470Q310,483 318.5,491.5Q327,500 340,500ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480Z"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_media_smartwatch.xml b/packages/SettingsLib/res/drawable/ic_media_smartwatch.xml
new file mode 100644
index 0000000..9c73485
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_media_smartwatch.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2020 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M16,0L8,0l-0.95,5.73C5.19,7.19 4,9.45 4,12s1.19,4.81 3.05,6.27L8,24h8l0.96,-5.73C18.81,16.81 20,14.54 20,12s-1.19,-4.81 -3.04,-6.27L16,0zM12,18c-3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6 6,2.69 6,6 -2.69,6 -6,6z"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_media_tablet.xml b/packages/SettingsLib/res/drawable/ic_media_tablet.xml
new file mode 100644
index 0000000..c773b96
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_media_tablet.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2020 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M200,920Q167,920 143.5,896.5Q120,873 120,840L120,120Q120,87 143.5,63.5Q167,40 200,40L760,40Q793,40 816.5,63.5Q840,87 840,120L840,840Q840,873 816.5,896.5Q793,920 760,920L200,920ZM200,720L200,840Q200,840 200,840Q200,840 200,840L760,840Q760,840 760,840Q760,840 760,840L760,720L200,720ZM400,800L560,800L560,760L400,760L400,800ZM200,640L760,640L760,240L200,240L200,640ZM200,160L760,160L760,120Q760,120 760,120Q760,120 760,120L200,120Q200,120 200,120Q200,120 200,120L200,160ZM200,160L200,120Q200,120 200,120Q200,120 200,120L200,120Q200,120 200,120Q200,120 200,120L200,160L200,160ZM200,720L200,720L200,840Q200,840 200,840Q200,840 200,840L200,840Q200,840 200,840Q200,840 200,840L200,720Z"/>
+</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_person_add.xml b/packages/SettingsLib/res/drawable/ic_person_add.xml
new file mode 100644
index 0000000..d138c69
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_person_add.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24"
+        android:tint="?android:attr/colorControlNormal">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M18,14V11H15V9H18V6H20V9H23V11H20V14ZM9,12Q7.35,12 6.175,10.825Q5,9.65 5,8Q5,6.35 6.175,5.175Q7.35,4 9,4Q10.65,4 11.825,5.175Q13,6.35 13,8Q13,9.65 11.825,10.825Q10.65,12 9,12ZM1,20V17.2Q1,16.35 1.438,15.637Q1.875,14.925 2.6,14.55Q4.15,13.775 5.75,13.387Q7.35,13 9,13Q10.65,13 12.25,13.387Q13.85,13.775 15.4,14.55Q16.125,14.925 16.562,15.637Q17,16.35 17,17.2V20ZM3,18H15V17.2Q15,16.925 14.863,16.7Q14.725,16.475 14.5,16.35Q13.15,15.675 11.775,15.337Q10.4,15 9,15Q7.6,15 6.225,15.337Q4.85,15.675 3.5,16.35Q3.275,16.475 3.138,16.7Q3,16.925 3,17.2ZM9,10Q9.825,10 10.413,9.412Q11,8.825 11,8Q11,7.175 10.413,6.588Q9.825,6 9,6Q8.175,6 7.588,6.588Q7,7.175 7,8Q7,8.825 7.588,9.412Q8.175,10 9,10ZM9,8Q9,8 9,8Q9,8 9,8Q9,8 9,8Q9,8 9,8Q9,8 9,8Q9,8 9,8Q9,8 9,8Q9,8 9,8ZM9,18Q9,18 9,18Q9,18 9,18Q9,18 9,18Q9,18 9,18Q9,18 9,18Q9,18 9,18Q9,18 9,18Q9,18 9,18Z"/>
+</vector>
diff --git a/packages/SettingsLib/res/layout/dialog_with_icon.xml b/packages/SettingsLib/res/layout/dialog_with_icon.xml
index 9081ca5..54f8096 100644
--- a/packages/SettingsLib/res/layout/dialog_with_icon.xml
+++ b/packages/SettingsLib/res/layout/dialog_with_icon.xml
@@ -13,87 +13,88 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:orientation="vertical"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:gravity="center"
-              android:padding="@dimen/grant_admin_dialog_padding"
-              android:paddingBottom="0dp">
-    <ImageView
-        android:id="@+id/dialog_with_icon_icon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:contentDescription=""/>
-    <TextView
-        android:id="@+id/dialog_with_icon_title"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        style="@style/DialogWithIconTitle"
-        android:text="@string/user_grant_admin_title"
-        android:textDirection="locale"/>
-    <TextView
-        android:id="@+id/dialog_with_icon_message"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:padding="10dp"
-        android:gravity="center"
-        style="@style/TextAppearanceSmall"
-        android:text=""
-        android:textDirection="locale"/>
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/new_user_dialog_id">
+
     <LinearLayout
-        android:id="@+id/custom_layout"
         android:orientation="vertical"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:paddingBottom="0dp">
-    </LinearLayout>
-    <LinearLayout
-        android:id="@+id/button_panel"
-        android:orientation="horizontal"
-        android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:gravity="center"
-        android:paddingBottom="0dp">
-        <Button
-            android:id="@+id/button_cancel"
-            style="@style/DialogButtonNegative"
-            android:layout_width="wrap_content"
-            android:buttonCornerRadius="28dp"
-            android:layout_height="wrap_content"
-            android:visibility="gone"/>
-        <Space
-            android:layout_width="0dp"
-            android:layout_height="1dp"
-            android:layout_weight="1" >
-        </Space>
-        <Button
-            android:id="@+id/button_back"
+        android:padding="@dimen/dialog_content_padding">
+        <ImageView
+            android:id="@+id/dialog_with_icon_icon"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            style="@style/DialogButtonNegative"
-            android:buttonCornerRadius="40dp"
-            android:clickable="true"
-            android:focusable="true"
-            android:text="Back"
-            android:visibility="gone"
-        />
-        <Space
-            android:layout_width="0dp"
-            android:layout_height="1dp"
-            android:layout_weight="0.05"
-        >
-        </Space>
-        <Button
-            android:id="@+id/button_ok"
+            android:importantForAccessibility="no"/>
+        <TextView
+            android:id="@+id/dialog_with_icon_title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            style="@style/DialogButtonPositive"
-            android:clickable="true"
-            android:focusable="true"
-            android:visibility="gone"
-        />
+            android:gravity="center"
+            style="@style/DialogWithIconTitle"/>
+        <TextView
+            android:id="@+id/dialog_with_icon_message"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:padding="10dp"
+            android:gravity="center"
+            style="@style/TextAppearanceSmall"/>
+
+        <LinearLayout
+            android:id="@+id/custom_layout"
+            android:orientation="vertical"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center">
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/button_panel"
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center">
+
+            <Button
+                android:id="@+id/button_cancel"
+                style="@style/DialogButtonNegative"
+                android:layout_width="wrap_content"
+                android:buttonCornerRadius="28dp"
+                android:layout_height="wrap_content"
+                android:visibility="gone"/>
+
+            <Space
+                android:layout_width="0dp"
+                android:layout_height="1dp"
+                android:layout_weight="1">
+            </Space>
+
+            <Button
+                android:id="@+id/button_back"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                style="@style/DialogButtonNegative"
+                android:buttonCornerRadius="40dp"
+                android:visibility="gone"/>
+
+            <Space
+                android:layout_width="0dp"
+                android:layout_height="1dp"
+                android:layout_weight="0.05">
+            </Space>
+
+            <Button
+                android:id="@+id/button_ok"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                style="@style/DialogButtonPositive"
+                android:visibility="gone"
+            />
+        </LinearLayout>
     </LinearLayout>
-</LinearLayout>
+</ScrollView>
diff --git a/packages/SettingsLib/res/layout/edit_user_info_dialog_content.xml b/packages/SettingsLib/res/layout/edit_user_info_dialog_content.xml
index 33c2e4855..4ffaf1b 100644
--- a/packages/SettingsLib/res/layout/edit_user_info_dialog_content.xml
+++ b/packages/SettingsLib/res/layout/edit_user_info_dialog_content.xml
@@ -28,7 +28,8 @@
         android:orientation="vertical">
         <TextView
             android:id="@+id/user_info_title"
-            android:layout_width="wrap_content"
+            android:gravity="center"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
             style="@style/EditUserDialogTitle"
             android:text="@string/user_info_settings_title"
diff --git a/packages/SettingsLib/res/layout/grant_admin_dialog_content.xml b/packages/SettingsLib/res/layout/grant_admin_dialog_content.xml
index d6acac2..26d8245 100644
--- a/packages/SettingsLib/res/layout/grant_admin_dialog_content.xml
+++ b/packages/SettingsLib/res/layout/grant_admin_dialog_content.xml
@@ -14,10 +14,14 @@
   ~ limitations under the License.
   -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/grant_admin_view"
               android:orientation="vertical"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
-              android:padding="@dimen/grant_admin_dialog_padding">
+              android:paddingLeft="@dimen/dialog_content_padding"
+              android:paddingBottom="@dimen/dialog_content_padding"
+              android:paddingRight="@dimen/dialog_content_padding">
+
     <RadioGroup
         android:id="@+id/choose_admin"
         android:layout_width="match_parent"
@@ -25,13 +29,19 @@
         android:orientation="vertical">
         <RadioButton
             android:id="@+id/grant_admin_yes"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:paddingTop="@dimen/radio_button_padding"
+            android:paddingBottom="@dimen/radio_button_padding"
+            android:paddingStart="@dimen/radio_button_padding_start"
             android:text="@string/grant_admin"/>
         <RadioButton
             android:id="@+id/grant_admin_no"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:paddingTop="@dimen/radio_button_padding"
+            android:paddingBottom="@dimen/radio_button_padding"
+            android:paddingStart="@dimen/radio_button_padding_start"
             android:text="@string/not_grant_admin"/>
     </RadioGroup>
 </LinearLayout>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index ecbda9f..0e6f207 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-oudio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD oudio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Gehoortoestelle"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE-oudio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Gekoppel aan gehoortoestelle"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Gekoppel aan LE-oudio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Gekoppel aan media-oudio"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Kies profiel"</string>
     <string name="category_personal" msgid="6236798763159385225">"Persoonlik"</string>
     <string name="category_work" msgid="4014193632325996115">"Werk"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Kloon"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Ontwikkelaaropsies"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Aktiveer ontwikkelaaropsies"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Stel opsies vir programontwikkeling"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 06ae97c..a453594 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"ኤችዲ ኦዲዮ፦ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"ኤችዲ ኦዲዮ"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"አጋዥ መስሚያዎች"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ኦዲዮ"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ከአጋዥ መስሚያዎች ጋር ተገናኝቷል"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"ከLE ኦዲዮ ጋር ተገናኝቷል"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"ወደ ማህደረ  መረጃ  አውዲዮ ተያይዟል"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"መገለጫ ይምረጡ"</string>
     <string name="category_personal" msgid="6236798763159385225">"የግል"</string>
     <string name="category_work" msgid="4014193632325996115">"ስራ"</string>
+    <string name="category_clone" msgid="1554511758987195974">"አባዛ"</string>
     <string name="development_settings_title" msgid="140296922921597393">"የገንቢዎች አማራጮች"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"የገንቢዎች አማራጮችን አንቃ"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"ለመተግበሪያ ግንባታ አማራጮች አዘጋጅ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 5239341..1a97348 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"صوت عالي الدقة: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"صوت عالي الدقة"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"سماعات الأذن الطبية"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"تمّ التوصيل بسماعات الأذن الطبية"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"‏متصل بـ LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"متصل بالإعدادات الصوتية للوسائط"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"اختيار ملف شخصي"</string>
     <string name="category_personal" msgid="6236798763159385225">"التطبيقات الشخصية"</string>
     <string name="category_work" msgid="4014193632325996115">"تطبيقات العمل"</string>
+    <string name="category_clone" msgid="1554511758987195974">"استنساخ"</string>
     <string name="development_settings_title" msgid="140296922921597393">"خيارات المطورين"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"تفعيل خيارات المطورين"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"تعيين خيارات تطوير التطبيق"</string>
@@ -546,13 +546,13 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"هذا الهاتف"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"هذا الجهاز اللوحي"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"هذا الهاتف"</string>
-    <string name="media_output_status_unknown_error" msgid="5098565887497902222">"لا يمكن تشغيل الوسائط على هذا الجهاز."</string>
-    <string name="media_output_status_require_premium" msgid="8411255800047014822">"يجب ترقية الحساب للتبديل."</string>
-    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"لا يمكن تشغيل المحتوى الذي تم تنزيله هنا."</string>
-    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"يمكنك إعادة المحاولة بعد الإعلان."</string>
-    <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"يجب تنشيط الجهاز لتشغيل الوسائط هنا."</string>
-    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"غير مسموح لهذا الجهاز بتشغيل الوسائط."</string>
-    <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"لا يمكن تشغيل هذه الوسائط هنا."</string>
+    <string name="media_output_status_unknown_error" msgid="5098565887497902222">"لا يمكن تشغيل الوسائط هنا"</string>
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"يجب ترقية الحساب للتبديل"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"المحتوى المنزَّل غير متوافق"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"أعِد المحاولة بعد الإعلان"</string>
+    <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"نشِّط الجهاز للتشغيل هنا"</string>
+    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"غير مسموح له بتشغيل وسائط"</string>
+    <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"هذه الوسائط غير متوافقة"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"حدثت مشكلة أثناء الاتصال. يُرجى إيقاف الجهاز ثم إعادة تشغيله."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"جهاز سماعي سلكي"</string>
     <string name="help_label" msgid="3528360748637781274">"المساعدة والملاحظات"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 79e652fec..7419665 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"এইচ্ছডি অডি\'অ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"এইচ্ছডি অডিঅ’"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"শ্ৰৱণ যন্ত্ৰ"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE অডিঅ’"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"শ্ৰৱণ যন্ত্ৰলৈ সংযোগ কৰা হৈছে"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE অডিঅ’ৰ সৈতে সংযোগ কৰক"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"মিডিয়া অডিঅ’লৈ সংযোগ হৈছে"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"প্ৰ’ফাইল বাছনি কৰক"</string>
     <string name="category_personal" msgid="6236798763159385225">"ব্যক্তিগত"</string>
     <string name="category_work" msgid="4014193632325996115">"কৰ্মস্থান-সম্পৰ্কীয়"</string>
+    <string name="category_clone" msgid="1554511758987195974">"ক্ল’ন"</string>
     <string name="development_settings_title" msgid="140296922921597393">"বিকাশকৰ্তাৰ বিকল্পসমূহ"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"বিকাশকৰ্তা বিষয়ক বিকল্পসমূহ সক্ষম কৰক"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"এপৰ বিকাশৰ বাবে বিকল্পসমূহ ছেট কৰক"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 21ad49a..8d42163 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Eşitmə cihazları"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Eşitmə Aparatlarına qoşuldu"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE audiosuna qoşulub"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Media audioya birləşdirilib"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Profil seçin"</string>
     <string name="category_personal" msgid="6236798763159385225">"Şəxsi"</string>
     <string name="category_work" msgid="4014193632325996115">"İş"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klonlayın"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Developer seçimləri"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Developer variantlarını aktiv edin"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Tətbiq inkişafı seçimlərini təyin et"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index e8fff50..924a53f 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -60,7 +60,7 @@
     <string name="wifi_not_in_range" msgid="1541760821805777772">"Nije u opsegu"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Automatsko povezivanje nije uspelo"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Nema pristupa internetu"</string>
-    <string name="saved_network" msgid="7143698034077223645">"Sačuvao/la je <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="saved_network" msgid="7143698034077223645">"Čuva <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automatski povezano preko %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatski povezano preko dobavljača ocene mreže"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Povezano preko: <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD zvuk: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD zvuk"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Slušni aparati"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Povezano sa slušnim aparatima"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Povezano sa LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Povezano sa zvukom medija"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Otkaži"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Uparivanje omogućava pristup kontaktima i istoriji poziva nakon povezivanja."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Uparivanje sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije moguće."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Uparivanje sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije moguće zbog netačnog PIN-a ili pristupnog koda."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Uparivanje sa <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nije moguće zbog netačnog PIN-a ili pristupnog koda."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Nije moguće komunicirati sa uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> je odbio/la uparivanje"</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Računar"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Izaberite profil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Lično"</string>
     <string name="category_work" msgid="4014193632325996115">"Posao"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klonirano"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opcije za programere"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Omogući opcije za programere"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Podešavanje opcija za programiranje aplikacije"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 13d3bbf..a7f1891 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Аўдыя ў HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Аўдыя ў HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слыхавыя апараты"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Падключана да слыхавых апаратаў"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Падключана да LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Падключана да аўдыё медыа"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Выбраць профіль"</string>
     <string name="category_personal" msgid="6236798763159385225">"Асабісты"</string>
     <string name="category_work" msgid="4014193632325996115">"Працоўны"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Клон"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Параметры распрацоўшчыка"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Уключыць параметры распрацоўшчыка"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Налада параметраў для распрацоўкі прыкладанняў"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 717c565..4ce56f07c 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Висококачествено аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Висококачествено аудио"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слухови апарати"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Установена е връзка със слухов апарат"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Свързано с LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Установена е връзка с медийно аудио"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Отказ"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"При свързване сдвояването предоставя достъп до вашите контакти и история на обажданията."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Неуспешно сдвояване с(ъс) <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Неуспешно сдвояване с(ъс) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> поради неправилен ПИН или код за достъп."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Неуспешно сдвояване с(ъс) <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: неправилен ПИН или ключ за достъп."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Не може да се свърже с/ъс <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Сдвояването е отхвърлено от <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Компютър"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Избор на потребителски профил"</string>
     <string name="category_personal" msgid="6236798763159385225">"Лични"</string>
     <string name="category_work" msgid="4014193632325996115">"Служебни"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Клониране"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Опции за програмисти"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Активиране на опциите за програмисти"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Задаване на опции за програмиране на приложения"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 7051a26..b22f214 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD অডিও: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD অডিও"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"হিয়ারিং এড"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE অডিও"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"হিয়ারিং এডের সাথে কানেক্ট করা হয়েছে"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE অডিও কানেক্ট করা হয়েছে"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"মিডিয়া অডিওতে কানেক্ট রয়েছে"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"প্রোফাইল বেছে নিন"</string>
     <string name="category_personal" msgid="6236798763159385225">"ব্যক্তিগত"</string>
     <string name="category_work" msgid="4014193632325996115">"অফিস"</string>
+    <string name="category_clone" msgid="1554511758987195974">"ক্লোন"</string>
     <string name="development_settings_title" msgid="140296922921597393">"ডেভেলপার বিকল্প"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"ডেভেলপার বিকল্প সক্ষম করুন"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"অ্যাপ্লিকেশান উন্নয়নের জন্য বিকল্পগুলি সেট করুন"</string>
@@ -547,8 +547,8 @@
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"এই ট্যাবলেট"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"এই ফোনটি"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"এই ডিভাইসে চালানো যাবে না"</string>
-    <string name="media_output_status_require_premium" msgid="8411255800047014822">"পরিবর্তন করতে অ্যাকাউন্ট আপগ্রেড করুন"</string>
-    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"এখানে ডাউনলোড করা যাবে না"</string>
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"পাল্টাতে অ্যাকাউন্ট আপগ্রেড করুন"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"এতে ডাউনলোড করা কন্টেন্ট প্লে করা যাবে না"</string>
     <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"বিজ্ঞাপনের পরে আবার চেষ্টা করুন"</string>
     <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"এখানে চালানোর জন্য ডিভাইসকে জাগান"</string>
     <string name="media_output_status_unauthorized" msgid="5880222828273853838">"চালানোর জন্য ডিভাইসের অনুমতি নেই"</string>
@@ -574,7 +574,7 @@
     <string name="user_add_profile_item_summary" msgid="5418602404308968028">"আপনি আপনার অ্যাকাউন্ট থেকে অ্যাপ্লিকেশন এবং কন্টেন্ট অ্যাক্সেস সীমাবদ্ধ করতে পারেন"</string>
     <string name="user_add_user_item_title" msgid="2394272381086965029">"ব্যবহারকারী"</string>
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"সীমাবদ্ধ প্রোফাইল"</string>
-    <string name="user_add_user_title" msgid="5457079143694924885">"নতুন ব্যবহারকারী জুড়বেন?"</string>
+    <string name="user_add_user_title" msgid="5457079143694924885">"নতুন ব্যবহারকারী যোগ করবেন?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"আপনি একাধিক ব্যবহারকারীর আইডি তৈরি করে অন্যদের সাথে এই ডিভাইসটি শেয়ার করতে পারেন। ডিভাইসের স্টোরেজে প্রত্যেক ব্যবহারকারী তার নিজস্ব জায়গা পাবেন যা তিনি অ্যাপ, ওয়ালপেপার এবং আরও অনেক কিছু দিয়ে কাস্টমাইজ করতে পারেন। ওয়াই-ফাই এর মতো ডিভাইস সেটিংস, যেগুলি সকলের ক্ষেত্রে প্রযোজ্য হয়, সেগুলি ব্যবহারকারীরা পরিবর্তন করতে পারবেন।\n\nনতুন ব্যবহারকারীর আইডি যোগ করলে সেই ব্যক্তিকে স্টোরেজে তার নিজের জায়গা সেট-আপ করতে হবে।\n\nঅন্যান্য ব্যবহারকারীদের হয়ে যে কোনও ব্যবহারকারী অ্যাপ আপডেট করতে পারবেন। তবে ব্যবহারযোগ্যতার সেটিংস এবং পরিষেবা নতুন ব্যবহারকারীর ক্ষেত্রে প্রযোজ্য নাও হতে পারে।"</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"আপনি একজন নতুন ব্যবহারকারী যোগ করলে তাকে তার জায়গা সেট-আপ করে নিতে হবে৷\n\nযেকোনও ব্যবহারকারী অন্য সব ব্যবহারকারীর জন্য অ্যাপ আপডেট করতে পারবেন৷"</string>
     <string name="user_grant_admin_title" msgid="5157031020083343984">"এই ব্যবহারকারীকে অ্যাডমিন করবেন?"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index d7dddcd..fd08686 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Slušni aparati"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Povezan na slušne aparate"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Povezano s LE zvukom"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Povezano sa zvukom medija"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Odaberite profil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Lično"</string>
     <string name="category_work" msgid="4014193632325996115">"Posao"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klonirajte"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opcije za programere"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Omogući opcije za programere"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Postavi opcije za razvoj aplikacija"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index f06a48b..a033313 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Àudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Àudio HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Audiòfons"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"S\'ha connectat als audiòfons"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Connectat a LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connectat a l\'àudio del mitjà"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Tria un perfil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Personal"</string>
     <string name="category_work" msgid="4014193632325996115">"Treball"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clona"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opcions per a desenvolupadors"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Activa les opcions per a desenvolupadors"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Defineix les opcions per al desenvolupament d\'aplicacions"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 9b7d40f..8da3a51 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -59,8 +59,8 @@
     <string name="wifi_check_password_try_again" msgid="8817789642851605628">"Zkontrolujte heslo a zkuste to znovu"</string>
     <string name="wifi_not_in_range" msgid="1541760821805777772">"Mimo dosah"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Připojení nebude automaticky navázáno"</string>
-    <string name="wifi_no_internet" msgid="1774198889176926299">"Nebyl zjištěn žádný přístup k internetu"</string>
-    <string name="saved_network" msgid="7143698034077223645">"Uloženo uživatelem <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_no_internet" msgid="1774198889176926299">"Není připojení k internetu"</string>
+    <string name="saved_network" msgid="7143698034077223645">"Uložil(a): <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Automaticky připojeno přes poskytovatele %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automaticky připojeno přes poskytovatele hodnocení sítí"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Připojeno přes <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD zvuk: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD zvuk"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Naslouchátka"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Připojeno k naslouchátkům"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Připojeno k LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Připojeno ke zvukovému médiu"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Vyberte profil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Osobní"</string>
     <string name="category_work" msgid="4014193632325996115">"Pracovní"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Pro vývojáře"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Aktivovat možnosti pro vývojáře"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Umožňuje nastavit možnosti pro vývoj aplikací"</string>
@@ -672,7 +672,7 @@
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Výchozí"</string>
     <string name="turn_screen_on_title" msgid="3266937298097573424">"Zapínání obrazovky"</string>
     <string name="allow_turn_screen_on" msgid="6194845766392742639">"Povolit zapínání obrazovky"</string>
-    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Povolte aplikaci zapínat obrazovku. Pokud aplikace bude mít toto oprávnění, může kdykoli zapnout obrazovku bez explicitního intentu."</string>
+    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Povolte aplikaci zapínat obrazovku. Pokud aplikace bude mít toto oprávnění, může kdykoli zapnout obrazovku bez požadavku uživatele."</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Zastavit vysílání v aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Pokud budete vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g> nebo změníte výstup, aktuální vysílání se zastaví"</string>
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index c6ae909..22b7240 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -95,7 +95,7 @@
     <string name="bluetooth_connected_no_a2dp_battery_level" msgid="6499078454894324287">"Tilsluttet <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (ingen medier) – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Tilsluttet <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g> (ingen telefon eller medier) – batteriniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Aktivt, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string>
-    <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"Aktivt – venstre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> batteri. Højre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri"</string>
+    <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"Aktivt, V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> batteri, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri"</string>
     <string name="bluetooth_battery_level" msgid="2893696778200201555">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string>
     <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"Venstre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> batteri. Højre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri"</string>
     <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktiv"</string>
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-lyd: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-lyd"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Høreapparater"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE-lyd"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Forbundet til høreapparater"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Forbundet med LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Forbundet til medielyd"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Annuller"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Parring giver adgang til dine kontakter og din opkaldshistorik, når enhederne er forbundet."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Der kunne ikke parres med <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Parring med <xliff:g id="DEVICE_NAME">%1$s</xliff:g> mislykkedes på grund af en forkert pinkode eller adgangsnøgle."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Kunne ikke parre med <xliff:g id="DEVICE_NAME">%1$s</xliff:g> pga. forkert pinkode eller adgangsnøgle."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Der kan ikke kommunikeres med <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Parring afvist af <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Computer"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Vælg profil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Personlig"</string>
     <string name="category_work" msgid="4014193632325996115">"Arbejde"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Indstillinger for udviklere"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Aktivér indstillinger for udviklere"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Konfigurer valgmuligheder for appudvikling"</string>
@@ -546,12 +546,12 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Denne telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Denne tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Denne telefon"</string>
-    <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Indholdet kan ikke afspilles på denne enhed"</string>
+    <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan ikke afspilles på denne enhed"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Opgrader kontoen for at skifte"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Downloads kan ikke afspilles her"</string>
     <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Prøv igen efter annoncen"</string>
     <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Væk enheden for at afspille her"</string>
-    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Enheden er ikke godkendt til afspilning"</string>
+    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Enheden er ikke godkendt"</string>
     <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Mediet kan ikke afspilles her"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Der kunne ikke oprettes forbindelse. Sluk og tænd enheden"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Lydenhed med ledning"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 3d6e8e9..57376ab 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-Audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-Audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hörhilfen"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Mit Hörhilfen verbunden"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Mit LE Audio verbunden"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Verbunden mit Medien-Audio"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Profil auswählen"</string>
     <string name="category_personal" msgid="6236798763159385225">"Privat"</string>
     <string name="category_work" msgid="4014193632325996115">"Geschäftlich"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klonen"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Entwickleroptionen"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Entwickleroptionen aktivieren"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Optionen zur App-Entwicklung festlegen"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index a7a410c..3b534a6 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Ήχος HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Ήχος HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Βοηθήματα ακοής"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Έγινε σύνδεση σε βοηθήματα ακοής"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Συνδέθηκε σε LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Συνδέθηκε σε ήχο πολυμέσων"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Επιλογή προφίλ"</string>
     <string name="category_personal" msgid="6236798763159385225">"Προσωπικό"</string>
     <string name="category_work" msgid="4014193632325996115">"Εργασίας"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Κλωνοποίηση"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Επιλογές για προγραμματιστές"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Ενεργοποίηση επιλογών για προγραμματιστές"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Ορισμός επιλογών για ανάπτυξη εφαρμογής"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 1173eaa..8e0aa4e 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connected to Hearing Aids"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Connected to LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connected to media audio"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Choose profile"</string>
     <string name="category_personal" msgid="6236798763159385225">"Personal"</string>
     <string name="category_work" msgid="4014193632325996115">"Work"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Developer options"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Enable developer options"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Set options for app development"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index bfec094..4066992 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -115,7 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
-    <string name="bluetooth_profile_le_audio" msgid="6125267378720026515">"LE audio (experimental)"</string>
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connected to Hearing Aids"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Connected to LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connected to media audio"</string>
@@ -215,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Choose profile"</string>
     <string name="category_personal" msgid="6236798763159385225">"Personal"</string>
     <string name="category_work" msgid="4014193632325996115">"Work"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Developer options"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Enable developer options"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Set options for app development"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 1173eaa..8e0aa4e 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connected to Hearing Aids"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Connected to LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connected to media audio"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Choose profile"</string>
     <string name="category_personal" msgid="6236798763159385225">"Personal"</string>
     <string name="category_work" msgid="4014193632325996115">"Work"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Developer options"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Enable developer options"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Set options for app development"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 1173eaa..8e0aa4e 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hearing Aids"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connected to Hearing Aids"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Connected to LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connected to media audio"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Choose profile"</string>
     <string name="category_personal" msgid="6236798763159385225">"Personal"</string>
     <string name="category_work" msgid="4014193632325996115">"Work"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Developer options"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Enable developer options"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Set options for app development"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index f9b646c..bd6ffa0 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -115,7 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎HD audio: ‎‏‎‎‏‏‎<xliff:g id="CODEC_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‏‏‏‏‎‏‎‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎‏‎‏‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‎HD audio‎‏‎‎‏‎"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‎‎‏‎‎Hearing Aids‎‏‎‎‏‎"</string>
-    <string name="bluetooth_profile_le_audio" msgid="6125267378720026515">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎‎‏‎‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‏‏‎LE audio (experimental)‎‏‎‎‏‎"</string>
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‎‎‏‎‎‎‏‏‏‎‎‏‏‏‏‎‏‏‎‏‎‎‏‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‎LE Audio‎‏‎‎‏‎"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‏‏‎‎‎‏‏‎‏‏‎‎‏‏‏‏‏‏‏‏‎‎Connected to Hearing Aids‎‏‎‎‏‎"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‏‏‎‎‏‏‎‎‏‎‏‎‎Connected to LE audio‎‏‎‎‏‎"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‏‎‏‏‎‏‏‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎Connected to media audio‎‏‎‎‏‎"</string>
@@ -215,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‎‏‎‏‏‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‏‎‎Choose profile‎‏‎‎‏‎"</string>
     <string name="category_personal" msgid="6236798763159385225">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‎‏‎‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‎Personal‎‏‎‎‏‎"</string>
     <string name="category_work" msgid="4014193632325996115">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‎Work‎‏‎‎‏‎"</string>
+    <string name="category_clone" msgid="1554511758987195974">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‎‎‏‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎Clone‎‏‎‎‏‎"</string>
     <string name="development_settings_title" msgid="140296922921597393">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‎‏‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‎Developer options‎‏‎‎‏‎"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎‎‎‎‏‏‏‎Enable developer options‎‏‎‎‏‎"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‏‏‎Set options for app development‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 904e7c3..efd0a5c 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio en HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio en HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Audífonos"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"audio de bajo consumo"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Conectado a audífonos"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Conectado a audio de bajo consumo"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Conectado al audio multimedia"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"La sincronización te permite acceder a los contactos y al historial de llamadas cuando el dispositivo está conectado."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"No se pudo vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"No se pudo vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g> porque la llave de acceso o el PIN son incorrectos."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"No se pudo vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: llave de acceso o PIN incorrectos."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"No se puede establecer la comunicación con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Vínculo rechazado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Computadora"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Elegir perfil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Personal"</string>
     <string name="category_work" msgid="4014193632325996115">"Trabajo"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clonar"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opciones para desarrolladores"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Activar opciones para programador"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Establecer opciones para desarrollar aplicaciones"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index e2f2d9b..0d828bb 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Audífonos"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Conectado a audífonos"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Conectado a LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Conectado al audio del medio"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"La vinculación permite acceder a tus contactos y al historial de llamadas cuando el dispositivo está conectado."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"No se ha podido emparejar con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"No se puede emparejar con <xliff:g id="DEVICE_NAME">%1$s</xliff:g> porque la llave de acceso o el PIN son incorrectos."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"No se puede emparejar con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: PIN o llave de acceso incorrectos."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"No se puede establecer comunicación con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Vinculación rechazada por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Ordenador"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Seleccionar perfil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Personal"</string>
     <string name="category_work" msgid="4014193632325996115">"Trabajo"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clonar"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opciones para desarrolladores"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Habilitar opciones para desarrolladores"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Establecer opciones de desarrollo de aplicaciones"</string>
@@ -329,7 +329,7 @@
     <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Verificar aplicaciones por USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Comprueba las aplicaciones instaladas por ADB/ADT para detectar comportamientos dañinos"</string>
     <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Muestra los dispositivos Bluetooth sin nombre (solo direcciones MAC)"</string>
-    <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Inhabilita la función de volumen absoluto de Bluetooth si se producen problemas de volumen con dispositivos remotos (p. ej., volumen excesivamente alto o falta de control)"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Inhabilita la función de volumen absoluto de Bluetooth si se producen problemas de \\nvolumen con dispositivos remotos (p. ej., volumen excesivamente alto o falta de control)"</string>
     <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Habilita la pila de funciones de Bluetooth Gabeldorsche"</string>
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Habilita la función de conectividad mejorada."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index e047ae5..9ba33bb 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-heli: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-heli"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Kuuldeaparaadid"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Kuuldeaparaatidega ühendatud"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Ühendatud üksusega LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Ühendatud meediumiheliga"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Tühista"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Sidumine annab ühenduse ajal juurdepääsu kontaktidele ja kõneajaloole."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Ei saanud seadmega <xliff:g id="DEVICE_NAME">%1$s</xliff:g> siduda."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Ei saanud seadmega <xliff:g id="DEVICE_NAME">%1$s</xliff:g> siduda vale PIN-koodi või parooli tõttu."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Ei saanud seadmega <xliff:g id="DEVICE_NAME">%1$s</xliff:g> siduda vale PIN-koodi või pääsuvõtme tõttu."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Seadmega <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ei saa sidet luua."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> hülgas sidumise."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Arvuti"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Profiili valimine"</string>
     <string name="category_personal" msgid="6236798763159385225">"Isiklik"</string>
     <string name="category_work" msgid="4014193632325996115">"Töö"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Kloonimine"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Arendaja valikud"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Arendaja valikute lubamine"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Rakenduse arenduse valikute määramine"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 68bf781..0005078 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Kalitate handiko audioa: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Kalitate handiko audioa"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Audifonoak"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"Kontsumo txikiko Bluetooth bidezko audioa"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Audifonoetara konektatuta"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE audio-ra konektatuta"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Euskarriaren audiora konektatuta"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Aukeratu profila"</string>
     <string name="category_personal" msgid="6236798763159385225">"Pertsonalak"</string>
     <string name="category_work" msgid="4014193632325996115">"Lanekoak"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klonatu"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Garatzaileentzako aukerak"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Gaitu garatzaileen aukerak"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Ezarri aplikazioak garatzeko aukerak"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index e7a6552..9f33592 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"‏صدای HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"‏صدای HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"سمعک"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"صدای کم‌مصرف"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"به سمعک متصل شد"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"به «صدای کم‌مصرف» وصل است"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"به رسانه صوتی متصل شد"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"انتخاب نمایه"</string>
     <string name="category_personal" msgid="6236798763159385225">"شخصی"</string>
     <string name="category_work" msgid="4014193632325996115">"کاری"</string>
+    <string name="category_clone" msgid="1554511758987195974">"مشابه‌سازی"</string>
     <string name="development_settings_title" msgid="140296922921597393">"گزینه‌های برنامه‌نویسان"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"فعال کردن گزینه‌های برنامه‌نویس"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"تنظیم گزینه‌های مربوط به طراحی برنامه"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index c2f6926..a543f36 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-ääni: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-ääni"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Kuulolaitteet"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Yhdistetty kuulolaitteisiin"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE Audio yhdistetty"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Yhdistetty median ääneen"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Peru"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Laiteparin muodostaminen mahdollistaa yhteystietojen ja soittohistorian käyttämisen yhteyden aikana."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Laiteparin muodostaminen laitteeseen <xliff:g id="DEVICE_NAME">%1$s</xliff:g> epäonnistui."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Laiteparia (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) ei voitu muodostaa, koska PIN-koodi tai avain oli virheellinen."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Laiteparia (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) ei voitu muodostaa, koska PIN tai avain oli väärä."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Ei yhteyttä laitteeseen <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Laite <xliff:g id="DEVICE_NAME">%1$s</xliff:g> torjui laitepariyhteyden."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Tietokone"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Valitse profiili"</string>
     <string name="category_personal" msgid="6236798763159385225">"Henkilökohtainen"</string>
     <string name="category_work" msgid="4014193632325996115">"Työ"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klooni"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Kehittäjäasetukset"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Ota kehittäjäasetukset käyttöön"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Valitse sovellusten kehittämisasetukset"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 0561c28..94dbeef 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -37,7 +37,7 @@
     <string name="wifi_security_wep" msgid="1413627788581122366">"WEP"</string>
     <string name="wifi_security_wpa" msgid="1072450904799930636">"WPA-Personal"</string>
     <string name="wifi_security_wpa2" msgid="4038267581230425543">"WPA2-Personal"</string>
-    <string name="wifi_security_wpa_wpa2" msgid="946853615482465986">"WPA/WPA2-Personal"</string>
+    <string name="wifi_security_wpa_wpa2" msgid="946853615482465986">"WPA/WPA2-Personnel"</string>
     <string name="wifi_security_eap" msgid="6179633834446852269">"WPA/WPA2/WPA3-Enterprise"</string>
     <string name="wifi_security_eap_wpa" msgid="6189023812330549957">"WPA-Enterprise"</string>
     <string name="wifi_security_eap_wpa_wpa2" msgid="1089879674896108216">"WPA/WPA2-Enterprise"</string>
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD : <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Prothèses auditives"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connecté aux prothèses auditives"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Connecté par LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connecté aux paramètres audio du média"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Sélectionnez un profil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Personnel"</string>
     <string name="category_work" msgid="4014193632325996115">"Professionnel"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Cloner"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Options pour les développeurs"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Activer les options pour les développeurs"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Définir les options pour le développement de l\'application"</string>
@@ -670,9 +670,9 @@
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Clavier physique"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Sélectionner disposition du clavier"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Par défaut"</string>
-    <string name="turn_screen_on_title" msgid="3266937298097573424">"Activation de l\'écran"</string>
+    <string name="turn_screen_on_title" msgid="3266937298097573424">"Activer l\'écran"</string>
     <string name="allow_turn_screen_on" msgid="6194845766392742639">"Autoriser l\'activation de l\'écran"</string>
-    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Autorisez une application à activer l\'écran. Lorsque vous accordez cette autorisation, l\'application peut activer l\'écran à tout moment sans votre volonté explicite."</string>
+    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Autorisez une application à activer l\'écran. Lorsque vous accordez cette autorisation, l\'application peut activer l\'écran à tout moment sans que vous lui demandiez."</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou changez la sortie, votre diffusion actuelle s\'arrêtera"</string>
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 66482e24..5a492a8 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -111,12 +111,11 @@
     <string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"À utiliser pour partage des contacts/historique des appels"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Partage de connexion Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS"</string>
-    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Accès à la carte SIM"</string>
+    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Accès à la SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD : <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Appareils auditifs"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connexion établie avec les appareils auditifs"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Connecté à LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Connecté aux paramètres audio du média"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Sélectionner un profil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Perso"</string>
     <string name="category_work" msgid="4014193632325996115">"Pro"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Options pour les développeurs"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Activer les options pour les développeurs"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Définir les options pour le développement de l\'application"</string>
@@ -672,7 +672,7 @@
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Par défaut"</string>
     <string name="turn_screen_on_title" msgid="3266937298097573424">"Activer l\'écran"</string>
     <string name="allow_turn_screen_on" msgid="6194845766392742639">"Autoriser l\'activation de l\'écran"</string>
-    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Autoriser une appli à activer l\'écran. Si l\'autorisation est accordée, l\'appli peut activer l\'écran à tout moment sans votre intention explicite."</string>
+    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Autoriser une appli à activer l\'écran. Si elle y est autorisée, l\'appli pourra activer l\'écran à tout moment sans que vous le lui demandiez."</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou que vous modifiez le résultat, votre annonce actuelle s\'arrêtera"</string>
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index f717e7e..9ea4cbd 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio en HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio en HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Audiófonos"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"Audio de baixo consumo"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Conectado a audiófonos"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Estableceuse conexión co audio de baixo consumo"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Conectado ao audio multimedia"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"A vinculación garante acceso aos teus contactos e ao historial de chamadas ao estar conectado"</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Non se puido vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Non se puido vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g> porque a clave de acceso ou o PIN son incorrectos."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Non se puido vincular con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, clave de acceso ou PIN incorrectos."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Non se pode comunicar con <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Vinculación rexeitada por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Ordenador"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Escoller perfil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Persoal"</string>
     <string name="category_work" msgid="4014193632325996115">"Traballo"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clonar"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opcións para programadores"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Activar opcións para programadores"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Definir as opcións de desenvolvemento de aplicacións"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 0eb03d3..0417940 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ઑડિયો: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ઑડિયો"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"શ્રવણ યંત્રો"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ઑડિયો"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"શ્રવણ યંત્રો સાથે કનેક્ટ કરેલું છે"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ઑડિયોથી કનેક્ટેડ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"મીડિયા ઑડિઓ સાથે કનેક્ટ કર્યુ"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"પ્રોફાઇલ પસંદ કરો"</string>
     <string name="category_personal" msgid="6236798763159385225">"વ્યક્તિગત"</string>
     <string name="category_work" msgid="4014193632325996115">"ઑફિસ"</string>
+    <string name="category_clone" msgid="1554511758987195974">"ક્લોન કરો"</string>
     <string name="development_settings_title" msgid="140296922921597393">"ડેવલપરના વિકલ્પો"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"વિકાસકર્તાનાં વિકલ્પો સક્ષમ કરો"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"ઍપ્લિકેશન વિકાસ માટે વિકલ્પો સેટ કરો"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 1af8706..3d04845 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"एचडी ऑडियो: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"एचडी ऑडियो"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"कान की मशीन"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"सुनने में मदद करने वाले डिवाइस से कनेक्ट है"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE Audio से कनेक्ट किया गया"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"मीडिया ऑडियो से कनेक्‍ट किया गया"</string>
@@ -215,7 +214,8 @@
   </string-array>
     <string name="choose_profile" msgid="343803890897657450">"प्रोफ़ाइल चुनें"</string>
     <string name="category_personal" msgid="6236798763159385225">"निजी"</string>
-    <string name="category_work" msgid="4014193632325996115">"वर्क"</string>
+    <string name="category_work" msgid="4014193632325996115">"वर्क ऐप्लिकेशन"</string>
+    <string name="category_clone" msgid="1554511758987195974">"क्लोन"</string>
     <string name="development_settings_title" msgid="140296922921597393">"डेवलपर के लिए सेटिंग और टूल"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"डेवलपर के लिए सेटिंग और टूल चालू करें"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"ऐप्लिकेशन विकास के लिए विकल्‍प सेट करें"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 7ef4f20..8649e22 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Slušni aparati"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Povezano sa Slušnim aparatima"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Povezano s profilom LE_AUDIO"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Povezano s medijskim zvukom"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Odabir profila"</string>
     <string name="category_personal" msgid="6236798763159385225">"Osobno"</string>
     <string name="category_work" msgid="4014193632325996115">"Posao"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Kloniranje"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opcije za razvojne programere"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Omogući opcije za razvojne programere"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Postavljanje opcija za razvoj aplikacije"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 7862891..0b9737e 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hallókészülékek"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"Alacsony energiaszintű hangátvitel"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Hallókészülékhez csatlakoztatva"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Csatlakoztatva az alacsony energiaszintű hangátvitelhez"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Csatlakoztatva az eszköz hangjához"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Mégse"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"A párosítás hozzáférést biztosít a névjegyekhez és híváselőzményekhez összekapcsolt állapotban."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Nem lehet párosítani a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközzel."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"A párosítás sikertelen volt a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközzel hibás PIN-kód vagy jelszó miatt."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Sikertelen párosítás a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközzel – hibás PIN vagy jelszó"</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Nem lehet kommunikálni a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközzel."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"A(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszköz elutasította a párosítást."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Számítógép"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Profil kiválasztása"</string>
     <string name="category_personal" msgid="6236798763159385225">"Személyes"</string>
     <string name="category_work" msgid="4014193632325996115">"Munkahelyi"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klónozás"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Fejlesztői beállítások"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Fejlesztői beállítások engedélyezése"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Alkalmazásfejlesztési beállítások megadása"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 517721f..55bb122 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD աուդիո՝ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD աուդիո"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Լսողական ապարատ"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Լսողական ապարատը միացված է"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Միացած է LE audio-ին"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Միացված է մեդիա աուդիոյին"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Ընտրեք պրոֆիլ"</string>
     <string name="category_personal" msgid="6236798763159385225">"Անձնական"</string>
     <string name="category_work" msgid="4014193632325996115">"Աշխատանքային"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Կլոն"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Մշակողի ընտրանքներ"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Միացնել մշակողի ընտրանքները"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Կարգավորել ընտրանքները ծրագրի ծրագրավորման համար"</string>
@@ -548,7 +548,7 @@
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Այս հեռախոսը"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Հնարավոր չէ նվագարկել այս սարքում"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Փոխելու համար անցեք հաշվի պրեմիում տարբերակին"</string>
-    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Հնարավոր չէ նվագարկել ներբեռնումներն այստեղ"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Ներբեռնումները չեն նվագարկվում այստեղ"</string>
     <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Նորից փորձեք գովազդից հետո"</string>
     <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Արթնացրեք սարքը՝ այստեղ նվագարկելու համար"</string>
     <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Նվագարկելու համար հաստատեք սարքը"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 84681ae..b6756c2 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Alat Bantu Dengar"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Terhubung ke Alat Bantu Dengar"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Terhubung ke LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Terhubung ke media audio"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Batal"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Penyandingan memberi akses ke kontak dan histori panggilan saat terhubung"</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Tidak dapat menyambungkan dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Tidak dapat menyambungkan dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> karena PIN atau kode sandi salah."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"PIN atau kunci sandi salah. Penyambungan ke <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gagal."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Tidak dapat berkomunikasi dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Penyandingan ditolak oleh <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Komputer"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Pilih profil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Pribadi"</string>
     <string name="category_work" msgid="4014193632325996115">"Kerja"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opsi developer"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Aktifkan opsi developer"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Menyetel opsi untuk pengembangan apl"</string>
@@ -670,7 +670,7 @@
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Keyboard fisik"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Pilih tata letak keyboard"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Default"</string>
-    <string name="turn_screen_on_title" msgid="3266937298097573424">"Mengaktifkan layar"</string>
+    <string name="turn_screen_on_title" msgid="3266937298097573424">"Pengaktifan layar"</string>
     <string name="allow_turn_screen_on" msgid="6194845766392742639">"Izinkan pengaktifan layar"</string>
     <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Mengizinkan aplikasi mengaktifkan layar. Jika diizinkan, aplikasi dapat mengaktifkan layar kapan saja tanpa izin Anda."</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Hentikan siaran <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index fe54576..db1cd0f 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-hljóð: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-hljóð"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Heyrnartæki"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE-hljóð"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Tengt við heyrnartæki"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Tengt við LE-hljóð"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Tengt við hljóðspilun efnis"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Veldu snið"</string>
     <string name="category_personal" msgid="6236798763159385225">"Persónulegt"</string>
     <string name="category_work" msgid="4014193632325996115">"Vinna"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Afrit"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Forritunarkostir"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Virkja valkosti þróunaraðila"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Stilla valkosti fyrir forritaþróun"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 91bacd9..9c28102 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Apparecchi acustici"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Connessione con gli apparecchi acustici stabilita"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Connesso a LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Collegato ad audio media"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Scegli profilo"</string>
     <string name="category_personal" msgid="6236798763159385225">"Personale"</string>
     <string name="category_work" msgid="4014193632325996115">"Lavoro"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opzioni sviluppatore"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Attiva Opzioni sviluppatore"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Imposta opzioni per lo sviluppo di applicazioni"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 71be2dc..167be60 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"‏אודיו באיכות HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"‏אודיו באיכות HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"מכשירי שמיעה"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"מחובר אל מכשירי שמיעה"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"‏מחובר אל LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"מחובר לאודיו של מדיה"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"בחירת פרופיל"</string>
     <string name="category_personal" msgid="6236798763159385225">"אישי"</string>
     <string name="category_work" msgid="4014193632325996115">"עבודה"</string>
+    <string name="category_clone" msgid="1554511758987195974">"שכפול"</string>
     <string name="development_settings_title" msgid="140296922921597393">"אפשרויות למפתחים"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"הפעלת אפשרויות למפתחים"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"הגדרת אפשרויות לפיתוח אפליקציות"</string>
@@ -576,7 +576,7 @@
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"פרופיל מוגבל"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"להוסיף משתמש חדש?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"‏ניתן לשתף מכשיר זה עם אנשים אחרים על ידי יצירת משתמשים נוספים. לכל משתמש מרחב משלו, שאותו אפשר להתאים אישית בעזרת אפליקציות, טפט ופריטים נוספים. המשתמשים יכולים גם להתאים הגדרות של המכשיר כגון Wi‑Fi, שמשפיעות על כולם.\n\nכשמוסיפים משתמש חדש, על משתמש זה להגדיר את המרחב שלו.\n\nכל אחד מהמשתמשים יכול לעדכן אפליקציות לכל שאר המשתמשים. ייתכן שהגדרות ושירותים של נגישות לא יועברו למשתמש החדש."</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"כשמוסיפים משתמש חדש, המשתמש הזה צריך להגדיר את המרחב שלו.\n\nכל משתמש יכול לעדכן אפליקציות עבור כל המשתמשים האחרים."</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"כשמוסיפים משתמש חדש, הוא צריך להגדיר את המרחב שלו.\n\nכל משתמש יכול לעדכן אפליקציות עבור כל המשתמשים האחרים."</string>
     <string name="user_grant_admin_title" msgid="5157031020083343984">"להגדיר את המשתמש הזה כאדמין?"</string>
     <string name="user_grant_admin_message" msgid="1673791931033486709">"לאדמינים יש הרשאות מיוחדות שאין למשתמשים אחרים. אדמין יכול לנהל את כל המשתמשים, לעדכן את המכשיר הזה או לאפס אותו, לשנות הגדרות, לראות את כל האפליקציות המותקנות ולהעניק הרשאות אדמין לאחרים או לשלול אותן."</string>
     <string name="user_grant_admin_button" msgid="5441486731331725756">"הגדרה כאדמין"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 4f5539b..0320468 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD オーディオ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD オーディオ"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"補聴器"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"補聴器に接続"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE Audio に接続"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"メディアの音声に接続"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"プロファイルの選択"</string>
     <string name="category_personal" msgid="6236798763159385225">"個人用"</string>
     <string name="category_work" msgid="4014193632325996115">"仕事用"</string>
+    <string name="category_clone" msgid="1554511758987195974">"クローン"</string>
     <string name="development_settings_title" msgid="140296922921597393">"開発者向けオプション"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"開発者向けオプションの有効化"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"アプリ開発オプションを設定する"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 6f18681..1152609 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD აუდიო: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD აუდიო"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"სმენის მოწყობილობები"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE-აუდიო"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"დაკავშირებულია სმენის მოწყობილობებთან"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"დაკავშირებულია LE აუდიოსთან"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"დაკავშირებულია აუდიო მულტიმედიურ სისტემასთან"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"აირჩიეთ პროფილი"</string>
     <string name="category_personal" msgid="6236798763159385225">"პირადი"</string>
     <string name="category_work" msgid="4014193632325996115">"სამსახური"</string>
+    <string name="category_clone" msgid="1554511758987195974">"კლონის შექმნა"</string>
     <string name="development_settings_title" msgid="140296922921597393">"პარამეტრები დეველოპერებისთვის"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"დეველოპერთა პარამეტრების ჩართვა"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"პარამეტრების დაყენება აპების დეველოპერებისთვის"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index c9563ed..996d216 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD форматты аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD форматты аудио"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Есту аппараттары"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Есту аппараттарына жалғанған"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE Audio-ға жалғанды."</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Медиа аудиосына жалғанған"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Профильді таңдау"</string>
     <string name="category_personal" msgid="6236798763159385225">"Жеке"</string>
     <string name="category_work" msgid="4014193632325996115">"Жұмыс"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Клондау"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Әзірлеуші опциялары"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Әзірлеуші ​​параметрлерін қосу"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Қолданба дамыту үшін опцияларын реттеу"</string>
@@ -672,7 +672,7 @@
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Әдепкі"</string>
     <string name="turn_screen_on_title" msgid="3266937298097573424">"Экранды қосу"</string>
     <string name="allow_turn_screen_on" msgid="6194845766392742639">"Экранды қосуға рұқсат беру"</string>
-    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Қолданбаның экранды қосуына рұқсат береді. Рұқсат берілсе, қолданба кез келген уақытта экранды өздігінен қосуы мүмкін."</string>
+    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Қолданбаға экранды қосуға рұқсат береді. Рұқсат берілсе, қолданба кез келген уақытта экранды өздігінен қосуы мүмкін."</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын таратуды тоқтатасыз ба?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын таратсаңыз немесе аудио шығысын өзгертсеңіз, қазіргі тарату сеансы тоқтайды."</string>
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын тарату"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 93a1e08..e546821 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"សំឡេងកម្រិត HD៖ <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"សំឡេងកម្រិត HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"ឧបករណ៍​ជំនួយការ​ស្ដាប់"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"បាន​ភ្ជាប់ទៅ​ឧបករណ៍​ជំនួយការ​ស្ដាប់"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"បានភ្ជាប់​ទៅ LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"បា​ន​ភ្ជាប់​ទៅ​អូឌីយ៉ូ​មេឌៀ"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"ជ្រើសរើស​កម្រងព័ត៌មាន"</string>
     <string name="category_personal" msgid="6236798763159385225">"ផ្ទាល់ខ្លួន"</string>
     <string name="category_work" msgid="4014193632325996115">"ការងារ"</string>
+    <string name="category_clone" msgid="1554511758987195974">"ក្លូន"</string>
     <string name="development_settings_title" msgid="140296922921597393">"ជម្រើសសម្រាប់អ្នកអភិវឌ្ឍន៍"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"បើកដំណើរការជម្រើសអ្នកអភិវឌ្ឍន៍"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"កំណត់​ជម្រើស​សម្រាប់​ការ​អភិវឌ្ឍ​កម្មវិធី"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 5f777f5..f4802a6 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ಆಡಿಯೋ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ಆಡಿಯೋ"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"ಶ್ರವಣ ಸಾಧನಗಳು"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ಆಡಿಯೋ"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ಶ್ರವಣ ಸಾಧನಗಳಿಗೆ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ಆಡಿಯೋಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"ಮಾಧ್ಯಮ ಆಡಿಯೋಗೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"ರದ್ದುಮಾಡಿ"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"ಸಂಪರ್ಕಗೊಳಿಸಿದಾಗ, ಜೋಡಿಸುವಿಕೆಯು ನಿಮ್ಮ ಸಂಪರ್ಕಗಳು ಮತ್ತು ಕರೆ ಇತಿಹಾಸಕ್ಕೆ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಜೋಡಣೆ ಮಾಡಲಾಗಲಿಲ್ಲ."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"ತಪ್ಪಾಗಿರುವ ಪಿನ್‌ ಅಥವಾ ಪಾಸ್‌ಕೀ ಕಾರಣದಿಂದಾಗಿ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಜೋಡಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"ತಪ್ಪು ಪಿನ್‌ ಅಥವಾ ಪಾಸ್‌ಕೀ ಕಾರಣ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಜೋಡಿಸಲಾಗಲಿಲ್ಲ."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಜೊತೆಗೆ ಸಂವಹನ ನಡೆಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"ಜೋಡಿಸುವಿಕೆಯನ್ನು <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ತಿರಸ್ಕರಿಸಿದೆ"</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"ಕಂಪ್ಯೂಟರ್‌"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"ಪ್ರೊಫೈಲ್ ಆಯ್ಕೆ ಮಾಡಿ"</string>
     <string name="category_personal" msgid="6236798763159385225">"ವೈಯಕ್ತಿಕ"</string>
     <string name="category_work" msgid="4014193632325996115">"ಕೆಲಸ"</string>
+    <string name="category_clone" msgid="1554511758987195974">"ಕ್ಲೋನ್"</string>
     <string name="development_settings_title" msgid="140296922921597393">"ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳು"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"ಅಪ್ಲಿಕೇಶನ್ ಅಭಿವೃದ್ಧಿಗಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
@@ -320,7 +320,7 @@
     <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"ವೈ-ಫೈ ಸಕ್ರಿಯವಾಗಿರುವಾಗಲೂ, ಯಾವಾಗಲೂ ಮೊಬೈಲ್‌ ಡೇಟಾ ಸಕ್ರಿಯವಾಗಿರಿಸಿ (ವೇಗವಾಗಿ ನೆಟ್‌ವರ್ಕ್‌ ಬದಲಾಯಿಸಲು)."</string>
     <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"ಹಾರ್ಡ್‌ವೇರ್‌ನ ವೇಗವರ್ಧನೆ ಟೆಥರಿಂಗ್ ಲಭ್ಯವಿದ್ದರೆ ಅದನ್ನು ಬಳಸಿ"</string>
     <string name="adb_warning_title" msgid="7708653449506485728">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
-    <string name="adb_warning_message" msgid="8145270656419669221">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯು ಅಭಿವೃದ್ಧಿ ಉದ್ದೇಶಗಳಿಗೆ ಮಾತ್ರ ಆಗಿದೆ. ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ನಡುವೆ ಡೇಟಾವನ್ನು ನಕಲಿಸಲು, ಅಧಿಸೂಚನೆ ಇಲ್ಲದೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಲು ಮತ್ತು ಲಾಗ್ ಡೇಟಾ ಓದಲು ಅದನ್ನು ಬಳಸಿ."</string>
+    <string name="adb_warning_message" msgid="8145270656419669221">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯು ಅಭಿವೃದ್ಧಿ ಉದ್ದೇಶಗಳಿಗೆ ಮಾತ್ರ ಆಗಿದೆ. ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ನಡುವೆ ಡೇಟಾವನ್ನು ನಕಲಿಸಲು, ನೋಟಿಫಿಕೇಶನ್ ಇಲ್ಲದೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆ್ಯಪ್‍ಗಳನ್ನು ಇನ್‍ಸ್ಟಾಲ್ ಮಾಡಲು ಮತ್ತು ಲಾಗ್ ಡೇಟಾ ಓದಲು ಅದನ್ನು ಬಳಸಿ."</string>
     <string name="adbwifi_warning_title" msgid="727104571653031865">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಅನುಮತಿಸಬೇಕೆ?"</string>
     <string name="adbwifi_warning_message" msgid="8005936574322702388">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್ ಮಾಡುವಿಕೆಯು ಅಭಿವೃದ್ಧಿ ಉದ್ದೇಶಗಳಿಗೆ ಮಾತ್ರ ಆಗಿದೆ. ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ನಡುವೆ ಡೇಟಾವನ್ನು ನಕಲಿಸಲು, ಅಧಿಸೂಚನೆ ಇಲ್ಲದೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆ್ಯಪ್‌ಗಳನ್ನು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲು ಮತ್ತು ಲಾಗ್ ಡೇಟಾ ಓದಲು ಅದನ್ನು ಬಳಸಿ."</string>
     <string name="adb_keys_warning_message" msgid="2968555274488101220">"ನೀವು ಹಿಂದೆ ಅಧಿಕೃತಗೊಳಿಸಿದ ಎಲ್ಲ ಕಂಪ್ಯೂಟರ್‌ಗಳಿಂದ USB ಡೀಬಗ್‌ಗೆ ಪ್ರವೇಶವನ್ನು ರದ್ದುಗೊಳಿಸುವುದೇ?"</string>
@@ -393,7 +393,7 @@
     <string name="app_process_limit_title" msgid="8361367869453043007">"ಹಿನ್ನೆಲೆ ಪ್ರಕ್ರಿಯೆ ಮಿತಿ"</string>
     <string name="show_all_anrs" msgid="9160563836616468726">"ಹಿನ್ನೆಲೆ ANR ಗಳನ್ನು ತೋರಿಸಿ"</string>
     <string name="show_all_anrs_summary" msgid="8562788834431971392">"ಹಿನ್ನೆಲೆ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್ ಪ್ರತಿಕ್ರಿಯಿಸುತ್ತಿಲ್ಲ ಎಂಬ ಸಂಭಾಷಣೆ ತೋರಿಸಿ"</string>
-    <string name="show_notification_channel_warnings" msgid="3448282400127597331">"ಅಧಿಸೂಚನೆ ಎಚ್ಚರಿಕೆ ತೋರಿಸಿ"</string>
+    <string name="show_notification_channel_warnings" msgid="3448282400127597331">"ನೋಟಿಫಿಕೇಶನ್ ಎಚ್ಚರಿಕೆ ತೋರಿಸಿ"</string>
     <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"ಅಮಾನ್ಯ ಚಾನಲ್ ಅಧಿಸೂಚನೆಗಾಗಿ ಪರದೆಯಲ್ಲಿ ಎಚ್ಚರಿಕೆ"</string>
     <string name="force_allow_on_external" msgid="9187902444231637880">"ಬಾಹ್ಯವಾಗಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಒತ್ತಾಯವಾಗಿ ಅನುಮತಿಸಿ"</string>
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"ಮ್ಯಾನಿಫೆಸ್ಟ್ ಮೌಲ್ಯಗಳು ಯಾವುದೇ ಆಗಿದ್ದರೂ, ಬಾಹ್ಯ ಸಂಗ್ರಹಣೆಗೆ ಬರೆಯಲು ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್‌ ಅನ್ನು ಅರ್ಹಗೊಳಿಸುತ್ತದೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index f80bba7..0eaf6dd 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD 오디오: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD 오디오"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"보청기"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE 오디오"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"보청기에 연결됨"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE 오디오에 연결됨"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"미디어 오디오에 연결됨"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"프로필 선택"</string>
     <string name="category_personal" msgid="6236798763159385225">"개인"</string>
     <string name="category_work" msgid="4014193632325996115">"직장"</string>
+    <string name="category_clone" msgid="1554511758987195974">"복사"</string>
     <string name="development_settings_title" msgid="140296922921597393">"개발자 옵션"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"개발자 옵션 사용"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"앱 개발 옵션 설정"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index d2fe7f7..6c9abb2 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD форматындагы аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD форматындагы аудио"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Угуу аппараттары"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Угуу аппараттарына туташып турат"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE аудио менен туташты"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Медиа аудиого туташты"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Жок"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Жупташканда байланыштарыңыз менен чалуу таржымалыңызды пайдалана аласыз."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүнө туташуу мүмкүн болгон жок."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"PIN-код же сырсөз туура эмес болгондуктан, \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" туташпай калды."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"\"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" туташкан жок: PIN-код же сырсөз туура эмес."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> менен байланышуу мүмкүн эмес."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Жупташтырууну <xliff:g id="DEVICE_NAME">%1$s</xliff:g> четке какты."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Компьютер"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Профиль тандоо"</string>
     <string name="category_personal" msgid="6236798763159385225">"Жеке"</string>
     <string name="category_work" msgid="4014193632325996115">"Жумуш"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Клон"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Иштеп чыгуучунун параметрлери"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Иштеп чыгуучунун параметрлерин иштетүү"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Колдонмо өндүрүү мүмкүнчүлүктөрүн орнотуу"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 6f5b3ff..1b7138d 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"ສຽງ HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"ສຽງ HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"ອຸປະກອນຊ່ວຍຟັງ"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"ສຽງ LE"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ເຊື່ອມຕໍ່ຫາອຸປະກອນຊ່ວຍຟັງແລ້ວ"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"ເຊື່ອມຕໍ່ຫາສຽງ LE ແລ້ວ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"ເຊື່ອມຕໍ່ກັບສື່ດ້ານສຽງແລ້ວ"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"ເລືອກໂປຣໄຟລ໌"</string>
     <string name="category_personal" msgid="6236798763159385225">"​ສ່ວນ​ໂຕ"</string>
     <string name="category_work" msgid="4014193632325996115">"​ບ່ອນ​ເຮັດ​ວຽກ"</string>
+    <string name="category_clone" msgid="1554511758987195974">"ໂຄລນ"</string>
     <string name="development_settings_title" msgid="140296922921597393">"ຕົວເລືອກນັກພັດທະນາ"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"ເປີດໃຊ້ຕົວເລືອກນັກພັດທະນາ"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"ຕັ້ງຄ່າໂຕເລືອກສຳລັບການພັດທະນາແອັບຯ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 645fba1..6024772 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD garsas: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD garsas"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Klausos aparatai"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Prisijungta prie klausos aparatų"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Prisijungta prie „LE Audio“"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Prijungta prie medijos garso įrašo"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Profilio pasirinkimas"</string>
     <string name="category_personal" msgid="6236798763159385225">"Asmeninės"</string>
     <string name="category_work" msgid="4014193632325996115">"Darbo"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Identiška kopija"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Kūrėjo parinktys"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Įgalinti kūrėjo parinktis"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Nustatyti programos kūrimo parinktis"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 429c744..259e3f4 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -106,7 +106,7 @@
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Tālruņa zvani"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Failu pārsūtīšana"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ievades ierīce"</string>
-    <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Interneta piekļuve"</string>
+    <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Piekļuve internetam"</string>
     <string name="bluetooth_profile_pbap" msgid="4262303387989406171">"Kontaktpersonu un zvanu vēst. kopīgošana"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"Paredzēts kontaktpersonu un zvanu vēstures kopīgošanai"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Interneta savienojuma koplietošana"</string>
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Dzirdes aparāti"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Izveidots savienojums ar dzirdes aparātiem"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Izveidots savienojums ar LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Savienots ar multivides audio"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Atcelt"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Veicot savienošanu pārī, šī ierīce savienojuma laikā varēs piekļūt jūsu kontaktpersonām un zvanu vēsturei."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Nevarēja savienot pārī ar ierīci <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Nevarēja savienot pārī ar ierīci <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, jo tika ievadīts nepareizs PIN kods vai nepareiza ieejas atslēga."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Nevarēja savienot pārī ar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, jo tika ievadīts nepareizs PIN kods vai ieejas atslēga."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Nevar sazināties ar ierīci <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> noraidīja pāra izveidi."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Dators"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Profila izvēlēšanās"</string>
     <string name="category_personal" msgid="6236798763159385225">"Privāts"</string>
     <string name="category_work" msgid="4014193632325996115">"Darba"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klons"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Izstrādātāju opcijas"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Izstrādātāju opciju iespējošana"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Iestatīt lietotņu izstrādes opcijas"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 1b851b5..55d29cd 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-аудио"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слушни помагала"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE-аудио"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Поврзано со слушни помагала"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Поврзано на LE-аудио"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Поврзан со аудио на медиуми"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Изберете профил"</string>
     <string name="category_personal" msgid="6236798763159385225">"Лични"</string>
     <string name="category_work" msgid="4014193632325996115">"Работа"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Клон"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Програмерски опции"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Овозможете ги програмерските опции"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Постави опции за развој на апликација"</string>
@@ -441,7 +441,7 @@
     <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Девтераномалија (слепило за црвена и зелена)"</string>
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномалија (слепило за црвена и зелена)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомалија (слепило за сина и жолта)"</string>
-    <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Корекција на бои"</string>
+    <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Корекција на боите"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Корекцијата на боите може да биде корисна кога сакате:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;да ги гледате боите попрецизно&lt;/li&gt; &lt;li&gt;&amp;nbsp;да ги отстраните боите за полесно да се концентрирате&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
@@ -672,7 +672,7 @@
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Стандардно"</string>
     <string name="turn_screen_on_title" msgid="3266937298097573424">"Вклучување на екранот"</string>
     <string name="allow_turn_screen_on" msgid="6194845766392742639">"Дозволи вклучување на екранот"</string>
-    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Дозволете апликација да го вклучи екранот. Ако дозволите, апликацијата може да го вклучи екранот во секое време без ваша намера."</string>
+    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Дозволува одредена апликација да го вклучува екранот. Ако е дозволено, апликацијата може да го вклучува екранот во секое време без ваша намера."</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Да се прекине емитувањето на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ако емитувате на <xliff:g id="SWITCHAPP">%1$s</xliff:g> или го промените излезот, тековното емитување ќе запре"</string>
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Емитување на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index f9c2c00..f234392 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ഓഡിയോ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ഓഡിയോ"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"ശ്രവണ സഹായികൾ"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ഓഡിയോ"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ശ്രവണ സഹായികളിലേക്ക് കണക്‌റ്റ് ചെയ്‌തു"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ഓഡിയോയിലേക്ക് കണക്‌റ്റ് ചെയ്‌തു"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"മീഡിയ ഓഡിയോയിലേക്ക് കണ‌ക്റ്റുചെയ്‌തു"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"പ്രൊഫൈൽ തിരഞ്ഞെടുക്കുക"</string>
     <string name="category_personal" msgid="6236798763159385225">"വ്യക്തിപരം"</string>
     <string name="category_work" msgid="4014193632325996115">"ഔദ്യോഗികം"</string>
+    <string name="category_clone" msgid="1554511758987195974">"ക്ലോൺ ചെയ്യുക"</string>
     <string name="development_settings_title" msgid="140296922921597393">"ഡെവലപ്പർ ഓ‌പ്ഷനുകൾ"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"ഡെവലപ്പർ ഓ‌പ്ഷനുകൾ പ്രവർത്തനക്ഷമമാക്കുക"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"അപ്ലിക്കേഷൻ വികസനത്തിന് ഓപ്ഷനുകൾ സജ്ജീകരിക്കുക"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 47bd474..309b683 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD аудио"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Сонсголын төхөөрөмж"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Аудио"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Сонсголын төхөөрөмжтэй холбосон"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE аудионд холбогдсон"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Медиа аудиод холбогдсон"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Профайл сонгох"</string>
     <string name="category_personal" msgid="6236798763159385225">"Хувийн"</string>
     <string name="category_work" msgid="4014193632325996115">"Ажил"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Клон"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Хөгжүүлэгчийн тохиргоо"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Хөгжүүлэгчийн сонголтыг идэвхжүүлэх"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Апп хөгжүүлэлтэд зориулсан сонголтуудыг тохируулах"</string>
@@ -576,7 +576,7 @@
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"Хязгаарлагдсан профайл"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"Шинэ хэрэглэгч нэмэх үү?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Та нэмэлт хэрэглэгч үүсгэх замаар бусад хүмүүстэй энэ төхөөрөмжийг хуваалцаж болно. Хэрэглэгч тус бүр апп, дэлгэцийн зураг болон бусад зүйлээ өөрчлөх боломжтой хувийн орон зайтай байна. Түүнчлэн хэрэглэгч нь бүх хэрэглэгчид нөлөөлөх боломжтой Wi-Fi зэрэг төхөөрөмжийн тохиргоог өөрчлөх боломжтой.\n\nХэрэв та шинэ хэрэглэгч нэмэх бол тухайн хүн хувийн орон зайгаа бүрдүүлэх ёстой.\n\nХэрэглэгч бүр бусад бүх хэрэглэгчийн өмнөөс апп шинэчилж болно. Хандалтын тохиргоо болон үйлчилгээг шинэ хэрэглэгчид шилжүүлэх боломжгүй байж болзошгүй."</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"Та шинэ хэрэглэгч нэмбэл тухайн хүн өөрийн профайлыг тохируулах шаардлагатай.\n\nАль ч хэрэглэгч бүх хэрэглэгчийн апп-уудыг шинэчлэх боломжтой."</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"Та шинэ хэрэглэгч нэмбэл тухайн хүн өөрийн профайлыг тохируулах шаардлагатай.\n\nАль ч хэрэглэгч бусад бүх хэрэглэгчийн аппуудыг шинэчлэх боломжтой."</string>
     <string name="user_grant_admin_title" msgid="5157031020083343984">"Энэ хэрэглэгчийг админ болгох уу?"</string>
     <string name="user_grant_admin_message" msgid="1673791931033486709">"Админууд бусад хэрэглэгчид байхгүй тусгай эрхтэй байдаг. Админ нь бүх хэрэглэгчийг удирдах, энэ төхөөрөмжийг шинэчлэх, сэргээх, тохиргоог өөрчлөх, бүх суулгасан аппыг харах болон бусад хэрэглэгчид админы эрх өгөх эсвэл эрхийг нь цуцлах боломжтой."</string>
     <string name="user_grant_admin_button" msgid="5441486731331725756">"Админ болгох"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index f1b1046..2a469b8 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ऑडिओ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ऑडिओ"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"श्रवणयंत्रे"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ऑडिओ"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"श्रवण यंत्रांशी कनेक्ट केले आहे"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ऑडिओशी कनेक्ट केले आहे"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"मीडिया ऑडिओवर कनेक्ट केले"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"प्रोफाइल निवडा"</string>
     <string name="category_personal" msgid="6236798763159385225">"वैयक्तिक"</string>
     <string name="category_work" msgid="4014193632325996115">"कार्य"</string>
+    <string name="category_clone" msgid="1554511758987195974">"क्लोन करा"</string>
     <string name="development_settings_title" msgid="140296922921597393">"डेव्हलपर पर्याय"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"डेव्हलपर पर्याय सुरू करा"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"अ‍ॅप विकासासाठी पर्याय सेट करा"</string>
@@ -548,10 +548,10 @@
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"हा फोन"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"या डिव्हाइसवर प्ले करू शकत नाही"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"स्विच करण्यासाठी खाते अपग्रेड करा"</string>
-    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"येथे डाउनलोड प्ले केले जाऊ शकत नाही"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"येथे डाउनलोड प्ले केले जाऊ शकत नाहीत"</string>
     <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"जाहिरातीनंतर पुन्हा प्रयत्न करा"</string>
     <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"येथे प्ले करण्यासाठी डिव्हाइस सुरू करा"</string>
-    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"प्ले करण्यासाठी डिव्हाइस हे मंजुरी दिलेले नाही"</string>
+    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"डिव्हाइसला प्ले करण्यासाठी मंजुरी नाही"</string>
     <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"हा मीडिया येथे प्ले करू शकत नाही"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"कनेक्‍ट करण्‍यात समस्‍या आली. डिव्हाइस बंद करा आणि नंतर सुरू करा"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"वायर असलेले ऑडिओ डिव्हाइस"</string>
@@ -576,7 +576,7 @@
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"प्रतिबंधित प्रोफाईल"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"नवीन वापरकर्ता जोडायचा?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"अतिरिक्त वापरकर्ते तयार करून तुम्ही इतर लोकांसोबत हे डिव्हाइस शेअर करू शकता. प्रत्येक वापरकर्त्यास त्यांची स्वतःची स्पेस असते, जी ते अ‍ॅप्स, वॉलपेपर आणि यासारख्या गोष्टींनी कस्टमाइझ करू शकतात. वापरकर्ते प्रत्येकाला प्रभावित करणाऱ्या वाय-फाय सारख्या डिव्हाइस सेटिंग्ज अ‍ॅडजस्ट देखील करू शकतात.\n\nतुम्ही एक नवीन वापरकर्ता जोडता, तेव्हा त्या व्यक्तीला त्याची स्पेस सेट अप करण्याची आवश्यकता असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अ‍ॅप्स अपडेट करू शकतो. अ‍ॅक्सेसिबिलिटी सेटिंग्ज आणि सेवा नवीन वापरकर्त्याला कदाचित ट्रान्सफर होणार नाहीत."</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"तुम्ही एक नवीन वापरकर्ता जोडता तेव्हा, त्या व्यक्तीस त्यांचे स्थान सेट करण्याची आवश्यकता असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अ‍ॅप्स अपडेट करू शकतो."</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"तुम्ही एक नवीन वापरकर्ता जोडता, तेव्हा त्या व्यक्तीस त्यांची स्पेस सेट करण्याची आवश्यकता असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अ‍ॅप्स अपडेट करू शकतो."</string>
     <string name="user_grant_admin_title" msgid="5157031020083343984">"या वापरकर्त्याला ॲडमिन करायचे का?"</string>
     <string name="user_grant_admin_message" msgid="1673791931033486709">"ॲडमिनकडे खास विशेषाधिकार आहेत जे इतर वापरकर्त्यांकडे नसतात. ॲडमिन सर्व वापरकर्ते व्यवस्थापित करू शकतो, हे डिव्हाइस अपडेट करू शकतो किंवा रीसेट करू शकतो, सेटिंग्जमध्ये सुधारणा करू शकतो, सर्व इंस्टॉल केलेली अ‍ॅप्स पाहू शकतो आणि इतरांसाठी ॲडमिनचे विशेषाधिकार मंजूर करू शकतो किंवा रद्द करू शकतो."</string>
     <string name="user_grant_admin_button" msgid="5441486731331725756">"ॲडमिन करा"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 0237e87..31cd9f3 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Alat Bantu Dengar"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Disambungkan pada Alat Bantu Dengar"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Disambungkan kepada LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Disambungkan ke audio media"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Pilih profil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Peribadi"</string>
     <string name="category_work" msgid="4014193632325996115">"Tempat Kerja"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Pilihan pembangun"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Dayakan pilihan pembangun"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Tetapkan pilihan untuk pembangunan aplikasi"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 50badf5..18e8961 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD အသံ- <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD အသံ"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"နားကြားကိရိယာ"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"နားကြားကိရိယာနှင့် ချိတ်ဆက်ပြီးပါပြီ"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE အသံနှင့် ချိတ်ဆက်ထားသည်"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"မီဒီယာအသံအား ချိတ်ဆက်ရန်"</string>
@@ -214,8 +213,9 @@
     <item msgid="6946761421234586000">"၄၀၀%"</item>
   </string-array>
     <string name="choose_profile" msgid="343803890897657450">"ပရိုဖိုင်ကို ရွေးရန်"</string>
-    <string name="category_personal" msgid="6236798763159385225">"ကိုယ်ရေး"</string>
+    <string name="category_personal" msgid="6236798763159385225">"ကိုယ်ပိုင်"</string>
     <string name="category_work" msgid="4014193632325996115">"အလုပ်"</string>
+    <string name="category_clone" msgid="1554511758987195974">"ပုံတူပွားရန်"</string>
     <string name="development_settings_title" msgid="140296922921597393">"ဆော့ဝဲလ်ရေးသူ ရွေးစရာများ"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"ဆော့ဖ်ဝဲရေးသူအတွက် ရွေးစရာများကို ဖွင့်ပါ"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"အပလီကေးရှင်းတိုးတက်မှုအတွက် ရွေးချယ်မှုကိုသတ်မှတ်သည်"</string>
@@ -441,7 +441,7 @@
     <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Deuteranomaly (အနီ-အစိမ်း)"</string>
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (အနီ-အစိမ်း)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (အပြာ-အဝါ)"</string>
-    <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"အရောင် အမှန်ပြင်ခြင်း"</string>
+    <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"အရောင်ပြင်ခြင်း"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"အရောင် အမှန်ပြင်ခြင်းသည် အောက်ပါတို့အတွက် အသုံးဝင်နိုင်သည်-&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;အရောင်များကို ပိုမိုမှန်ကန်စွာ ကြည့်ရှုခြင်း&lt;/li&gt; &lt;li&gt;&amp;nbsp;အာရုံစိုက်နိုင်ရန် အရောင်များ ဖယ်ရှားခြင်း&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
@@ -469,7 +469,7 @@
     <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"မကြာမီ စက်ပိတ်သွားနိုင်သည် (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"အားပြည့်ရန် <xliff:g id="TIME">%1$s</xliff:g> လိုသည်"</string>
-    <string name="power_charging_duration" msgid="6127154952524919719">"အားပြည့်ရန် <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> လိုသည်"</string>
+    <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားပြည့်ရန် <xliff:g id="TIME">%2$s</xliff:g> လိုသည်"</string>
     <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားသွင်းခြင်းကို အကောင်းဆုံးပြင်ဆင်ထားသည်"</string>
     <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားသွင်းခြင်းကို အကောင်းဆုံးပြင်ဆင်ထားသည်"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"မသိ"</string>
@@ -672,7 +672,7 @@
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"မူရင်း"</string>
     <string name="turn_screen_on_title" msgid="3266937298097573424">"ဖန်သားပြင် ဖွင့်ခြင်း"</string>
     <string name="allow_turn_screen_on" msgid="6194845766392742639">"ဖန်သားပြင် ဖွင့်ခွင့်ပြုရန်"</string>
-    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"အက်ပ်ကို ဖန်သားပြင် ဖွင့်ခွင့်ပြုနိုင်သည်။ ခွင့်ပြုထားပါက အက်ပ်သည် သင့်ထံမှ တိကျသောရည်ရွယ်ချက်မလိုဘဲ ဖန်သားပြင်ကို အချိန်မရွေး ဖွင့်နိုင်မည်။"</string>
+    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"အက်ပ်ကို ဖန်သားပြင် ဖွင့်ခွင့်ပြုနိုင်သည်။ ခွင့်ပြုထားပါက သင်က တစ်စုံတစ်ခု လုပ်ဆောင်ရန် မရည်ရွယ်သော်လည်း အက်ပ်သည် ဖန်သားပြင်ကို အချိန်မရွေး ဖွင့်နိုင်မည်။"</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g> ထုတ်လွှင့်ခြင်းကို ရပ်မလား။"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ကို ထုတ်လွှင့်သောအခါ (သို့) အထွက်ကို ပြောင်းသောအခါ သင့်လက်ရှိထုတ်လွှင့်ခြင်း ရပ်သွားမည်"</string>
     <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ထုတ်လွှင့်ခြင်း"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index a3c1fa4..b505254 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-lyd: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-lyd"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Høreapparater"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE-lyd"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Koblet til høreapparater"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Koblet til LE-lyd"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Koblet til medielyd"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Velg profil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Personlig"</string>
     <string name="category_work" msgid="4014193632325996115">"Jobb"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Utvikleralternativer"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Slå på utvikleralternativer"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Angi alternativer for apputvikling"</string>
@@ -551,8 +551,8 @@
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Kan ikke spille av nedlastinger her"</string>
     <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Prøv igjen etter annonsen"</string>
     <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Vekk enheten for å spille her"</string>
-    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Enheten er ikke godkjent for avspilling"</string>
-    <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Kan ikke spille dette medieinnholdet her"</string>
+    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Enheten er ikke godkjent"</string>
+    <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Kan ikke spille av dette her"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Tilkoblingsproblemer. Slå enheten av og på igjen"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Lydenhet med kabel"</string>
     <string name="help_label" msgid="3528360748637781274">"Hjelp og tilbakemelding"</string>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index 451f198..fccd8bbe 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -59,9 +59,9 @@
     <item msgid="6421717003037072581">"सधैँ HDCP जाँच प्रयोग गर्नुहोस्"</item>
   </string-array>
   <string-array name="bt_hci_snoop_log_entries">
-    <item msgid="695678520785580527">"असक्षम पारिएको छ"</item>
-    <item msgid="6336372935919715515">"फिल्टर सक्षम पारियो"</item>
-    <item msgid="2779123106632690576">"सक्षम पारिएको छ"</item>
+    <item msgid="695678520785580527">"अफ गरिएको छ"</item>
+    <item msgid="6336372935919715515">"फिल्टर अफ पारियो"</item>
+    <item msgid="2779123106632690576">"अन गरिएको छ"</item>
   </string-array>
   <string-array name="bt_hci_snoop_log_filters_entries">
     <item msgid="195768089203590086">"ACL हेडर मात्र छाड्नुहोस्"</item>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index a60d602..a7990fc 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -111,12 +111,11 @@
     <string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"कन्ट्याक्ट र कल हिस्ट्री सेयर गर्न प्रयोग गरियोस्"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"इन्टरनेट जडान साझेदारी गर्दै"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"टेक्स्ट म्यासेजहरू"</string>
-    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM पहुँच"</string>
+    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM एक्सेस"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD अडियो: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD अडियो"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"श्रवण यन्त्रहरू"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE अडियो"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"श्रवण यन्त्रहरूमा जडान गरियो"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE अडियोमा कनेक्ट गरिएको छ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"मिडिया अडियोसँग जडित"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"प्रोफाइल रोज्नुहोस्"</string>
     <string name="category_personal" msgid="6236798763159385225">"व्यक्तिगत"</string>
     <string name="category_work" msgid="4014193632325996115">"काम"</string>
+    <string name="category_clone" msgid="1554511758987195974">"क्लोन"</string>
     <string name="development_settings_title" msgid="140296922921597393">"विकासकर्ताका विकल्पहरू"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"विकासकर्ता विकल्प सक्रिया गर्नुहोस्"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"एप विकासको लागि विकल्पहरू सेट गर्नुहोस्"</string>
@@ -548,11 +548,11 @@
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"यो फोन"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"यो डिभाइसमा मिडिया प्ले गर्न मिल्दैन"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"आफूले प्रयोग गर्न चाहेको खाता अपग्रेड गर्नुहोस्"</string>
-    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"डाउनलोड गरिएका सामग्री यहाँ प्ले गर्न मिल्दैन"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"डाउनलोड गरिएका सामग्री यसमा प्ले गर्न मिल्दैन"</string>
     <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"विज्ञापन सकिएपछि फेरि प्रयास गर्नुहोस्"</string>
     <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"यो मिडिया यहाँ प्ले गर्न डिभाइस सक्रिय गर्नुहोस्"</string>
-    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"यो डिभाइसलाई मिडिया प्ले गर्ने अनुमोदन दिइएको छैन"</string>
-    <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"यो मिडिया यहाँ प्ले गर्न मिल्दैन"</string>
+    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"यो डिभाइसलाई मिडिया प्ले गर्ने अनुमति छैन"</string>
+    <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"यो मिडिया यसमा प्ले गर्न मिल्दैन"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"जोड्ने क्रममा समस्या भयो। यन्त्रलाई निष्क्रिय पारेर फेरि अन गर्नुहोस्"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"तारयुक्त अडियो यन्त्र"</string>
     <string name="help_label" msgid="3528360748637781274">"मद्दत र प्रतिक्रिया"</string>
@@ -574,7 +574,7 @@
     <string name="user_add_profile_item_summary" msgid="5418602404308968028">"तपाईं आफ्नो खाताबाट एपहरू र सामग्रीहरूको पहुँचलाई प्रतिबन्ध गर्न सक्नुहुन्छ"</string>
     <string name="user_add_user_item_title" msgid="2394272381086965029">"प्रयोगकर्ता"</string>
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"प्रतिबन्धित प्रोफाइल"</string>
-    <string name="user_add_user_title" msgid="5457079143694924885">"नयाँ प्रयोगकर्ता थप्ने हो?"</string>
+    <string name="user_add_user_title" msgid="5457079143694924885">"नयाँ प्रयोगकर्ता हाल्ने हो?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"तपाईं थप प्रयोगकर्ताहरू सिर्जना गरेर ती प्रयोगकर्तालाई यो डिभाइस प्रयोग गर्न दिन सक्नुहुन्छ। हरेक प्रयोगकर्ताको आफ्नै ठाउँ हुन्छ। उनीहरू यो ठाउँमा आफ्नै एप, वालपेपर आदिका लागि प्रयोग गर्न सक्छन्। उनीहरू सबैजनालाई असर पार्ने Wi-Fi जस्ता डिभाइसका सेटिङहरू पनि परिवर्तन गर्न सक्छन्।\n\nतपाईंले नयाँ प्रयोगकर्ता थप्दा उक्त व्यक्तिले आफ्नो ठाउँ सेटअप गर्नु पर्ने हुन्छ।\n\nसबै प्रयोगकर्ता अन्य सबै प्रयोगकर्ताले प्रयोग गर्ने एपहरू अद्यावधिक गर्न सक्छन्। तपाईं थप प्रयोगकर्ताहरू सिर्जना गरेर ती प्रयोगकर्तालाई यो डिभाइस प्रयोग गर्न दिन सक्नुहुन्छ। हरेक प्रयोगकर्ताको आफ्नै ठाउँ हुन्छ। उनीहरू यो ठाउँमा आफ्नै एप, वालपेपर आदिका लागि प्रयोग गर्न सक्छन्। उनीहरू सबैजनालाई असर पार्ने Wi-Fi जस्ता डिभाइसका सेटिङहरू पनि परिवर्तन गर्न सक्छन्।BREAK_0BREAK_1तपाईंले नयाँ प्रयोगकर्ता थप्दा उक्त व्यक्तिले आफ्नो ठाउँ सेटअप गर्नु पर्ने हुन्छ।BREAK_2BREAK_3सबै प्रयोगकर्ता अन्य सबै प्रयोगकर्ताले प्रयोग गर्ने एपहरू अद्यावधिक गर्न सक्छन्। तर पहुँचसम्बन्धी सेटिङ तथा सेवाहरू नयाँ प्रयोगकर्तामा नसर्न सक्छन्।"</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"तपाईंले नयाँ प्रयोगकर्ता थप्नुभयो भने ती प्रयोगकर्ताले आफ्नो स्पेस सेट गर्नु पर्ने हुन्छ।\n\nसबै प्रयोगकर्ताले अरू प्रयोगकर्ताका एपहरू अपडेट गर्न सक्छन्।"</string>
     <string name="user_grant_admin_title" msgid="5157031020083343984">"यी प्रयोगकर्तालाई एड्मिन बनाउने हो?"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 4a8dfb0..ee02217 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hoortoestellen"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Verbonden met hoortoestellen"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Verbonden met LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Verbonden met audio van medium"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Profiel kiezen"</string>
     <string name="category_personal" msgid="6236798763159385225">"Persoonlijk"</string>
     <string name="category_work" msgid="4014193632325996115">"Werk"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klonen"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Ontwikkelaarsopties"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Opties voor ontwikkelaars aanzetten"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Opties instellen voor appontwikkeling"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 3c4c67f..5795abe 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ଅଡିଓ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ଅଡିଓ"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"ଶ୍ରବଣ ଯନ୍ତ୍ର"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ଅଡିଓ"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ଶ୍ରବଣ ଯନ୍ତ୍ରକୁ ସଂଯୋଗ ହୋଇଛି"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ଅଡିଓ ସହ କନେକ୍ଟ କରାଯାଇଛି"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"ମିଡିଆ ଅଡିଓ ସହ ସଂଯୁକ୍ତ"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"ପ୍ରୋଫାଇଲ୍‌ ବାଛନ୍ତୁ"</string>
     <string name="category_personal" msgid="6236798763159385225">"ବ୍ୟକ୍ତିଗତ"</string>
     <string name="category_work" msgid="4014193632325996115">"ୱାର୍କ"</string>
+    <string name="category_clone" msgid="1554511758987195974">"କ୍ଲୋନ"</string>
     <string name="development_settings_title" msgid="140296922921597393">"ଡେଭଲପରଙ୍କ ପାଇଁ ବିକଳ୍ପଗୁଡ଼ିକ"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"ଡେଭଲପର୍‌ ବିକଳ୍ପଗୁଡ଼ିକ ସକ୍ଷମ କରନ୍ତୁ"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"ଆପ୍‌ର ବିକାଶ ପାଇଁ ବିକଳ୍ପମାନ ସେଟ୍‌ କରନ୍ତୁ"</string>
@@ -270,10 +270,10 @@
     <string name="debug_networking_category" msgid="6829757985772659599">"ନେଟ୍‌ୱର୍କିଙ୍ଗ"</string>
     <string name="wifi_display_certification" msgid="1805579519992520381">"ୱାୟରଲେସ୍‌ ଡିସ୍‌ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍"</string>
     <string name="wifi_verbose_logging" msgid="1785910450009679371">"ୱାଇ-ଫାଇ ଭର୍ବୋସ୍‌ ଲଗିଙ୍ଗ ସକ୍ଷମ କରନ୍ତୁ"</string>
-    <string name="wifi_scan_throttling" msgid="2985624788509913617">"ୱାଇ-ଫାଇ ସ୍କାନ୍ ନିୟନ୍ତ୍ରଣ"</string>
-    <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"ୱାଇ-ଫାଇ ଅଣ-ଅବିରତ MAC ରେଣ୍ଡମାଇଜେସନ୍"</string>
-    <string name="mobile_data_always_on" msgid="8275958101875563572">"ମୋବାଇଲ୍‌ ଡାଟା ସର୍ବଦା ସକ୍ରିୟ"</string>
-    <string name="tethering_hardware_offload" msgid="4116053719006939161">"ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର ଆକ୍ସିଲିରେସନ୍"</string>
+    <string name="wifi_scan_throttling" msgid="2985624788509913617">"ୱାଇ-ଫାଇ ସ୍କାନ ନିୟନ୍ତ୍ରଣ"</string>
+    <string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"ୱାଇ-ଫାଇ ଅଣ-ଅବିରତ MAC ରେଣ୍ଡମାଇଜେସନ"</string>
+    <string name="mobile_data_always_on" msgid="8275958101875563572">"ମୋବାଇଲ ଡାଟା ସର୍ବଦା ସକ୍ରିୟ"</string>
+    <string name="tethering_hardware_offload" msgid="4116053719006939161">"ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର ଆକ୍ସିଲିରେସନ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"ବ୍ଲୁଟୂଥ ଡିଭାଇସଗୁଡ଼ିକୁ ନାମ ବିନା ଦେଖାନ୍ତୁ"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"ପୂର୍ଣ୍ଣ ଭଲ୍ୟୁମ୍‌ ଅକ୍ଷମ କରନ୍ତୁ"</string>
     <string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"ଗାବେଲ୍‌ଡୋର୍ସ ସକ୍ରିୟ କରନ୍ତୁ"</string>
@@ -302,8 +302,8 @@
     <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"କନେକ୍ଟ କରିହେଲା ନାହିଁ"</string>
     <string name="wifi_display_certification_summary" msgid="8111151348106907513">"ୱେୟାରଲେସ୍‌ ଡିସ୍‌ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍ ପାଇଁ ବିକଳ୍ପ ଦେଖାନ୍ତୁ"</string>
     <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"ୱାଇ-ଫାଇ ଲଗିଙ୍ଗ ସ୍ତର ବଢ଼ାନ୍ତୁ, ୱାଇ-ଫାଇ ପିକର୍‌ରେ ପ୍ରତି SSID RSSI ଦେଖାନ୍ତୁ"</string>
-    <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ବ୍ୟାଟେରୀ ଖର୍ଚ୍ଚ କମ୍ ଏବଂ ନେଟ୍‌ୱାର୍କ କାର୍ଯ୍ୟକ୍ଷମତା ଉନ୍ନତ କରିଥାଏ"</string>
-    <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"ଯେତେବେଳେ ଏହି ମୋଡ୍ ସକ୍ଷମ କରାଯାଏ, ପ୍ରତ୍ୟେକ ଥର MAC ରେଣ୍ଡୋମାଇଜେସନ୍ ସକ୍ଷମ ଥିବା କୌଣସି ନେଟୱାର୍କ ସହ ଏହି ଡିଭାଇସ୍ ସଂଯୋଗ ହେଲେ ଏହାର MAC ଠିକଣା ବଦଳିପାରେ।"</string>
+    <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ବେଟେରୀ ଖର୍ଚ୍ଚକୁ କମ ଏବଂ ନେଟୱାର୍କ କାର୍ଯ୍ୟକ୍ଷମତାକୁ ଉନ୍ନତ କରିଥାଏ"</string>
+    <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"ଯେତେବେଳେ ଏହି ମୋଡକୁ ସକ୍ଷମ କରାଯାଏ, ପ୍ରତ୍ୟେକ ଥର MAC ରେଣ୍ଡମାଇଜେସନ ସକ୍ଷମ ଥିବା କୌଣସି ନେଟୱାର୍କ ସହ ଏହି ଡିଭାଇସ ସଂଯୋଗ ହେଲେ ଏହାର MAC ଠିକଣା ବଦଳିପାରେ।"</string>
     <string name="wifi_metered_label" msgid="8737187690304098638">"ମପାଯାଉଥିବା"</string>
     <string name="wifi_unmetered_label" msgid="6174142840934095093">"ମପାଯାଉନଥିବା"</string>
     <string name="select_logd_size_title" msgid="1604578195914595173">"ଲଗର୍‌ ବଫର୍‌ ସାଇଜ୍"</string>
@@ -317,8 +317,8 @@
     <string name="allow_mock_location" msgid="2102650981552527884">"ନକଲି ଲୋକେଶନ୍‌ର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="allow_mock_location_summary" msgid="179780881081354579">"ନକଲି ଲୋକେଶନ୍‌ର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="debug_view_attributes" msgid="3539609843984208216">"ବିଶେଷତା ଯାଞ୍ଚ ଭ୍ୟୁକୁ ସକ୍ଷମ କରନ୍ତୁ"</string>
-    <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"ୱାଇ-ଫାଇ ସକ୍ରିୟ ଥିଲେ ମଧ୍ୟ ସର୍ବଦା ମୋବାଇଲ୍‌ ଡାଟାକୁ ସକ୍ରିୟ ରଖନ୍ତୁ (ଦ୍ରୁତ ନେଟ୍‌ୱର୍କ ସ୍ୱିଚିଙ୍ଗ ପାଇଁ)।"</string>
-    <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"ଯଦି ଉପଲବ୍ଧ ଥାଏ, ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର୍‌ ଆକ୍ସିଲିରେସନ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"ୱାଇ-ଫାଇ ସକ୍ରିୟ ଥିଲେ ମଧ୍ୟ ସର୍ବଦା ମୋବାଇଲ ଡାଟାକୁ ସକ୍ରିୟ ରଖନ୍ତୁ (ଦ୍ରୁତ ନେଟୱାର୍କ ସ୍ୱିଚିଂ ପାଇଁ)।"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"ଯଦି ଉପଲବ୍ଧ ଥାଏ, ତେବେ ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର ଆକ୍ସିଲିରେସନକୁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="adb_warning_title" msgid="7708653449506485728">"USB ଡିବଗିଙ୍ଗ କରିବେ?"</string>
     <string name="adb_warning_message" msgid="8145270656419669221">"USB ଡିବଗିଂ କେବଳ ଡେଭଲପମେଣ୍ଟ ଉଦ୍ଦେଶ୍ୟ ପାଇଁ ଉଦ୍ଦିଷ୍ଟ ଅଟେ। ଆପଣଙ୍କ କମ୍ପ୍ୟୁଟର ଏବଂ ଡିଭାଇସ୍‌ ମଧ୍ୟରେ ଡାଟା କପି କରିବାକୁ, ବିନା ବିଜ୍ଞପ୍ତିରେ ଆପଣଙ୍କ ଡିଭାଇସରେ ଆପସ୍‌ ସଂସ୍ଥାପନ କରିବାକୁ, ଏବଂ ଲଗ୍‌ ଡାଟା ପଢିବାକୁ ଏହା ବ୍ୟବହାର କରନ୍ତୁ।"</string>
     <string name="adbwifi_warning_title" msgid="727104571653031865">"ୱାୟାରଲେସ୍ ଡିବଗିଂ ପାଇଁ ଅନୁମତି ଦେବେ?"</string>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index 533788a..4225e02 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -200,7 +200,7 @@
   </string-array>
   <string-array name="select_logpersist_summaries">
     <item msgid="97587758561106269">"ਬੰਦ"</item>
-    <item msgid="7126170197336963369">"ਸਭ ਲੌਗ ਬਫ਼ਰ"</item>
+    <item msgid="7126170197336963369">"ਸਾਰੇ ਲੌਗ ਬਫ਼ਰ"</item>
     <item msgid="7167543126036181392">"ਸਭ ਪਰ ਰੇਡੀਓ ਲੌਗ ਬਫ਼ਰ"</item>
     <item msgid="5135340178556563979">"ਸਿਰਫ਼ ਕਰਨਲ ਲੌਗ ਬਫ਼ਰ"</item>
   </string-array>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index ce2617a..7472e5d 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ਆਡੀਓ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ਆਡੀਓ"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"ਸੁਣਨ ਦੇ ਸਾਧਨ"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ਆਡੀਓ"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ਸੁਣਨ ਦੇ ਸਾਧਨਾਂ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ਆਡੀਓ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"ਮੀਡੀਆ  ਆਡੀਓ  ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"ਪ੍ਰੋਫਾਈਲ ਚੁਣੋ"</string>
     <string name="category_personal" msgid="6236798763159385225">"ਨਿੱਜੀ"</string>
     <string name="category_work" msgid="4014193632325996115">"ਕੰਮ ਸੰਬੰਧੀ"</string>
+    <string name="category_clone" msgid="1554511758987195974">"ਕਲੋਨ ਕਰੋ"</string>
     <string name="development_settings_title" msgid="140296922921597393">"ਵਿਕਾਸਕਾਰ ਚੋਣਾਂ"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"ਵਿਕਾਸਕਾਰ ਵਿਕਲਪਾਂ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"ਐਪ ਵਿਕਾਸ ਲਈ ਚੋਣਾਂ ਸੈੱਟ ਕਰੋ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index bcf7f24..8821bdc 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Dźwięk HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Dźwięk HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Aparaty słuchowe"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Połączono z aparatami słuchowymi"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Połączono z LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Połączono z funkcją audio multimediów"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Anuluj"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Sparowanie powoduje przyznanie dostępu do historii połączeń i Twoich kontaktów w trakcie połączenia."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Nie udało się sparować z urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Nie udało się sparować z urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ze względu na błędny kod PIN lub klucz."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Nieudane parowanie z: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Błędny kod PIN lub klucz dostępu."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Nie można skomunikować się z urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Powiązanie odrzucone przez urządzenie <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Komputer"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Wybierz profil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Osobiste"</string>
     <string name="category_work" msgid="4014193632325996115">"Służbowe"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opcje programisty"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Włącz opcje programisty"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Ustaw opcje związane z programowaniem aplikacji."</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index f937554..15331c3 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Áudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Áudio HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Aparelhos auditivos"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Conectado a aparelhos auditivos"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Conectado ao perfil Áudio de baixa energia"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Conectado ao áudio da mídia"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"O pareamento dá acesso a seus contatos e ao histórico de ligações quando estiver conectado."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> por causa de um PIN ou senha incorretos."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: PIN ou senha incorretos."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Não é possível se comunicar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Pareamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Computador"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Escolher perfil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Pessoal"</string>
     <string name="category_work" msgid="4014193632325996115">"Trabalho"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opções do desenvolvedor"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Ativar opções do desenvolvedor"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Define as opções para o desenvolvimento do app"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 441fe55..08a4422 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Áudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Áudio HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Aparelhos auditivos"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Ligado a aparelhos auditivos"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Ligado a LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Ligado ao áudio de multimédia"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"A sincronização concede acesso aos seus contactos e ao histórico de chamadas quando tem uma ligação estabelecida."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Não foi possível sincronizar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Não foi possível sincronizar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> devido a PIN ou token de acesso incorreto."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Não foi possível sincronizar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: PIN ou chave de acesso errado."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Não é possível comunicar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Emparelhamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Computador"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Escolher perfil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Pessoal"</string>
     <string name="category_work" msgid="4014193632325996115">"Trabalho"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opções de programador"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Ativar as opções de programador"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Definir opções de desenvolvimento da aplicação"</string>
@@ -516,7 +516,7 @@
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Não registado"</string>
     <string name="status_unavailable" msgid="5279036186589861608">"Indisponível"</string>
     <string name="wifi_status_mac_randomized" msgid="466382542497832189">"O MAC é aleatório."</string>
-    <string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0 dispositivo ligados}=1{1 dispositivo ligado}other{# dispositivos ligados}}"</string>
+    <string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0 dispositivo ligado}=1{1 dispositivo ligado}other{# dispositivos ligados}}"</string>
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Mais tempo."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Menos tempo."</string>
     <string name="cancel" msgid="5665114069455378395">"Cancelar"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index f937554..15331c3 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Áudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Áudio HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Aparelhos auditivos"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Conectado a aparelhos auditivos"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Conectado ao perfil Áudio de baixa energia"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Conectado ao áudio da mídia"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"O pareamento dá acesso a seus contatos e ao histórico de ligações quando estiver conectado."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> por causa de um PIN ou senha incorretos."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Não foi possível parear com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: PIN ou senha incorretos."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Não é possível se comunicar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Pareamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Computador"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Escolher perfil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Pessoal"</string>
     <string name="category_work" msgid="4014193632325996115">"Trabalho"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clone"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opções do desenvolvedor"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Ativar opções do desenvolvedor"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Define as opções para o desenvolvimento do app"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 1803a87..edad3bd 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Aparate auditive"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Conectat la aparatul auditiv"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Conectat la LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Conectat la profilul pentru conținut media audio"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Anulează"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Asocierea dispozitivelor îți permite accesul la persoanele de contact și la istoricul apelurilor când dispozitivul este conectat."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Nu s-a putut împerechea cu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Nu s-a putut asocia cu <xliff:g id="DEVICE_NAME">%1$s</xliff:g> din cauza unui cod PIN sau a unei chei de acces incorecte."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Nu s-a putut asocia cu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: cod PIN sau cheie de acces incorectă."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Nu se poate comunica cu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Împerechere respinsă de <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Computer"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Alege un profil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Personal"</string>
     <string name="category_work" msgid="4014193632325996115">"Serviciu"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Clonează"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opțiuni pentru dezvoltatori"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Activează opțiunile pentru dezvoltatori"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Setează opțiuni pentru dezvoltarea aplicației"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 3b6956c..6b5a4a0 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -59,7 +59,7 @@
     <string name="wifi_check_password_try_again" msgid="8817789642851605628">"Возможно, вы указали неверный пароль. Повторите попытку."</string>
     <string name="wifi_not_in_range" msgid="1541760821805777772">"Недоступна"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Подключение не будет выполняться автоматически"</string>
-    <string name="wifi_no_internet" msgid="1774198889176926299">"Без доступа к Интернету"</string>
+    <string name="wifi_no_internet" msgid="1774198889176926299">"Без доступа к интернету"</string>
     <string name="saved_network" msgid="7143698034077223645">"Сохранено: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Автоматически подключено к %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Автоматически подключено через автора рейтинга сетей"</string>
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD Audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD Audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слуховые аппараты"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Слуховой аппарат подключен"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Подключено к LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Подключено к мультимедийному аудиоустройству"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Отмена"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Установление соединения обеспечивает доступ к вашим контактам и журналу звонков при подключении."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Не удалось подключиться к устройству \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Устройство \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" не подключено: неверный PIN-код или пароль."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"\"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" не подключается: неверный PIN-код или пароль."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Не удается установить соединение с устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> не разрешает подключение."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Компьютер"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Выбор профиля"</string>
     <string name="category_personal" msgid="6236798763159385225">"Личный профиль"</string>
     <string name="category_work" msgid="4014193632325996115">"Рабочий профиль"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Клон"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Для разработчиков"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Включить параметры для разработчиков"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Настройка параметров для разработчиков"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 5c00c74..1dbe5a0 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ශ්‍රව්‍යය: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ශ්‍රව්‍යය"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"ශ්‍රවණාධාරක"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ශ්‍රව්‍ය"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"ශ්‍රවණාධාරක වෙත සම්බන්ධ කළා"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ශ්‍රව්‍ය වෙත සම්බන්ධ විය"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"මාධ්‍ය ශ්‍රව්‍යට සම්බන්ධ විය"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"පැතිකඩ තෝරන්න"</string>
     <string name="category_personal" msgid="6236798763159385225">"පෞද්ගලික"</string>
     <string name="category_work" msgid="4014193632325996115">"කාර්යාලය"</string>
+    <string name="category_clone" msgid="1554511758987195974">"ක්ලෝන කරන්න"</string>
     <string name="development_settings_title" msgid="140296922921597393">"වර්ධක විකල්ප"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"සංවර්ධක විකල්ප සබල කිරීම"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"යෙදුම් සංවර්ධනයට විකල්ප සකසන්න"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 6702d17..b29d0ed 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD zvuk: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD zvuk"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Načúvadlá"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Pripojené k načúvadlám"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Pripojené k systému LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Pripojené ku zvukovému médiu"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Zrušiť"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Párovaním udelíte zariadeniam po pripojení prístup k svojim kontaktom a histórii hovorov."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Nepodarilo sa spárovať so zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"So zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g> sa nespárovalo pre nesprávny kód PIN alebo prístupový kľúč."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Nespárované so zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: nesprávny PIN či prístupový kľúč."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"So zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g> nie je možné komunikovať."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Párovanie odmietnuté zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Počítač"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Výber profilu"</string>
     <string name="category_personal" msgid="6236798763159385225">"Osobné"</string>
     <string name="category_work" msgid="4014193632325996115">"Pracovné"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klonovanie"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Pre vývojárov"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Povolenie možností vývojára"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Možnosti nastavenia vývoja aplikácií"</string>
@@ -671,7 +671,7 @@
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Vyberte rozloženie klávesnice"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Predvolené"</string>
     <string name="turn_screen_on_title" msgid="3266937298097573424">"Zapínanie obrazovky"</string>
-    <string name="allow_turn_screen_on" msgid="6194845766392742639">"Povolenie zapínania obrazovky"</string>
+    <string name="allow_turn_screen_on" msgid="6194845766392742639">"Povoliť zapínanie obrazovky"</string>
     <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Povoľte aplikácii zapínať obrazovku. Ak to urobíte, aplikácia bude môcť kedykoľvek zapínať obrazovku, a to aj vtedy, keď to nebudete mať v úmysle."</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Chcete zastaviť vysielanie aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Ak vysielate aplikáciu <xliff:g id="SWITCHAPP">%1$s</xliff:g> alebo zmeníte výstup, aktuálne vysielanie bude zastavené"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index a504fe9..6b3f63e 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Zvok visoke kakovosti: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Zvok visoke kakovosti"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Slušni pripomočki"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE zvok"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Povezava s slušnimi pripomočki je vzpostavljena"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Povezano s profilom LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Povezan s profilom za predstavnostni zvok"</string>
@@ -215,7 +214,8 @@
   </string-array>
     <string name="choose_profile" msgid="343803890897657450">"Izbira profila"</string>
     <string name="category_personal" msgid="6236798763159385225">"Osebno"</string>
-    <string name="category_work" msgid="4014193632325996115">"Služba"</string>
+    <string name="category_work" msgid="4014193632325996115">"Delo"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Možnosti za razvijalce"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Omogočanje možnosti za razvijalce"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Nastavi možnosti za razvoj aplikacij"</string>
@@ -516,7 +516,7 @@
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Ni registrirana"</string>
     <string name="status_unavailable" msgid="5279036186589861608">"Ni na voljo"</string>
     <string name="wifi_status_mac_randomized" msgid="466382542497832189">"Naslov MAC je naključno izbran"</string>
-    <string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0 naprav ni povezanih}=1{1 naprava je povezana}one{# naprava je povezana}two{# napravi sta povezani}few{# naprave so povezane}other{# naprav je povezanih}}"</string>
+    <string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{0 naprav ni povezanih.}=1{1 naprava je povezana.}one{# naprava je povezana.}two{# napravi sta povezani.}few{# naprave so povezane.}other{# naprav je povezanih.}}"</string>
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Daljši čas."</string>
     <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Krajši čas."</string>
     <string name="cancel" msgid="5665114069455378395">"Prekliči"</string>
@@ -548,9 +548,9 @@
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ta telefon"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Ni mogoče predvajati v tej napravi."</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Za preklop je potrebna nadgradnja računa"</string>
-    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tukaj ni mogoče predvajati prenosov"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Prenosov tu ni mogoče predvajati"</string>
     <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Poskusite znova po oglasu"</string>
-    <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Zbudite napravo, če želite predvajati tukaj."</string>
+    <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Zbudite napravo za predvajanje tu"</string>
     <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Naprava ni odobrena za predvajanje."</string>
     <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Te predstavnosti ni mogoče predvajati tukaj."</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Težava pri povezovanju. Napravo izklopite in znova vklopite."</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 70f463c..7d43c0a1 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Audio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Audio HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Aparatet e dëgjimit"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Lidhur me aparatet e dëgjimit"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"U lidh me audion LE"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"U lidh me audion e medias"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Zgjidh profilin"</string>
     <string name="category_personal" msgid="6236798763159385225">"Personale"</string>
     <string name="category_work" msgid="4014193632325996115">"Punë"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klono"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Opsionet e zhvilluesit"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Aktivizo opsionet e zhvilluesit"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Cakto opsionet për zhvillimin e aplikacionit"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 38d7bca..3471646 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -60,7 +60,7 @@
     <string name="wifi_not_in_range" msgid="1541760821805777772">"Није у опсегу"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Аутоматско повезивање није успело"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Нема приступа интернету"</string>
-    <string name="saved_network" msgid="7143698034077223645">"Сачувао/ла је <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="saved_network" msgid="7143698034077223645">"Чува <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"Аутоматски повезано преко %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Аутоматски повезано преко добављача оцене мреже"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"Повезано преко: <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD звук: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD звук"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слушни апарати"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Повезано са слушним апаратима"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Повезано са LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Повезано са звуком медија"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Откажи"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Упаривање омогућава приступ контактима и историји позива након повезивања."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Упаривање са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g> није могуће."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Упаривање са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g> није могуће због нетачног PIN-а или приступног кода."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Упаривање са <xliff:g id="DEVICE_NAME">%1$s</xliff:g> није могуће због нетачног PIN-а или приступног кода."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Није могуће комуницирати са уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> је одбио/ла упаривање"</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Рачунар"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Изаберите профил"</string>
     <string name="category_personal" msgid="6236798763159385225">"Лично"</string>
     <string name="category_work" msgid="4014193632325996115">"Посао"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Клонирано"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Опције за програмере"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Омогући опције за програмере"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Подешавање опција за програмирање апликације"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 66d2193..c264192 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-ljud: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-ljud"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Hörapparater"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Ansluten till hörapparater"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Ansluten till LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Ansluten till medialjud"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Avbryt"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Om du kopplar enheten får du tillgång till dina kontakter och din samtalshistorik när du är ansluten."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Det gick inte att koppla till <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Det gick inte att koppla till <xliff:g id="DEVICE_NAME">%1$s</xliff:g> på grund av en felaktig PIN-kod eller nyckel."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Parkoppling med <xliff:g id="DEVICE_NAME">%1$s</xliff:g> misslyckades på grund av fel PIN-kod eller nyckel."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Det går inte att kommunicera med <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Parkoppling avvisad av <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Dator"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Välj profil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Privat"</string>
     <string name="category_work" msgid="4014193632325996115">"Jobb"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Utvecklaralternativ"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Aktivera utvecklaralternativ"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Ange alternativ för apputveckling"</string>
@@ -546,12 +546,12 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Den här telefonen"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Den här surfplattan"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Den här telefonen"</string>
-    <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Det går inte att spela upp denna enhet"</string>
+    <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan inte spelas på denna enhet"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Uppgradera kontot för att byta"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Det går inte att spela upp nedladdningar här"</string>
     <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Försök igen efter annonsen"</string>
     <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Väck enheten för att spela upp här"</string>
-    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Enheten har inte godkänts för uppspelning"</string>
+    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Enheten är inte godkänd"</string>
     <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Det går inte att spela upp detta här"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Det gick inte att ansluta. Stäng av enheten och slå på den igen"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Ljudenhet med kabelanslutning"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index c95dd61..e104582 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Sauti ya HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Sauti ya HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Vifaa vya Kusaidia Kusikia"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Imeunganishwa kwenye Vifaa vya Kusaidia Kusikia"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Imeunganishwa kwenye LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Imeunganishwa kwenye sikika ya njia ya mawasiliano"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Chagua wasifu"</string>
     <string name="category_personal" msgid="6236798763159385225">"Binafsi"</string>
     <string name="category_work" msgid="4014193632325996115">"Ya Kazini"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Kloni"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Chaguo za wasanidi"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Washa chaguo za wasanidi programu"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Weka chaguo kwa ajili ya maendeleo ya programu"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 9a1a21a..33cde5b 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ஆடியோ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ஆடியோ"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"செவித்துணை கருவிகள்"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ஆடியோ"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"செவித்துணை கருவிகளுடன் இணைக்கப்பட்டது"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ஆடியோவுடன் இணைக்கப்பட்டுள்ளது"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"மீடியா ஆடியோவுடன் இணைக்கப்பட்டது"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"சுயவிவரத்தைத் தேர்வு செய்க"</string>
     <string name="category_personal" msgid="6236798763159385225">"தனிப்பட்டவை"</string>
     <string name="category_work" msgid="4014193632325996115">"பணியிடம்"</string>
+    <string name="category_clone" msgid="1554511758987195974">"குளோன்"</string>
     <string name="development_settings_title" msgid="140296922921597393">"டெவெலப்பர் விருப்பங்கள்"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"டெவெலப்பர் விருப்பங்களை இயக்கு"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"ஆப்ஸின் மேம்பாட்டிற்காக விருப்பங்களை அமை"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index cd0b983..fcdad54 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ఆడియో: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ఆడియో"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"వినికిడి మద్దతు ఉపకరణాలు"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE ఆడియో"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"వినికిడి మద్దతు ఉపకరణాలకు కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE ఆడియోకు కనెక్ట్ చేయబడింది"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"మీడియా ఆడియోకు కనెక్ట్ చేయబడింది"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"ప్రొఫైల్‌ను ఎంచుకోండి"</string>
     <string name="category_personal" msgid="6236798763159385225">"వ్యక్తిగతం"</string>
     <string name="category_work" msgid="4014193632325996115">"ఆఫీస్"</string>
+    <string name="category_clone" msgid="1554511758987195974">"క్లోన్ చేయండి"</string>
     <string name="development_settings_title" msgid="140296922921597393">"డెవలపర్ ఆప్షన్‌లు"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"డెవలపర్ ఎంపికలను ప్రారంభించండి"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"యాప్‌ అభివృద్ధి కోసం ఎంపికలను సెట్ చేయండి"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 1bbfb6d..6595c6b 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"เสียง HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"เสียง HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"เครื่องช่วยฟัง"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"เชื่อมต่อกับเครื่องช่วยฟังแล้ว"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"เชื่อมต่อกับ LE Audio แล้ว"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"เชื่อมต่อกับระบบเสียงของสื่อแล้ว"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"เลือกโปรไฟล์"</string>
     <string name="category_personal" msgid="6236798763159385225">"ส่วนตัว"</string>
     <string name="category_work" msgid="4014193632325996115">"งาน"</string>
+    <string name="category_clone" msgid="1554511758987195974">"โคลน"</string>
     <string name="development_settings_title" msgid="140296922921597393">"ตัวเลือกสำหรับนักพัฒนาแอป"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"เปิดใช้ตัวเลือกสำหรับนักพัฒนาแอป"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"ตั้งค่าตัวเลือกสำหรับการพัฒนาแอปพลิเคชัน"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 75da2c7..b6616aa 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Mga Hearing Aid"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Nakakonekta sa Mga Hearing Aid"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Nakakonekta sa LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Konektado sa media audio"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Pumili ng profile"</string>
     <string name="category_personal" msgid="6236798763159385225">"Personal"</string>
     <string name="category_work" msgid="4014193632325996115">"Trabaho"</string>
+    <string name="category_clone" msgid="1554511758987195974">"I-clone"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Mga opsyon ng developer"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"I-enable ang mga opsyon ng developer"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Magtakda ng mga pagpipilian para sa pagbuo ng app"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 10414da..2d9ca2b 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ses: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ses"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"İşitme Cihazları"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"İşitme Cihazlarına Bağlandı"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE Audio\'ya bağlandı"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Medya sesine bağlanıldı"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Profil seçin"</string>
     <string name="category_personal" msgid="6236798763159385225">"Kişisel"</string>
     <string name="category_work" msgid="4014193632325996115">"İş"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Geliştirici seçenekleri"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Geliştirici seçeneklerini etkinleştir"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Uygulama geliştirme için seçenekleri ayarla"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 6404e3a..9a0c136 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-аудіо: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-аудіо"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Слухові апарати"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Підключено до слухових апаратів"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Підключено до LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Підключено до аудіоджерела"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Скасувати"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Якщо ви під’єднаєте інший пристрій, він матиме доступ до ваших контактів та історії дзвінків."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Не вдалося створити пару з пристроєм <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Помилка підключення до пристрою <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: неправильний PIN-код чи ключ доступу."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Не підключено пристрій <xliff:g id="DEVICE_NAME">%1$s</xliff:g>: неправильний PIN-код чи ключ доступу."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Неможливо зв’язатися з пристроєм <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Створ. пари відхилено <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Комп’ютер"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Вибрати профіль"</string>
     <string name="category_personal" msgid="6236798763159385225">"Особисте"</string>
     <string name="category_work" msgid="4014193632325996115">"Робоче"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Копія профілю"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Параметри розробника"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Увімкнути параметри розробника"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Установити параметри для розробки програми"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 3e8700d..4991022 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"‏HD آڈیو: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"‏HD آڈیو"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"سماعتی آلات"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"‏LE آڈیو"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"سماعتی آلات سے منسلک ہے"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"‏LE آڈیو سے منسلک ہے"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"میڈیا آڈیو سے مربوط"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"پروفائل منتخب کریں"</string>
     <string name="category_personal" msgid="6236798763159385225">"ذاتی"</string>
     <string name="category_work" msgid="4014193632325996115">"دفتر"</string>
+    <string name="category_clone" msgid="1554511758987195974">"کلون کریں"</string>
     <string name="development_settings_title" msgid="140296922921597393">"ڈویلپر کے اختیارات"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"ڈویلپر کے اختیارات فعال کریں"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"ایپ ڈویلپمنٹ کیلئے اختیارات سیٹ کریں"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 67a5ec8..d4d0bbc 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Eshitish apparatlari"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Eshitish apparatlariga ulangan"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE audioga ulandi"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Audio qurilmasiga ulangan"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Profilni tanlang"</string>
     <string name="category_personal" msgid="6236798763159385225">"Shaxsiy"</string>
     <string name="category_work" msgid="4014193632325996115">"Ish"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Nusxalash"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Dasturchi sozlamalari"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Dasturchi sozlamalarini yoqish"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Ilova dasturlash moslamalari"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 4a0f3be..1609d92 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Âm thanh HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Âm thanh HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Thiết bị trợ thính"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"Âm thanh năng lượng thấp"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Đã kết nối với Thiết bị trợ thính"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Đã kết nối với âm thanh LE"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Đã kết nối với âm thanh nội dung nghe nhìn"</string>
@@ -142,7 +141,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Hủy"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Ghép nối giúp bạn có thể truy cập danh bạ và nhật ký cuộc gọi của mình khi được kết nối."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Không thể ghép nối với <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Không thể ghép nối với <xliff:g id="DEVICE_NAME">%1$s</xliff:g> do mã PIN hoặc mã xác nhận không đúng."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Không thể ghép nối với <xliff:g id="DEVICE_NAME">%1$s</xliff:g> do mã PIN hoặc mã truy cập không đúng."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Không thể kết nối với <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Ghép nối bị <xliff:g id="DEVICE_NAME">%1$s</xliff:g> từ chối."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Máy tính"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Chọn hồ sơ"</string>
     <string name="category_personal" msgid="6236798763159385225">"Cá nhân"</string>
     <string name="category_work" msgid="4014193632325996115">"Công việc"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Nhân bản"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Tùy chọn cho nhà phát triển"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Bật tùy chọn nhà phát triển"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Đặt tùy chọn cho phát triển ứng dụng"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index d51ecb5..9815c90 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -111,12 +111,11 @@
     <string name="bluetooth_profile_pbap_summary" msgid="6466456791354759132">"用于联系人信息和通话记录分享"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"共享互联网连接"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"短信"</string>
-    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM 卡存取权限"</string>
+    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM 卡访问权限"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD 音频:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD 音频"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"助听器"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE 音频"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"已连接到助听器"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"已连接到 LE 音频"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"已连接到媒体音频"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"选择个人资料"</string>
     <string name="category_personal" msgid="6236798763159385225">"个人"</string>
     <string name="category_work" msgid="4014193632325996115">"工作"</string>
+    <string name="category_clone" msgid="1554511758987195974">"克隆"</string>
     <string name="development_settings_title" msgid="140296922921597393">"开发者选项"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"启用开发者选项"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"设置应用开发选项"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 177cebc..1412dcd 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"高清音訊:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"高清音訊"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"助聽器"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"已連接助聽器"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"已連接 LE Audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"已連接媒體音頻裝置"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"選擇設定檔"</string>
     <string name="category_personal" msgid="6236798763159385225">"個人"</string>
     <string name="category_work" msgid="4014193632325996115">"工作"</string>
+    <string name="category_clone" msgid="1554511758987195974">"複製"</string>
     <string name="development_settings_title" msgid="140296922921597393">"開發人員選項"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"啟用開發人員選項"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"設定應用程式開發選項"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 843c1bf..2a04ea9 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD 高解析音訊:<xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD 高解析音訊"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"助聽器"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE Audio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"已連接到助聽器"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"已連上 LE audio"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"連接至媒體音訊"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"選擇設定檔"</string>
     <string name="category_personal" msgid="6236798763159385225">"個人"</string>
     <string name="category_work" msgid="4014193632325996115">"工作"</string>
+    <string name="category_clone" msgid="1554511758987195974">"複製"</string>
     <string name="development_settings_title" msgid="140296922921597393">"開發人員選項"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"啟用開發人員選項"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"設定應用程式開發選項"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 5ff1917..80f4d50 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -115,8 +115,7 @@
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Umsindo we-HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"Umsindo we-HD"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"Izinsiza zokuzwa"</string>
-    <!-- no translation found for bluetooth_profile_le_audio (6125267378720026515) -->
-    <skip />
+    <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"Umsindo we-LE"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"Kuxhumeke kwizinsiza zokuzwa"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"Kuxhunywe kumsindo we-LE"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"Ixhume emsindweni wemidiya"</string>
@@ -216,6 +215,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Khetha iphrofayela"</string>
     <string name="category_personal" msgid="6236798763159385225">"Okomuntu siqu"</string>
     <string name="category_work" msgid="4014193632325996115">"Umsebenzi"</string>
+    <string name="category_clone" msgid="1554511758987195974">"Yenza i-clone"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Izinketho Zonjiniyela"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Nika amandla izinketho zonjiniyela"</string>
     <string name="development_settings_summary" msgid="8718917813868735095">"Setha okukhethwayo kwentuthuko yohlelo lokusebenza"</string>
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index 2372c80..91549d7 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -112,8 +112,9 @@
     <dimen name="broadcast_dialog_btn_minHeight">44dp</dimen>
     <dimen name="broadcast_dialog_margin">16dp</dimen>
 
-    <!-- Size of grant admin privileges dialog padding -->
-    <dimen name="grant_admin_dialog_padding">16dp</dimen>
+    <dimen name="dialog_content_padding">16dp</dimen>
+    <dimen name="radio_button_padding">12dp</dimen>
+    <dimen name="radio_button_padding_start">8dp</dimen>
 
     <dimen name="dialog_button_horizontal_padding">16dp</dimen>
     <dimen name="dialog_button_vertical_padding">8dp</dimen>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
index 964e4b2..00ccea1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
@@ -36,6 +36,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.UserManager.EnforcingUser;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.style.ForegroundColorSpan;
@@ -118,12 +119,13 @@
             return enforcedAdmin;
         }
 
-        final int restrictionSource = enforcingUsers.get(0).getUserRestrictionSource();
+        final EnforcingUser enforcingUser = enforcingUsers.get(0);
+        final int restrictionSource = enforcingUser.getUserRestrictionSource();
         if (restrictionSource == UserManager.RESTRICTION_SOURCE_SYSTEM) {
             return null;
         }
 
-        final EnforcedAdmin admin = getProfileOrDeviceOwner(context, userHandle);
+        final EnforcedAdmin admin = getProfileOrDeviceOwner(context, enforcingUser.getUserHandle());
         if (admin != null) {
             return admin;
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index e846480..8d4aa9a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -67,6 +67,10 @@
     static final String STORAGE_MANAGER_ENABLED_PROPERTY =
             "ro.storage_manager.enabled";
 
+    @VisibleForTesting
+    static final String INCOMPATIBLE_CHARGER_WARNING_DISABLED =
+            "incompatible_charger_warning_disabled";
+
     private static Signature[] sSystemSignature;
     private static String sPermissionControllerPackageName;
     private static String sServicesSystemSharedLibPackageName;
@@ -652,6 +656,19 @@
 
     /** Whether there is any incompatible chargers in the current UsbPort? */
     public static boolean containsIncompatibleChargers(Context context, String tag) {
+        // Avoid the caller doesn't have permission to read the "Settings.Secure" data.
+        try {
+            // Whether the incompatible charger warning is disabled or not
+            if (Settings.Secure.getInt(context.getContentResolver(),
+                    INCOMPATIBLE_CHARGER_WARNING_DISABLED, 0) == 1) {
+                Log.d(tag, "containsIncompatibleChargers: disabled");
+                return false;
+            }
+        } catch (Exception e) {
+            Log.e(tag, "containsIncompatibleChargers()", e);
+            return false;
+        }
+
         final List<UsbPort> usbPortList =
                 context.getSystemService(UsbManager.class).getPorts();
         if (usbPortList == null || usbPortList.isEmpty()) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 4d6dd4b..f5bacb6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -250,6 +250,7 @@
                 }
             }
             cachedDevice.onActiveDeviceChanged(isActive, bluetoothProfile);
+            mDeviceManager.onActiveDeviceChanged(cachedDevice);
         }
         for (BluetoothCallback callback : mCallbacks) {
             callback.onActiveDeviceChanged(activeDevice, bluetoothProfile);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 1aa1741..2e6bb53 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -47,6 +47,7 @@
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.settingslib.widget.AdaptiveOutlineDrawable;
 
+import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
@@ -78,6 +79,7 @@
     BluetoothDevice mDevice;
     private HearingAidInfo mHearingAidInfo;
     private int mGroupId;
+    private Timestamp mBondTimestamp;
 
     // Need this since there is no method for getting RSSI
     short mRssi;
@@ -889,15 +891,25 @@
             mDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_UNKNOWN);
             mDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_UNKNOWN);
             mDevice.setSimAccessPermission(BluetoothDevice.ACCESS_UNKNOWN);
+
+            mBondTimestamp = null;
         }
 
         refresh();
 
-        if (bondState == BluetoothDevice.BOND_BONDED && mDevice.isBondingInitiatedLocally()) {
-            connect();
+        if (bondState == BluetoothDevice.BOND_BONDED) {
+            mBondTimestamp = new Timestamp(System.currentTimeMillis());
+
+            if (mDevice.isBondingInitiatedLocally()) {
+                connect();
+            }
         }
     }
 
+    public Timestamp getBondTimestamp() {
+        return mBondTimestamp;
+    }
+
     public BluetoothClass getBtClass() {
         return mDevice.getBluetoothClass();
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index 7b4c862..0c1b793 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -25,6 +25,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -37,6 +38,8 @@
     private static final String TAG = "CachedBluetoothDeviceManager";
     private static final boolean DEBUG = BluetoothUtils.D;
 
+    @VisibleForTesting static int sLateBondingTimeoutMillis = 5000; // 5s
+
     private Context mContext;
     private final LocalBluetoothManager mBtManager;
 
@@ -47,6 +50,8 @@
     @VisibleForTesting
     CsipDeviceManager mCsipDeviceManager;
     BluetoothDevice mOngoingSetMemberPair;
+    boolean mIsLateBonding;
+    int mGroupIdOfLateBonding;
 
     public CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager) {
         mContext = context;
@@ -209,6 +214,14 @@
      * @return The name, or if unavailable, the address.
      */
     public String getName(BluetoothDevice device) {
+        if (isOngoingPairByCsip(device)) {
+            CachedBluetoothDevice firstDevice =
+                    mCsipDeviceManager.getFirstMemberDevice(mGroupIdOfLateBonding);
+            if (firstDevice != null && firstDevice.getName() != null) {
+                return firstDevice.getName();
+            }
+        }
+
         CachedBluetoothDevice cachedDevice = findDevice(device);
         if (cachedDevice != null && cachedDevice.getName() != null) {
             return cachedDevice.getName();
@@ -309,6 +322,8 @@
 
             // To clear the SetMemberPair flag when the Bluetooth is turning off.
             mOngoingSetMemberPair = null;
+            mIsLateBonding = false;
+            mGroupIdOfLateBonding = BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
         }
     }
 
@@ -318,13 +333,23 @@
             return mHearingAidDeviceManager.onProfileConnectionStateChangedIfProcessed(cachedDevice,
                 state);
         }
-        if (profileId == BluetoothProfile.CSIP_SET_COORDINATOR) {
+        if (profileId == BluetoothProfile.HEADSET
+                || profileId == BluetoothProfile.A2DP
+                || profileId == BluetoothProfile.LE_AUDIO
+                || profileId == BluetoothProfile.CSIP_SET_COORDINATOR) {
             return mCsipDeviceManager.onProfileConnectionStateChangedIfProcessed(cachedDevice,
                 state);
         }
         return false;
     }
 
+    /** Handles when the device been set as active/inactive. */
+    public synchronized void onActiveDeviceChanged(CachedBluetoothDevice cachedBluetoothDevice) {
+        if (cachedBluetoothDevice.isHearingAidDevice()) {
+            mHearingAidDeviceManager.onActiveDeviceChanged(cachedBluetoothDevice);
+        }
+    }
+
     public synchronized void onDeviceUnpaired(CachedBluetoothDevice device) {
         device.setGroupId(BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
         CachedBluetoothDevice mainDevice = mCsipDeviceManager.findMainDevice(device);
@@ -367,15 +392,54 @@
     private synchronized boolean shouldPairByCsip(BluetoothDevice device, int groupId) {
         boolean isOngoingSetMemberPair = mOngoingSetMemberPair != null;
         int bondState = device.getBondState();
-        if (isOngoingSetMemberPair || bondState != BluetoothDevice.BOND_NONE
-                || !mCsipDeviceManager.isExistedGroupId(groupId)) {
-            Log.d(TAG, "isOngoingSetMemberPair: " + isOngoingSetMemberPair
-                    + " , device.getBondState: " + bondState);
+        boolean groupExists = mCsipDeviceManager.isExistedGroupId(groupId);
+        Log.d(TAG,
+                "isOngoingSetMemberPair=" + isOngoingSetMemberPair + ", bondState=" + bondState
+                        + ", groupExists=" + groupExists + ", groupId=" + groupId);
+
+        if (isOngoingSetMemberPair || bondState != BluetoothDevice.BOND_NONE || !groupExists) {
             return false;
         }
         return true;
     }
 
+    private synchronized boolean checkLateBonding(int groupId) {
+        CachedBluetoothDevice firstDevice = mCsipDeviceManager.getFirstMemberDevice(groupId);
+        if (firstDevice == null) {
+            Log.d(TAG, "No first device in group: " + groupId);
+            return false;
+        }
+
+        Timestamp then = firstDevice.getBondTimestamp();
+        if (then == null) {
+            Log.d(TAG, "No bond timestamp");
+            return true;
+        }
+
+        Timestamp now = new Timestamp(System.currentTimeMillis());
+
+        long diff = (now.getTime() - then.getTime());
+        Log.d(TAG, "Time difference to first bonding: " + diff + "ms");
+
+        return diff > sLateBondingTimeoutMillis;
+    }
+
+    /**
+     * Called to check if there is an ongoing bonding for the device and it is late bonding.
+     * If the device is not matching the ongoing bonding device then false will be returned.
+     *
+     * @param device The device to check.
+     */
+    public synchronized boolean isLateBonding(BluetoothDevice device) {
+        if (!isOngoingPairByCsip(device)) {
+            Log.d(TAG, "isLateBonding: pair not ongoing or not matching device");
+            return false;
+        }
+
+        Log.d(TAG, "isLateBonding: " + mIsLateBonding);
+        return mIsLateBonding;
+    }
+
     /**
      * Called when we found a set member of a group. The function will check the {@code groupId} if
      * it exists and the bond state of the device is BOND_NONE, and if there isn't any ongoing pair
@@ -388,12 +452,16 @@
         if (!shouldPairByCsip(device, groupId)) {
             return;
         }
-        Log.d(TAG, "Bond " + device.getAnonymizedAddress() + " by CSIP");
+        Log.d(TAG, "Bond " + device.getAnonymizedAddress() + " groupId=" + groupId + " by CSIP ");
         mOngoingSetMemberPair = device;
+        mIsLateBonding = checkLateBonding(groupId);
+        mGroupIdOfLateBonding = groupId;
         syncConfigFromMainDevice(device, groupId);
         if (!device.createBond(BluetoothDevice.TRANSPORT_LE)) {
             Log.d(TAG, "Bonding could not be started");
             mOngoingSetMemberPair = null;
+            mIsLateBonding = false;
+            mGroupIdOfLateBonding = BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
         }
     }
 
@@ -429,7 +497,7 @@
      * function, and would not like to update the UI. If not, return {@code false}.
      */
     public synchronized boolean onBondStateChangedIfProcess(BluetoothDevice device, int bondState) {
-        if (mOngoingSetMemberPair == null || !mOngoingSetMemberPair.equals(device)) {
+        if (!isOngoingPairByCsip(device)) {
             return false;
         }
 
@@ -438,6 +506,8 @@
         }
 
         mOngoingSetMemberPair = null;
+        mIsLateBonding = false;
+        mGroupIdOfLateBonding = BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
         if (bondState != BluetoothDevice.BOND_NONE) {
             if (findDevice(device) == null) {
                 final LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager();
@@ -461,7 +531,7 @@
      * {@code false}.
      */
     public boolean isOngoingPairByCsip(BluetoothDevice device) {
-        return !(mOngoingSetMemberPair == null) && mOngoingSetMemberPair.equals(device);
+        return mOngoingSetMemberPair != null && mOngoingSetMemberPair.equals(device);
     }
 
     private void log(String msg) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
index 356bb82..3a6da2c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
@@ -28,6 +28,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -83,14 +84,14 @@
     boolean setMemberDeviceIfNeeded(CachedBluetoothDevice newDevice) {
         final int groupId = newDevice.getGroupId();
         if (isValidGroupId(groupId)) {
-            final CachedBluetoothDevice CsipDevice = getCachedDevice(groupId);
-            log("setMemberDeviceIfNeeded, main: " + CsipDevice + ", member: " + newDevice);
+            final CachedBluetoothDevice mainDevice = getCachedDevice(groupId);
+            log("setMemberDeviceIfNeeded, main: " + mainDevice + ", member: " + newDevice);
             // Just add one of the coordinated set from a pair in the list that is shown in the UI.
             // Once there is other devices with the same groupId, to add new device as member
             // devices.
-            if (CsipDevice != null) {
-                CsipDevice.addMemberDevice(newDevice);
-                newDevice.setName(CsipDevice.getName());
+            if (mainDevice != null) {
+                mainDevice.addMemberDevice(newDevice);
+                newDevice.setName(mainDevice.getName());
                 return true;
             }
         }
@@ -152,14 +153,7 @@
             log("onGroupIdChanged: groupId is invalid");
             return;
         }
-        log("onGroupIdChanged: mCachedDevices list =" + mCachedDevices.toString());
-        List<CachedBluetoothDevice> memberDevicesList = getMemberDevicesList(groupId);
-        CachedBluetoothDevice newMainDevice =
-                getPreferredMainDeviceWithoutConectionState(groupId, memberDevicesList);
-
-        log("onGroupIdChanged: The mainDevice= " + newMainDevice
-                + " and the memberDevicesList of groupId= " + groupId + " =" + memberDevicesList);
-        addMemberDevicesIntoMainDevice(memberDevicesList, newMainDevice);
+        updateRelationshipOfGroupDevices(groupId);
     }
 
     // @return {@code true}, the event is processed inside the method. It is for updating
@@ -168,61 +162,30 @@
     boolean onProfileConnectionStateChangedIfProcessed(CachedBluetoothDevice cachedDevice,
             int state) {
         log("onProfileConnectionStateChangedIfProcessed: " + cachedDevice + ", state: " + state);
-        switch (state) {
-            case BluetoothProfile.STATE_CONNECTED:
-                onGroupIdChanged(cachedDevice.getGroupId());
-                CachedBluetoothDevice mainDevice = findMainDevice(cachedDevice);
-                if (mainDevice != null) {
-                    if (mainDevice.isConnected()) {
-                        // When main device exists and in connected state, receiving member device
-                        // connection. To refresh main device UI
-                        mainDevice.refresh();
-                        return true;
-                    } else {
-                        // When both LE Audio devices are disconnected, receiving member device
-                        // connection. To switch content and dispatch to notify UI change
-                        mBtManager.getEventManager().dispatchDeviceRemoved(mainDevice);
-                        mainDevice.switchMemberDeviceContent(cachedDevice);
-                        mainDevice.refresh();
-                        // It is necessary to do remove and add for updating the mapping on
-                        // preference and device
-                        mBtManager.getEventManager().dispatchDeviceAdded(mainDevice);
-                        return true;
-                    }
-                }
-                break;
-            case BluetoothProfile.STATE_DISCONNECTED:
-                mainDevice = findMainDevice(cachedDevice);
-                if (mainDevice != null) {
-                    // When main device exists, receiving sub device disconnection
-                    // To update main device UI
-                    mainDevice.refresh();
-                    return true;
-                }
-                final Set<CachedBluetoothDevice> memberSet = cachedDevice.getMemberDevice();
-                if (memberSet.isEmpty()) {
-                    break;
-                }
 
-                for (CachedBluetoothDevice device : memberSet) {
-                    if (device.isConnected()) {
-                        log("set device: " + device + " as the main device");
-                        // Main device is disconnected and sub device is connected
-                        // To copy data from sub device to main device
-                        mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice);
-                        cachedDevice.switchMemberDeviceContent(device);
-                        cachedDevice.refresh();
-                        // It is necessary to do remove and add for updating the mapping on
-                        // preference and device
-                        mBtManager.getEventManager().dispatchDeviceAdded(cachedDevice);
-                        return true;
-                    }
-                }
-                break;
-            default:
-                // Do not handle this state.
+        if (state != BluetoothProfile.STATE_CONNECTED
+                && state != BluetoothProfile.STATE_DISCONNECTED) {
+            return false;
         }
-        return false;
+        return updateRelationshipOfGroupDevices(cachedDevice.getGroupId());
+    }
+
+    @VisibleForTesting
+    boolean updateRelationshipOfGroupDevices(int groupId) {
+        if (!isValidGroupId(groupId)) {
+            log("The device is not group.");
+            return false;
+        }
+        log("updateRelationshipOfGroupDevices: mCachedDevices list =" + mCachedDevices.toString());
+
+        // Get the preferred main device by getPreferredMainDeviceWithoutConectionState
+        List<CachedBluetoothDevice> groupDevicesList = getGroupDevicesFromAllOfDevicesList(groupId);
+        CachedBluetoothDevice preferredMainDevice =
+                getPreferredMainDevice(groupId, groupDevicesList);
+        log("The preferredMainDevice= " + preferredMainDevice
+                + " and the groupDevicesList of groupId= " + groupId
+                + " =" + groupDevicesList);
+        return addMemberDevicesIntoMainDevice(groupId, preferredMainDevice);
     }
 
     CachedBluetoothDevice findMainDevice(CachedBluetoothDevice device) {
@@ -262,114 +225,164 @@
         return false;
     }
 
-    private List<CachedBluetoothDevice> getMemberDevicesList(int groupId) {
-        return mCachedDevices.stream()
-                .filter(cacheDevice -> cacheDevice.getGroupId() == groupId)
-                .collect(Collectors.toList());
+    @VisibleForTesting
+    List<CachedBluetoothDevice> getGroupDevicesFromAllOfDevicesList(int groupId) {
+        List<CachedBluetoothDevice> groupDevicesList = new ArrayList<>();
+        if (!isValidGroupId(groupId)) {
+            return groupDevicesList;
+        }
+        for (CachedBluetoothDevice item : mCachedDevices) {
+            if (groupId != item.getGroupId()) {
+                continue;
+            }
+            groupDevicesList.add(item);
+            groupDevicesList.addAll(item.getMemberDevice());
+        }
+        return groupDevicesList;
     }
 
-    private CachedBluetoothDevice getPreferredMainDeviceWithoutConectionState(int groupId,
-            List<CachedBluetoothDevice> memberDevicesList) {
-        // First, priority connected lead device from LE profile
-        // Second, the DUAL mode device which has A2DP/HFP and LE audio
-        // Last, any one of LE device in the list.
-        if (memberDevicesList == null || memberDevicesList.isEmpty()) {
+    public CachedBluetoothDevice getFirstMemberDevice(int groupId) {
+        List<CachedBluetoothDevice> members = getGroupDevicesFromAllOfDevicesList(groupId);
+        if (members.isEmpty())
             return null;
+
+        CachedBluetoothDevice firstMember = members.get(0);
+        log("getFirstMemberDevice: groupId=" + groupId
+                + " address=" + firstMember.getDevice().getAnonymizedAddress());
+        return firstMember;
+    }
+
+    @VisibleForTesting
+    CachedBluetoothDevice getPreferredMainDevice(int groupId,
+            List<CachedBluetoothDevice> groupDevicesList) {
+        // How to select the preferred main device?
+        // 1. The DUAL mode connected device which has A2DP/HFP and LE audio.
+        // 2. One of connected LE device in the list. Default is the lead device from LE profile.
+        // 3. If there is no connected device, then reset the relationship. Set the DUAL mode
+        // deviced as the main device. Otherwise, set any one of the device.
+        if (groupDevicesList == null || groupDevicesList.isEmpty()) {
+            return null;
+        }
+
+        CachedBluetoothDevice dualModeDevice = groupDevicesList.stream()
+                .filter(cachedDevice -> cachedDevice.getConnectableProfiles().stream()
+                        .anyMatch(profile -> profile instanceof LeAudioProfile))
+                .filter(cachedDevice -> cachedDevice.getConnectableProfiles().stream()
+                        .anyMatch(profile -> profile instanceof A2dpProfile
+                                || profile instanceof HeadsetProfile))
+                .findFirst().orElse(null);
+        if (dualModeDevice != null && dualModeDevice.isConnected()) {
+            log("getPreferredMainDevice: The connected DUAL mode device");
+            return dualModeDevice;
         }
 
         final LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager();
         final CachedBluetoothDeviceManager deviceManager = mBtManager.getCachedDeviceManager();
         final LeAudioProfile leAudioProfile = profileManager.getLeAudioProfile();
-        final BluetoothDevice mainBluetoothDevice = (leAudioProfile != null && isAtLeastT())
+        final BluetoothDevice leAudioLeadDevice = (leAudioProfile != null && isAtLeastT())
                 ? leAudioProfile.getConnectedGroupLeadDevice(groupId) : null;
 
-        if (mainBluetoothDevice != null) {
+        if (leAudioLeadDevice != null) {
             log("getPreferredMainDevice: The LeadDevice from LE profile is "
-                    + mainBluetoothDevice.getAnonymizedAddress());
+                    + leAudioLeadDevice.getAnonymizedAddress());
         }
-
-        // 1st
-        CachedBluetoothDevice newMainDevice =
-                mainBluetoothDevice != null ? deviceManager.findDevice(mainBluetoothDevice) : null;
-        if (newMainDevice != null) {
-            if (newMainDevice.isConnected()) {
-                log("getPreferredMainDevice: The connected LeadDevice from LE profile");
-                return newMainDevice;
-            } else {
-                log("getPreferredMainDevice: The LeadDevice is not connect.");
-            }
-        } else {
+        CachedBluetoothDevice leAudioLeadCachedDevice =
+                leAudioLeadDevice != null ? deviceManager.findDevice(leAudioLeadDevice) : null;
+        if (leAudioLeadCachedDevice == null) {
             log("getPreferredMainDevice: The LeadDevice is not in the all of devices list");
+        } else if (leAudioLeadCachedDevice.isConnected()) {
+            log("getPreferredMainDevice: The connected LeadDevice from LE profile");
+            return leAudioLeadCachedDevice;
         }
-
-        // 2nd
-        newMainDevice = memberDevicesList.stream()
-                .filter(cachedDevice -> cachedDevice.getConnectableProfiles().stream()
-                        .anyMatch(profile -> profile instanceof A2dpProfile
-                                || profile instanceof HeadsetProfile))
+        CachedBluetoothDevice oneOfConnectedDevices = groupDevicesList.stream()
+                .filter(cachedDevice -> cachedDevice.isConnected())
                 .findFirst().orElse(null);
-        if (newMainDevice != null) {
-            log("getPreferredMainDevice: The DUAL mode device");
-            return newMainDevice;
+        if (oneOfConnectedDevices != null) {
+            log("getPreferredMainDevice: One of the connected devices.");
+            return oneOfConnectedDevices;
         }
 
-        // last
-        if (!memberDevicesList.isEmpty()) {
-            newMainDevice = memberDevicesList.get(0);
+        if (dualModeDevice != null) {
+            log("getPreferredMainDevice: The DUAL mode device.");
+            return dualModeDevice;
         }
-        return newMainDevice;
+        // last
+        if (!groupDevicesList.isEmpty()) {
+            log("getPreferredMainDevice: One of the group devices.");
+            return groupDevicesList.get(0);
+        }
+        return null;
     }
 
-    private void addMemberDevicesIntoMainDevice(List<CachedBluetoothDevice> memberDevicesList,
-            CachedBluetoothDevice newMainDevice) {
-        if (newMainDevice == null) {
+    @VisibleForTesting
+    boolean addMemberDevicesIntoMainDevice(int groupId, CachedBluetoothDevice preferredMainDevice) {
+        boolean hasChanged = false;
+        if (preferredMainDevice == null) {
             log("addMemberDevicesIntoMainDevice: No main device. Do nothing.");
-            return;
+            return hasChanged;
         }
-        if (memberDevicesList.isEmpty()) {
-            log("addMemberDevicesIntoMainDevice: No member device in list. Do nothing.");
-            return;
-        }
-        CachedBluetoothDevice mainDeviceOfNewMainDevice = findMainDevice(newMainDevice);
-        boolean isMemberInOtherMainDevice = mainDeviceOfNewMainDevice != null;
-        if (!memberDevicesList.contains(newMainDevice) && isMemberInOtherMainDevice) {
-            log("addMemberDevicesIntoMainDevice: The 'new main device' is not in list, and it is "
-                    + "the member at other device. Do switch main and member.");
+
+        // If the current main device is not preferred main device, then set it as new main device.
+        // Otherwise, do nothing.
+        BluetoothDevice bluetoothDeviceOfPreferredMainDevice = preferredMainDevice.getDevice();
+        CachedBluetoothDevice mainDeviceOfPreferredMainDevice = findMainDevice(preferredMainDevice);
+        boolean hasPreferredMainDeviceAlreadyBeenMainDevice =
+                mainDeviceOfPreferredMainDevice == null;
+
+        if (!hasPreferredMainDeviceAlreadyBeenMainDevice) {
+            // preferredMainDevice has not been the main device.
+            // switch relationship between the mainDeviceOfPreferredMainDevice and
+            // PreferredMainDevice
+
+            log("addMemberDevicesIntoMainDevice: The PreferredMainDevice have the mainDevice. "
+                    + "Do switch relationship between the mainDeviceOfPreferredMainDevice and "
+                    + "PreferredMainDevice");
             // To switch content and dispatch to notify UI change
-            mBtManager.getEventManager().dispatchDeviceRemoved(mainDeviceOfNewMainDevice);
-            mainDeviceOfNewMainDevice.switchMemberDeviceContent(newMainDevice);
-            mainDeviceOfNewMainDevice.refresh();
+            mBtManager.getEventManager().dispatchDeviceRemoved(mainDeviceOfPreferredMainDevice);
+            mainDeviceOfPreferredMainDevice.switchMemberDeviceContent(preferredMainDevice);
+            mainDeviceOfPreferredMainDevice.refresh();
             // It is necessary to do remove and add for updating the mapping on
             // preference and device
-            mBtManager.getEventManager().dispatchDeviceAdded(mainDeviceOfNewMainDevice);
-        } else {
-            log("addMemberDevicesIntoMainDevice: Set new main device");
-            for (CachedBluetoothDevice memberDeviceItem : memberDevicesList) {
-                if (memberDeviceItem.equals(newMainDevice)) {
+            mBtManager.getEventManager().dispatchDeviceAdded(mainDeviceOfPreferredMainDevice);
+            hasChanged = true;
+        }
+
+        // If the mCachedDevices List at CachedBluetoothDeviceManager has multiple items which are
+        // the same groupId, then combine them and also keep the preferred main device as main
+        // device.
+        List<CachedBluetoothDevice> topLevelOfGroupDevicesList = mCachedDevices.stream()
+                .filter(device -> device.getGroupId() == groupId)
+                .collect(Collectors.toList());
+        boolean haveMultiMainDevicesInAllOfDevicesList = topLevelOfGroupDevicesList.size() > 1;
+        // Update the new main of CachedBluetoothDevice, since it may be changed in above step.
+        final CachedBluetoothDeviceManager deviceManager = mBtManager.getCachedDeviceManager();
+        preferredMainDevice = deviceManager.findDevice(bluetoothDeviceOfPreferredMainDevice);
+        if (haveMultiMainDevicesInAllOfDevicesList) {
+            // put another devices into main device.
+            for (CachedBluetoothDevice deviceItem : topLevelOfGroupDevicesList) {
+                if (deviceItem.getDevice() == null || deviceItem.getDevice().equals(
+                        bluetoothDeviceOfPreferredMainDevice)) {
                     continue;
                 }
-                Set<CachedBluetoothDevice> memberSet = memberDeviceItem.getMemberDevice();
-                if (!memberSet.isEmpty()) {
-                    for (CachedBluetoothDevice memberSetItem : memberSet) {
-                        if (!memberSetItem.equals(newMainDevice)) {
-                            newMainDevice.addMemberDevice(memberSetItem);
-                        }
+
+                Set<CachedBluetoothDevice> memberSet = deviceItem.getMemberDevice();
+                for (CachedBluetoothDevice memberSetItem : memberSet) {
+                    if (!memberSetItem.equals(preferredMainDevice)) {
+                        preferredMainDevice.addMemberDevice(memberSetItem);
                     }
-                    memberSet.clear();
                 }
-
-                newMainDevice.addMemberDevice(memberDeviceItem);
-                mCachedDevices.remove(memberDeviceItem);
-                mBtManager.getEventManager().dispatchDeviceRemoved(memberDeviceItem);
-            }
-
-            if (!mCachedDevices.contains(newMainDevice)) {
-                mCachedDevices.add(newMainDevice);
-                mBtManager.getEventManager().dispatchDeviceAdded(newMainDevice);
+                memberSet.clear();
+                preferredMainDevice.addMemberDevice(deviceItem);
+                mCachedDevices.remove(deviceItem);
+                mBtManager.getEventManager().dispatchDeviceRemoved(deviceItem);
+                hasChanged = true;
             }
         }
-        log("addMemberDevicesIntoMainDevice: After changed, CachedBluetoothDevice list: "
-                + mCachedDevices);
+        if (hasChanged) {
+            log("addMemberDevicesIntoMainDevice: After changed, CachedBluetoothDevice list: "
+                    + mCachedDevices);
+        }
+        return hasChanged;
     }
 
     private void log(String msg) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
index 4354e0c..e5e5782 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
@@ -224,15 +224,9 @@
                         // It is necessary to do remove and add for updating the mapping on
                         // preference and device
                         mBtManager.getEventManager().dispatchDeviceAdded(mainDevice);
-                        // Only need to set first device of a set. AudioDeviceInfo for
-                        // GET_DEVICES_OUTPUTS will not change device.
-                        setAudioRoutingConfig(cachedDevice);
                     }
                     return true;
                 }
-                // Only need to set first device of a set. AudioDeviceInfo for GET_DEVICES_OUTPUTS
-                // will not change device.
-                setAudioRoutingConfig(cachedDevice);
                 break;
             case BluetoothProfile.STATE_DISCONNECTED:
                 mainDevice = findMainDevice(cachedDevice);
@@ -258,13 +252,20 @@
 
                     return true;
                 }
-                // Only need to clear when last device of a set get disconnected
-                clearAudioRoutingConfig();
                 break;
         }
         return false;
     }
 
+    void onActiveDeviceChanged(CachedBluetoothDevice device) {
+        if (device.isActiveDevice(BluetoothProfile.HEARING_AID) || device.isActiveDevice(
+                BluetoothProfile.LE_AUDIO)) {
+            setAudioRoutingConfig(device);
+        } else {
+            clearAudioRoutingConfig();
+        }
+    }
+
     private void setAudioRoutingConfig(CachedBluetoothDevice device) {
         AudioDeviceAttributes hearingDeviceAttributes =
                 mRoutingHelper.getMatchedHearingDeviceAttributes(device);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 43e3a32..0e7b79b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -37,6 +37,7 @@
 import android.bluetooth.BluetoothProfile;
 import android.bluetooth.BluetoothSap;
 import android.bluetooth.BluetoothUuid;
+import android.bluetooth.BluetoothVolumeControl;
 import android.content.Context;
 import android.content.Intent;
 import android.os.ParcelUuid;
@@ -240,8 +241,8 @@
                 Log.d(TAG, "Adding local Volume Control profile");
             }
             mVolumeControlProfile = new VolumeControlProfile(mContext, mDeviceManager, this);
-            // Note: no event handler for VCP, only for being connectable.
-            mProfileNameMap.put(VolumeControlProfile.NAME, mVolumeControlProfile);
+            addProfile(mVolumeControlProfile, VolumeControlProfile.NAME,
+                    BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED);
         }
         if (mLeAudioProfile == null && supportedList.contains(BluetoothProfile.LE_AUDIO)) {
             if (DEBUG) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
index c4f09ce..f911d35 100644
--- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
@@ -111,6 +111,9 @@
     public static final int COMPLICATION_TYPE_SMARTSPACE = 7;
     public static final int COMPLICATION_TYPE_MEDIA_ENTRY = 8;
 
+    private static final int SCREENSAVER_HOME_CONTROLS_ENABLED_DEFAULT = 1;
+    private static final int LOCKSCREEN_SHOW_CONTROLS_DEFAULT = 0;
+
     private final Context mContext;
     private final IDreamManager mDreamManager;
     private final DreamInfoComparator mComparator;
@@ -311,8 +314,14 @@
 
     /** Gets whether home controls button is enabled on the dream */
     private boolean getHomeControlsEnabled() {
-        return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.SCREENSAVER_HOME_CONTROLS_ENABLED, 1) == 1;
+        return Settings.Secure.getInt(
+                mContext.getContentResolver(),
+                Settings.Secure.LOCKSCREEN_SHOW_CONTROLS,
+                LOCKSCREEN_SHOW_CONTROLS_DEFAULT) == 1
+                && Settings.Secure.getInt(
+                        mContext.getContentResolver(),
+                        Settings.Secure.SCREENSAVER_HOME_CONTROLS_ENABLED,
+                        SCREENSAVER_HOME_CONTROLS_ENABLED_DEFAULT) == 1;
     }
 
     /**
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
index 2555e2b..76556639 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
@@ -16,12 +16,11 @@
 
 package com.android.settingslib.fuelgauge;
 
-import static android.os.BatteryManager.BATTERY_HEALTH_OVERHEAT;
-import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
 import static android.os.BatteryManager.BATTERY_STATUS_FULL;
 import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
-import static android.os.BatteryManager.EXTRA_HEALTH;
-import static android.os.BatteryManager.EXTRA_LEVEL;
+import static android.os.BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE;
+import static android.os.BatteryManager.CHARGING_POLICY_DEFAULT;
+import static android.os.BatteryManager.EXTRA_CHARGING_STATUS;
 import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
 import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
 import static android.os.BatteryManager.EXTRA_PLUGGED;
@@ -51,7 +50,7 @@
     public final int status;
     public final int level;
     public final int plugged;
-    public final int health;
+    public final int chargingStatus;
     public final int maxChargingWattage;
     public final boolean present;
     public final Optional<Boolean> incompatibleCharger;
@@ -62,12 +61,12 @@
                 ? null : new BatteryStatus(batteryChangedIntent, incompatibleCharger);
     }
 
-    public BatteryStatus(int status, int level, int plugged, int health,
+    public BatteryStatus(int status, int level, int plugged, int chargingStatus,
             int maxChargingWattage, boolean present) {
         this.status = status;
         this.level = level;
         this.plugged = plugged;
-        this.health = health;
+        this.chargingStatus = chargingStatus;
         this.maxChargingWattage = maxChargingWattage;
         this.present = present;
         this.incompatibleCharger = Optional.empty();
@@ -86,7 +85,8 @@
         status = batteryChangedIntent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
         plugged = batteryChangedIntent.getIntExtra(EXTRA_PLUGGED, 0);
         level = getBatteryLevel(batteryChangedIntent);
-        health = batteryChangedIntent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
+        chargingStatus = batteryChangedIntent.getIntExtra(EXTRA_CHARGING_STATUS,
+                CHARGING_POLICY_DEFAULT);
         present = batteryChangedIntent.getBooleanExtra(EXTRA_PRESENT, true);
         this.incompatibleCharger = incompatibleCharger;
 
@@ -143,9 +143,9 @@
         return level < LOW_BATTERY_THRESHOLD;
     }
 
-    /** Whether battery is overheated. */
-    public boolean isOverheated() {
-        return health == BATTERY_HEALTH_OVERHEAT;
+    /** Whether battery defender is enabled. */
+    public boolean isBatteryDefender() {
+        return chargingStatus == CHARGING_POLICY_ADAPTIVE_LONGLIFE;
     }
 
     /** Return current chargin speed is fast, slow or normal. */
@@ -163,7 +163,8 @@
     @Override
     public String toString() {
         return "BatteryStatus{status=" + status + ",level=" + level + ",plugged=" + plugged
-                + ",health=" + health + ",maxChargingWattage=" + maxChargingWattage + "}";
+                + ",chargingStatus=" + chargingStatus + ",maxChargingWattage=" + maxChargingWattage
+                + "}";
     }
 
     /**
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
index c036fdb..632120e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
@@ -15,10 +15,14 @@
  */
 package com.android.settingslib.media;
 
-import static android.media.MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK;
-import static android.media.MediaRoute2Info.FEATURE_REMOTE_VIDEO_PLAYBACK;
 import static android.media.MediaRoute2Info.TYPE_GROUP;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_CAR;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_COMPUTER;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_GAME_CONSOLE;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_SMARTWATCH;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_TABLET;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_TABLET_DOCKED;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
 
 import android.content.Context;
@@ -31,8 +35,6 @@
 
 import com.android.settingslib.R;
 
-import java.util.List;
-
 /**
  * InfoMediaDevice extends MediaDevice to represents wifi device.
  */
@@ -69,13 +71,12 @@
 
     @Override
     public Drawable getIconWithoutBackground() {
-        return mContext.getDrawable(getDrawableResIdByFeature());
+        return mContext.getDrawable(getDrawableResIdByType());
     }
 
     @VisibleForTesting
-    // MediaRoute2Info.getType was made public on API 34, but exists since API 30.
     @SuppressWarnings("NewApi")
-    int getDrawableResId() {
+    int getDrawableResIdByType() {
         int resId;
         switch (mRouteInfo.getType()) {
             case TYPE_GROUP:
@@ -84,6 +85,24 @@
             case TYPE_REMOTE_TV:
                 resId = R.drawable.ic_media_display_device;
                 break;
+            case TYPE_REMOTE_TABLET:
+                resId = R.drawable.ic_media_tablet;
+                break;
+            case TYPE_REMOTE_TABLET_DOCKED:
+                resId = R.drawable.ic_dock_device;
+                break;
+            case TYPE_REMOTE_COMPUTER:
+                resId = R.drawable.ic_media_computer;
+                break;
+            case TYPE_REMOTE_GAME_CONSOLE:
+                resId = R.drawable.ic_media_game_console;
+                break;
+            case TYPE_REMOTE_CAR:
+                resId = R.drawable.ic_media_car;
+                break;
+            case TYPE_REMOTE_SMARTWATCH:
+                resId = R.drawable.ic_media_smartwatch;
+                break;
             case TYPE_REMOTE_SPEAKER:
             default:
                 resId = R.drawable.ic_media_speaker_device;
@@ -92,21 +111,6 @@
         return resId;
     }
 
-    @VisibleForTesting
-    int getDrawableResIdByFeature() {
-        int resId;
-        final List<String> features = mRouteInfo.getFeatures();
-        if (features.contains(FEATURE_REMOTE_GROUP_PLAYBACK)) {
-            resId = R.drawable.ic_media_group_device;
-        } else if (features.contains(FEATURE_REMOTE_VIDEO_PLAYBACK)) {
-            resId = R.drawable.ic_media_display_device;
-        } else {
-            resId = R.drawable.ic_media_speaker_device;
-        }
-
-        return resId;
-    }
-
     @Override
     public String getId() {
         return MediaDeviceUtils.getId(mRouteInfo);
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 82c6f11..3fcb7f3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -23,7 +23,13 @@
 import static android.media.MediaRoute2Info.TYPE_HDMI;
 import static android.media.MediaRoute2Info.TYPE_HEARING_AID;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_AUDIO_VIDEO_RECEIVER;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_CAR;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_COMPUTER;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_GAME_CONSOLE;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_SMARTWATCH;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_TABLET;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_TABLET_DOCKED;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
 import static android.media.MediaRoute2Info.TYPE_UNKNOWN;
 import static android.media.MediaRoute2Info.TYPE_USB_ACCESSORY;
@@ -531,7 +537,6 @@
     @SuppressWarnings("NewApi")
     @VisibleForTesting
     void addMediaDevice(MediaRoute2Info route) {
-        //TODO(b/258141461): Attach flag and disable reason in MediaDevice
         final int deviceType = route.getType();
         MediaDevice mediaDevice = null;
         switch (deviceType) {
@@ -539,7 +544,12 @@
             case TYPE_REMOTE_TV:
             case TYPE_REMOTE_SPEAKER:
             case TYPE_GROUP:
-                //TODO(b/148765806): use correct device type once api is ready.
+            case TYPE_REMOTE_TABLET:
+            case TYPE_REMOTE_TABLET_DOCKED:
+            case TYPE_REMOTE_COMPUTER:
+            case TYPE_REMOTE_GAME_CONSOLE:
+            case TYPE_REMOTE_CAR:
+            case TYPE_REMOTE_SMARTWATCH:
                 mediaDevice = new InfoMediaDevice(mContext, mRouterManager, route,
                         mPackageName, mPreferenceItemMap.get(route.getId()));
                 break;
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/CreateUserDialogController.java b/packages/SettingsLib/src/com/android/settingslib/users/CreateUserDialogController.java
new file mode 100644
index 0000000..e61c8f5
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/users/CreateUserDialogController.java
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.users;
+
+import android.annotation.IntDef;
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.internal.util.UserIcons;
+import com.android.settingslib.R;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
+import com.android.settingslib.drawable.CircleFramedDrawable;
+import com.android.settingslib.utils.CustomDialogHelper;
+import com.android.settingslib.utils.ThreadUtils;
+
+import java.io.File;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This class encapsulates a Dialog for editing the user nickname and photo.
+ */
+public class CreateUserDialogController {
+
+    private static final String KEY_AWAITING_RESULT = "awaiting_result";
+    private static final String KEY_CURRENT_STATE = "current_state";
+    private static final String KEY_SAVED_PHOTO = "pending_photo";
+    private static final String KEY_SAVED_NAME = "saved_name";
+    private static final String KEY_IS_ADMIN = "admin_status";
+    private static final String KEY_ADD_USER_LONG_MESSAGE_DISPLAYED =
+            "key_add_user_long_message_displayed";
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({EXIT_DIALOG, INITIAL_DIALOG, GRANT_ADMIN_DIALOG,
+            EDIT_NAME_DIALOG, CREATE_USER_AND_CLOSE})
+    public @interface AddUserState {}
+
+    private static final int EXIT_DIALOG = -1;
+    private static final int INITIAL_DIALOG = 0;
+    private static final int GRANT_ADMIN_DIALOG = 1;
+    private static final int EDIT_NAME_DIALOG = 2;
+    private static final int CREATE_USER_AND_CLOSE = 3;
+
+    private @AddUserState int mCurrentState;
+
+    private CustomDialogHelper mCustomDialogHelper;
+
+    private EditUserPhotoController mEditUserPhotoController;
+    private Bitmap mSavedPhoto;
+    private String mSavedName;
+    private Drawable mSavedDrawable;
+    private Boolean mIsAdmin;
+    private Dialog mUserCreationDialog;
+    private View mGrantAdminView;
+    private View mEditUserInfoView;
+    private EditText mUserNameView;
+    private Activity mActivity;
+    private ActivityStarter mActivityStarter;
+    private boolean mWaitingForActivityResult;
+    private NewUserData mSuccessCallback;
+
+    private final String mFileAuthority;
+
+    public CreateUserDialogController(String fileAuthority) {
+        mFileAuthority = fileAuthority;
+    }
+
+    /**
+     * Resets saved values.
+     */
+    public void clear() {
+        mUserCreationDialog = null;
+        mCustomDialogHelper = null;
+        mEditUserPhotoController = null;
+        mSavedPhoto = null;
+        mSavedName = null;
+        mSavedDrawable = null;
+        mIsAdmin = null;
+        mActivity = null;
+        mActivityStarter = null;
+        mGrantAdminView = null;
+        mEditUserInfoView = null;
+        mUserNameView = null;
+        mSuccessCallback = null;
+        mCurrentState = INITIAL_DIALOG;
+    }
+
+    /**
+     * Notifies that the containing activity or fragment was reinitialized.
+     */
+    public void onRestoreInstanceState(Bundle savedInstanceState) {
+        String pendingPhoto = savedInstanceState.getString(KEY_SAVED_PHOTO);
+        if (pendingPhoto != null) {
+            ThreadUtils.postOnBackgroundThread(() -> {
+                mSavedPhoto = EditUserPhotoController.loadNewUserPhotoBitmap(
+                        new File(pendingPhoto));
+            });
+        }
+        mCurrentState = savedInstanceState.getInt(KEY_CURRENT_STATE);
+        if (savedInstanceState.containsKey(KEY_IS_ADMIN)) {
+            mIsAdmin = savedInstanceState.getBoolean(KEY_IS_ADMIN);
+        }
+        mSavedName = savedInstanceState.getString(KEY_SAVED_NAME);
+        mWaitingForActivityResult = savedInstanceState.getBoolean(KEY_AWAITING_RESULT, false);
+    }
+
+    /**
+     * Notifies that the containing activity or fragment is saving its state for later use.
+     */
+    public void onSaveInstanceState(Bundle savedInstanceState) {
+        if (mUserCreationDialog != null && mEditUserPhotoController != null) {
+            // Bitmap cannot be stored into bundle because it may exceed parcel limit
+            // Store it in a temporary file instead
+            ThreadUtils.postOnBackgroundThread(() -> {
+                File file = mEditUserPhotoController.saveNewUserPhotoBitmap();
+                if (file != null) {
+                    savedInstanceState.putString(KEY_SAVED_PHOTO, file.getPath());
+                }
+            });
+        }
+        if (mIsAdmin != null) {
+            savedInstanceState.putBoolean(KEY_IS_ADMIN, Boolean.TRUE.equals(mIsAdmin));
+        }
+        savedInstanceState.putString(KEY_SAVED_NAME, mUserNameView.getText().toString().trim());
+        savedInstanceState.putInt(KEY_CURRENT_STATE, mCurrentState);
+        savedInstanceState.putBoolean(KEY_AWAITING_RESULT, mWaitingForActivityResult);
+    }
+
+    /**
+     * Notifies that an activity has started.
+     */
+    public void startingActivityForResult() {
+        mWaitingForActivityResult = true;
+    }
+
+    /**
+     * Notifies that the result from activity has been received.
+     */
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        mWaitingForActivityResult = false;
+        if (mEditUserPhotoController != null) {
+            mEditUserPhotoController.onActivityResult(requestCode, resultCode, data);
+        }
+    }
+
+    /**
+     * Creates an add user dialog with option to set the user's name and photo and choose their
+     * admin status.
+     */
+    public Dialog createDialog(Activity activity,
+            ActivityStarter activityStarter, boolean isMultipleAdminEnabled,
+            NewUserData successCallback, Runnable cancelCallback) {
+        mActivity = activity;
+        mCustomDialogHelper = new CustomDialogHelper(activity);
+        mSuccessCallback = successCallback;
+        mActivityStarter = activityStarter;
+        addCustomViews(isMultipleAdminEnabled);
+        mUserCreationDialog = mCustomDialogHelper.getDialog();
+        updateLayout();
+        mUserCreationDialog.setOnDismissListener(view -> {
+            cancelCallback.run();
+            clear();
+        });
+        mUserCreationDialog.setCanceledOnTouchOutside(true);
+        return mUserCreationDialog;
+    }
+
+    private void addCustomViews(boolean isMultipleAdminEnabled) {
+        addGrantAdminView();
+        addUserInfoEditView();
+        mCustomDialogHelper.setPositiveButton(R.string.next, view -> {
+            mCurrentState++;
+            if (mCurrentState == GRANT_ADMIN_DIALOG && !isMultipleAdminEnabled) {
+                mCurrentState++;
+            }
+            updateLayout();
+        });
+        mCustomDialogHelper.setNegativeButton(R.string.back, view -> {
+            mCurrentState--;
+            if (mCurrentState == GRANT_ADMIN_DIALOG && !isMultipleAdminEnabled) {
+                mCurrentState--;
+            }
+            updateLayout();
+        });
+        return;
+    }
+
+    private void updateLayout() {
+        switch (mCurrentState) {
+            case INITIAL_DIALOG:
+                mEditUserInfoView.setVisibility(View.GONE);
+                mGrantAdminView.setVisibility(View.GONE);
+                final SharedPreferences preferences = mActivity.getPreferences(
+                        Context.MODE_PRIVATE);
+                final boolean longMessageDisplayed = preferences.getBoolean(
+                        KEY_ADD_USER_LONG_MESSAGE_DISPLAYED, false);
+                final int messageResId = longMessageDisplayed
+                        ? R.string.user_add_user_message_short
+                        : R.string.user_add_user_message_long;
+                if (!longMessageDisplayed) {
+                    preferences.edit().putBoolean(
+                            KEY_ADD_USER_LONG_MESSAGE_DISPLAYED,
+                            true).apply();
+                }
+                Drawable icon = mActivity.getDrawable(R.drawable.ic_person_add);
+                mCustomDialogHelper.setVisibility(mCustomDialogHelper.ICON, true)
+                        .setVisibility(mCustomDialogHelper.TITLE, true)
+                        .setVisibility(mCustomDialogHelper.MESSAGE, true)
+                        .setIcon(icon)
+                        .setButtonEnabled(true)
+                        .setTitle(R.string.user_add_user_title)
+                        .setMessage(messageResId)
+                        .setNegativeButtonText(R.string.cancel)
+                        .setPositiveButtonText(R.string.next);
+                break;
+            case GRANT_ADMIN_DIALOG:
+                mEditUserInfoView.setVisibility(View.GONE);
+                mGrantAdminView.setVisibility(View.VISIBLE);
+                mCustomDialogHelper
+                        .setVisibility(mCustomDialogHelper.ICON, true)
+                        .setVisibility(mCustomDialogHelper.TITLE, true)
+                        .setVisibility(mCustomDialogHelper.MESSAGE, true)
+                        .setIcon(mActivity.getDrawable(R.drawable.ic_admin_panel_settings))
+                        .setTitle(R.string.user_grant_admin_title)
+                        .setMessage(R.string.user_grant_admin_message)
+                        .setNegativeButtonText(R.string.back)
+                        .setPositiveButtonText(R.string.next);
+                if (mIsAdmin == null) {
+                    mCustomDialogHelper.setButtonEnabled(false);
+                }
+                break;
+            case EDIT_NAME_DIALOG:
+                mCustomDialogHelper
+                        .setVisibility(mCustomDialogHelper.ICON, false)
+                        .setVisibility(mCustomDialogHelper.TITLE, false)
+                        .setVisibility(mCustomDialogHelper.MESSAGE, false)
+                        .setNegativeButtonText(R.string.back)
+                        .setPositiveButtonText(R.string.done);
+                mEditUserInfoView.setVisibility(View.VISIBLE);
+                mGrantAdminView.setVisibility(View.GONE);
+                break;
+            case CREATE_USER_AND_CLOSE:
+                Drawable newUserIcon = mEditUserPhotoController != null
+                        ? mEditUserPhotoController.getNewUserPhotoDrawable()
+                        : null;
+
+                String newName = mUserNameView.getText().toString().trim();
+                String defaultName = mActivity.getString(R.string.user_new_user_name);
+                String userName = !newName.isEmpty() ? newName : defaultName;
+
+                if (mSuccessCallback != null) {
+                    mSuccessCallback.onSuccess(userName, newUserIcon,
+                            Boolean.TRUE.equals(mIsAdmin));
+                }
+                mCustomDialogHelper.getDialog().dismiss();
+                clear();
+                break;
+            case EXIT_DIALOG:
+                mCustomDialogHelper.getDialog().dismiss();
+                break;
+            default:
+                if (mCurrentState < EXIT_DIALOG) {
+                    mCurrentState = EXIT_DIALOG;
+                    updateLayout();
+                } else {
+                    mCurrentState = CREATE_USER_AND_CLOSE;
+                    updateLayout();
+                }
+                break;
+        }
+    }
+
+    private Drawable getUserIcon(Drawable defaultUserIcon) {
+        if (mSavedPhoto != null) {
+            mSavedDrawable = CircleFramedDrawable.getInstance(mActivity, mSavedPhoto);
+            return mSavedDrawable;
+        }
+        return defaultUserIcon;
+    }
+
+    private void addUserInfoEditView() {
+        mEditUserInfoView = View.inflate(mActivity, R.layout.edit_user_info_dialog_content, null);
+        mCustomDialogHelper.addCustomView(mEditUserInfoView);
+        setUserName();
+        ImageView userPhotoView = mEditUserInfoView.findViewById(R.id.user_photo);
+
+        // if oldUserIcon param is null then we use a default gray user icon
+        Drawable defaultUserIcon = UserIcons.getDefaultUserIcon(
+                mActivity.getResources(), UserHandle.USER_NULL, false);
+        // in case a new photo was selected and the activity got recreated we have to load the image
+        Drawable userIcon = getUserIcon(defaultUserIcon);
+        userPhotoView.setImageDrawable(userIcon);
+
+        if (isChangePhotoRestrictedByBase(mActivity)) {
+            // some users can't change their photos so we need to remove the suggestive icon
+            mEditUserInfoView.findViewById(R.id.add_a_photo_icon).setVisibility(View.GONE);
+        } else {
+            RestrictedLockUtils.EnforcedAdmin adminRestriction =
+                    getChangePhotoAdminRestriction(mActivity);
+            if (adminRestriction != null) {
+                userPhotoView.setOnClickListener(view ->
+                        RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
+                                mActivity, adminRestriction));
+            } else {
+                mEditUserPhotoController = createEditUserPhotoController(userPhotoView);
+            }
+        }
+    }
+
+    private void setUserName() {
+        mUserNameView = mEditUserInfoView.findViewById(R.id.user_name);
+        if (mSavedName == null) {
+            mUserNameView.setText(R.string.user_new_user_name);
+        } else {
+            mUserNameView.setText(mSavedName);
+        }
+    }
+
+    private void addGrantAdminView() {
+        mGrantAdminView = View.inflate(mActivity, R.layout.grant_admin_dialog_content, null);
+        mCustomDialogHelper.addCustomView(mGrantAdminView);
+        RadioGroup radioGroup = mGrantAdminView.findViewById(R.id.choose_admin);
+        radioGroup.setOnCheckedChangeListener((group, checkedId) -> {
+                    mCustomDialogHelper.setButtonEnabled(true);
+                    mIsAdmin = checkedId == R.id.grant_admin_yes;
+                }
+        );
+        if (Boolean.TRUE.equals(mIsAdmin)) {
+            RadioButton button = radioGroup.findViewById(R.id.grant_admin_yes);
+            button.setChecked(true);
+        } else if (Boolean.FALSE.equals(mIsAdmin)) {
+            RadioButton button = radioGroup.findViewById(R.id.grant_admin_no);
+            button.setChecked(true);
+        }
+    }
+
+    @VisibleForTesting
+    boolean isChangePhotoRestrictedByBase(Context context) {
+        return RestrictedLockUtilsInternal.hasBaseUserRestriction(
+                context, UserManager.DISALLOW_SET_USER_ICON, UserHandle.myUserId());
+    }
+
+    @VisibleForTesting
+    RestrictedLockUtils.EnforcedAdmin getChangePhotoAdminRestriction(Context context) {
+        return RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
+                context, UserManager.DISALLOW_SET_USER_ICON, UserHandle.myUserId());
+    }
+
+    @VisibleForTesting
+    EditUserPhotoController createEditUserPhotoController(ImageView userPhotoView) {
+        return new EditUserPhotoController(mActivity, mActivityStarter, userPhotoView,
+                mSavedPhoto, mSavedDrawable, mFileAuthority);
+    }
+
+    public boolean isActive() {
+        return mCustomDialogHelper != null && mCustomDialogHelper.getDialog() != null;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/NewUserData.java b/packages/SettingsLib/src/com/android/settingslib/users/NewUserData.java
new file mode 100644
index 0000000..3d18b59
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/users/NewUserData.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.users;
+
+import android.graphics.drawable.Drawable;
+
+/**
+ * Defines a callback when a new user data is filled out.
+ */
+public interface NewUserData {
+
+    /**
+     * Consumes data relevant to new user that needs to be created.
+     * @param userName New user name.
+     * @param userImage New user icon.
+     * @param isNewUserAdmin A boolean that indicated whether new user has admin status.
+     */
+    void onSuccess(String userName, Drawable userImage, Boolean isNewUserAdmin);
+
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
index dce1e20..0637e5d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
@@ -43,6 +43,7 @@
 import android.telephony.ServiceState;
 import android.text.TextUtils;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -65,6 +66,7 @@
 @Config(shadows = {UtilsTest.ShadowSecure.class, UtilsTest.ShadowLocationManager.class})
 public class UtilsTest {
     private static final double[] TEST_PERCENTAGES = {0, 0.4, 0.5, 0.6, 49, 49.3, 49.8, 50, 100};
+    private static final String TAG = "UtilsTest";
     private static final String PERCENTAGE_0 = "0%";
     private static final String PERCENTAGE_1 = "1%";
     private static final String PERCENTAGE_49 = "49%";
@@ -96,6 +98,12 @@
         mAudioManager = mContext.getSystemService(AudioManager.class);
     }
 
+    @After
+    public void reset() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Utils.INCOMPATIBLE_CHARGER_WARNING_DISABLED, 0);
+    }
+
     @Test
     public void testUpdateLocationEnabled() {
         int currentUserId = ActivityManager.getCurrentUser();
@@ -427,13 +435,13 @@
     @Test
     public void containsIncompatibleChargers_nullPorts_returnFalse() {
         when(mUsbManager.getPorts()).thenReturn(null);
-        assertThat(Utils.containsIncompatibleChargers(mContext, "tag")).isFalse();
+        assertThat(Utils.containsIncompatibleChargers(mContext, TAG)).isFalse();
     }
 
     @Test
     public void containsIncompatibleChargers_emptyPorts_returnFalse() {
         when(mUsbManager.getPorts()).thenReturn(new ArrayList<>());
-        assertThat(Utils.containsIncompatibleChargers(mContext, "tag")).isFalse();
+        assertThat(Utils.containsIncompatibleChargers(mContext, TAG)).isFalse();
     }
 
     @Test
@@ -443,13 +451,13 @@
         when(mUsbManager.getPorts()).thenReturn(usbPorts);
         when(mUsbPort.getStatus()).thenReturn(null);
 
-        assertThat(Utils.containsIncompatibleChargers(mContext, "tag")).isFalse();
+        assertThat(Utils.containsIncompatibleChargers(mContext, TAG)).isFalse();
     }
 
     @Test
     public void containsIncompatibleChargers_returnTrue() {
         setupIncompatibleCharging();
-        assertThat(Utils.containsIncompatibleChargers(mContext, "tag")).isTrue();
+        assertThat(Utils.containsIncompatibleChargers(mContext, TAG)).isTrue();
     }
 
     @Test
@@ -457,7 +465,7 @@
         setupIncompatibleCharging();
         when(mUsbPortStatus.getComplianceWarnings()).thenReturn(new int[1]);
 
-        assertThat(Utils.containsIncompatibleChargers(mContext, "tag")).isFalse();
+        assertThat(Utils.containsIncompatibleChargers(mContext, TAG)).isFalse();
     }
 
     @Test
@@ -465,7 +473,7 @@
         setupIncompatibleCharging();
         when(mUsbPort.supportsComplianceWarnings()).thenReturn(false);
 
-        assertThat(Utils.containsIncompatibleChargers(mContext, "tag")).isFalse();
+        assertThat(Utils.containsIncompatibleChargers(mContext, TAG)).isFalse();
     }
 
     @Test
@@ -473,7 +481,16 @@
         setupIncompatibleCharging();
         when(mUsbPortStatus.isConnected()).thenReturn(false);
 
-        assertThat(Utils.containsIncompatibleChargers(mContext, "tag")).isFalse();
+        assertThat(Utils.containsIncompatibleChargers(mContext, TAG)).isFalse();
+    }
+
+    @Test
+    public void containsIncompatibleChargers_disableWarning_returnFalse() {
+        setupIncompatibleCharging();
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Utils.INCOMPATIBLE_CHARGER_WARNING_DISABLED, 1);
+
+        assertThat(Utils.containsIncompatibleChargers(mContext, TAG)).isFalse();
     }
 
     private void setupIncompatibleCharging() {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
index 3361a66..8c316d1 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
@@ -46,6 +46,7 @@
 import org.robolectric.RuntimeEnvironment;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 @RunWith(RobolectricTestRunner.class)
@@ -396,6 +397,21 @@
     }
 
     @Test
+    public void dispatchActiveDeviceChanged_callExpectedOnActiveDeviceChanged() {
+        mBluetoothEventManager.registerCallback(mBluetoothCallback);
+        when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(
+                Collections.singletonList(mCachedDevice1));
+
+        mBluetoothEventManager.dispatchActiveDeviceChanged(mCachedDevice1,
+                BluetoothProfile.HEARING_AID);
+
+        verify(mCachedDeviceManager).onActiveDeviceChanged(mCachedDevice1);
+        verify(mBluetoothCallback).onActiveDeviceChanged(mCachedDevice1,
+                BluetoothProfile.HEARING_AID);
+    }
+
+    @Test
     public void showUnbondMessage_reasonAuthTimeout_showCorrectedErrorCode() {
         mIntent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
         mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index 4b3820e..7e7c76e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -17,7 +17,9 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
@@ -604,4 +606,20 @@
         verify(mDevice2).setPhonebookAccessPermission(BluetoothDevice.ACCESS_ALLOWED);
         verify(mDevice2).createBond(BluetoothDevice.TRANSPORT_LE);
     }
+
+    @Test
+    public void onActiveDeviceChanged_validHiSyncId_callExpectedFunction() {
+        mHearingAidDeviceManager = spy(new HearingAidDeviceManager(mContext, mLocalBluetoothManager,
+                mCachedDeviceManager.mCachedDevices));
+        doNothing().when(mHearingAidDeviceManager).onActiveDeviceChanged(any());
+        mCachedDeviceManager.mHearingAidDeviceManager = mHearingAidDeviceManager;
+        when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
+        cachedDevice1.setHearingAidInfo(
+                new HearingAidInfo.Builder().setHiSyncId(HISYNCID1).build());
+
+        mCachedDeviceManager.onActiveDeviceChanged(cachedDevice1);
+
+        verify(mHearingAidDeviceManager).onActiveDeviceChanged(cachedDevice1);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CsipDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CsipDeviceManagerTest.java
new file mode 100644
index 0000000..9b41bc4
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CsipDeviceManagerTest.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothCsipSetCoordinator;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.os.Parcel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class CsipDeviceManagerTest {
+    private final static String DEVICE_NAME_1 = "TestName_1";
+    private final static String DEVICE_NAME_2 = "TestName_2";
+    private final static String DEVICE_NAME_3 = "TestName_3";
+    private final static String DEVICE_ALIAS_1 = "TestAlias_1";
+    private final static String DEVICE_ALIAS_2 = "TestAlias_2";
+    private final static String DEVICE_ALIAS_3 = "TestAlias_3";
+    private final static String DEVICE_ADDRESS_1 = "AA:BB:CC:DD:EE:11";
+    private final static String DEVICE_ADDRESS_2 = "AA:BB:CC:DD:EE:22";
+    private final static String DEVICE_ADDRESS_3 = "AA:BB:CC:DD:EE:33";
+    private final static int GROUP1 = 1;
+    private final BluetoothClass DEVICE_CLASS_1 =
+            createBtClass(BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES);
+    private final BluetoothClass DEVICE_CLASS_2 =
+            createBtClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE);
+
+    @Mock
+    private LocalBluetoothManager mLocalBluetoothManager;
+    @Mock
+    private LocalBluetoothProfileManager mLocalProfileManager;
+    @Mock
+    private BluetoothEventManager mBluetoothEventManager;
+    @Mock
+    private BluetoothDevice mDevice1;
+    @Mock
+    private BluetoothDevice mDevice2;
+    @Mock
+    private BluetoothDevice mDevice3;
+    @Mock
+    private HeadsetProfile mHfpProfile;
+    @Mock
+    private A2dpProfile mA2dpProfile;
+    @Mock
+    private LeAudioProfile mLeAudioProfile;
+
+    private CachedBluetoothDevice mCachedDevice1;
+    private CachedBluetoothDevice mCachedDevice2;
+    private CachedBluetoothDevice mCachedDevice3;
+    private CachedBluetoothDeviceManager mCachedDeviceManager;
+    private CsipDeviceManager mCsipDeviceManager;
+    private Context mContext;
+    private List<CachedBluetoothDevice> mCachedDevices = new ArrayList<CachedBluetoothDevice>();
+
+
+    private BluetoothClass createBtClass(int deviceClass) {
+        Parcel p = Parcel.obtain();
+        p.writeInt(deviceClass);
+        p.setDataPosition(0); // reset position of parcel before passing to constructor
+
+        BluetoothClass bluetoothClass = BluetoothClass.CREATOR.createFromParcel(p);
+        p.recycle();
+        return bluetoothClass;
+    }
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = RuntimeEnvironment.application;
+        when(mDevice1.getAddress()).thenReturn(DEVICE_ADDRESS_1);
+        when(mDevice2.getAddress()).thenReturn(DEVICE_ADDRESS_2);
+        when(mDevice3.getAddress()).thenReturn(DEVICE_ADDRESS_3);
+        when(mDevice1.getName()).thenReturn(DEVICE_NAME_1);
+        when(mDevice2.getName()).thenReturn(DEVICE_NAME_2);
+        when(mDevice3.getName()).thenReturn(DEVICE_NAME_3);
+        when(mDevice1.getAlias()).thenReturn(DEVICE_ALIAS_1);
+        when(mDevice2.getAlias()).thenReturn(DEVICE_ALIAS_2);
+        when(mDevice3.getAlias()).thenReturn(DEVICE_ALIAS_3);
+        when(mDevice1.getBluetoothClass()).thenReturn(DEVICE_CLASS_1);
+        when(mDevice2.getBluetoothClass()).thenReturn(DEVICE_CLASS_2);
+        when(mDevice3.getBluetoothClass()).thenReturn(DEVICE_CLASS_2);
+        when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
+        when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalProfileManager);
+        when(mLocalProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile);
+        when(mLocalProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
+        when(mLocalProfileManager.getHeadsetProfile()).thenReturn(mHfpProfile);
+
+        when(mLeAudioProfile.getConnectedGroupLeadDevice(anyInt())).thenReturn(null);
+        mCachedDeviceManager = new CachedBluetoothDeviceManager(mContext, mLocalBluetoothManager);
+        when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
+
+        mCachedDevices = mCachedDeviceManager.mCachedDevices;
+        mCsipDeviceManager = mCachedDeviceManager.mCsipDeviceManager;
+
+        // Setup the default for testing
+        mCachedDevice1 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice1));
+        mCachedDevice2 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice2));
+        mCachedDevice3 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice3));
+
+        mCachedDevice1.setGroupId(GROUP1);
+        mCachedDevice2.setGroupId(GROUP1);
+        mCachedDevice1.addMemberDevice(mCachedDevice2);
+        mCachedDevices.add(mCachedDevice1);
+        mCachedDevices.add(mCachedDevice3);
+
+        List<LocalBluetoothProfile> profiles = new ArrayList<LocalBluetoothProfile>();
+        profiles.add(mHfpProfile);
+        profiles.add(mA2dpProfile);
+        profiles.add(mLeAudioProfile);
+        when(mCachedDevice1.getConnectableProfiles()).thenReturn(profiles);
+        when(mCachedDevice1.isConnected()).thenReturn(true);
+
+        profiles.clear();
+        profiles.add(mLeAudioProfile);
+        when(mCachedDevice2.getConnectableProfiles()).thenReturn(profiles);
+        when(mCachedDevice2.isConnected()).thenReturn(true);
+
+        profiles.clear();
+        profiles.add(mHfpProfile);
+        profiles.add(mA2dpProfile);
+        when(mCachedDevice3.getConnectableProfiles()).thenReturn(profiles);
+        when(mCachedDevice3.isConnected()).thenReturn(true);
+
+    }
+
+    @Test
+    public void onProfileConnectionStateChangedIfProcessed_profileIsConnecting_returnOff() {
+        assertThat(mCsipDeviceManager.onProfileConnectionStateChangedIfProcessed(mCachedDevice1,
+                BluetoothProfile.STATE_CONNECTING)).isFalse();
+    }
+
+    @Test
+    public void onProfileConnectionStateChangedIfProcessed_profileIsDisconnecting_returnOff() {
+        assertThat(mCsipDeviceManager.onProfileConnectionStateChangedIfProcessed(mCachedDevice1,
+                BluetoothProfile.STATE_DISCONNECTING)).isFalse();
+    }
+
+    @Test
+    public void updateRelationshipOfGroupDevices_invalidGroupId_returnOff() {
+        assertThat(mCsipDeviceManager.updateRelationshipOfGroupDevices(
+                BluetoothCsipSetCoordinator.GROUP_ID_INVALID)).isFalse();
+    }
+
+    @Test
+    public void getGroupDevicesFromAllOfDevicesList_invalidGroupId_returnEmpty() {
+        assertThat(mCsipDeviceManager.getGroupDevicesFromAllOfDevicesList(
+                BluetoothCsipSetCoordinator.GROUP_ID_INVALID).isEmpty()).isTrue();
+    }
+
+    @Test
+    public void getGroupDevicesFromAllOfDevicesList_validGroupId_returnGroupDevices() {
+        List<CachedBluetoothDevice> expectedList = new ArrayList<>();
+        expectedList.add(mCachedDevice1);
+        expectedList.add(mCachedDevice2);
+
+        assertThat(mCsipDeviceManager.getGroupDevicesFromAllOfDevicesList(GROUP1))
+                .isEqualTo(expectedList);
+    }
+
+    @Test
+    public void getPreferredMainDevice_dualModeDevice_returnDualModeDevice() {
+        CachedBluetoothDevice expectedDevice = mCachedDevice1;
+
+        assertThat(
+                mCsipDeviceManager.getPreferredMainDevice(GROUP1,
+                        mCsipDeviceManager.getGroupDevicesFromAllOfDevicesList(GROUP1)))
+                .isEqualTo(expectedDevice);
+    }
+
+    @Test
+    public void getPreferredMainDevice_noConnectedDualModeDevice_returnLeadDevice() {
+        when(mCachedDevice1.isConnected()).thenReturn(false);
+        when(mLeAudioProfile.getConnectedGroupLeadDevice(anyInt())).thenReturn(mDevice2);
+        CachedBluetoothDevice expectedDevice = mCachedDevice2;
+
+        assertThat(
+                mCsipDeviceManager.getPreferredMainDevice(GROUP1,
+                        mCsipDeviceManager.getGroupDevicesFromAllOfDevicesList(GROUP1)))
+                .isEqualTo(expectedDevice);
+    }
+
+    @Test
+    public void getPreferredMainDevice_noConnectedDualModeDeviceNoLeadDevice_returnConnectedOne() {
+        when(mCachedDevice1.isConnected()).thenReturn(false);
+        when(mCachedDevice2.isConnected()).thenReturn(true);
+        CachedBluetoothDevice expectedDevice = mCachedDevice2;
+
+        assertThat(
+                mCsipDeviceManager.getPreferredMainDevice(GROUP1,
+                        mCsipDeviceManager.getGroupDevicesFromAllOfDevicesList(GROUP1)))
+                .isEqualTo(expectedDevice);
+    }
+
+    @Test
+    public void getPreferredMainDevice_noConnectedDevice_returnDualModeDevice() {
+        when(mCachedDevice1.isConnected()).thenReturn(false);
+        when(mCachedDevice2.isConnected()).thenReturn(false);
+        CachedBluetoothDevice expectedDevice = mCachedDevice1;
+
+        assertThat(
+                mCsipDeviceManager.getPreferredMainDevice(GROUP1,
+                        mCsipDeviceManager.getGroupDevicesFromAllOfDevicesList(GROUP1)))
+                .isEqualTo(expectedDevice);
+    }
+
+    @Test
+    public void getPreferredMainDevice_noConnectedDeviceNoDualMode_returnFirstOneDevice() {
+        when(mCachedDevice1.isConnected()).thenReturn(false);
+        when(mCachedDevice2.isConnected()).thenReturn(false);
+        List<LocalBluetoothProfile> profiles = new ArrayList<LocalBluetoothProfile>();
+        profiles.add(mLeAudioProfile);
+        when(mCachedDevice1.getConnectableProfiles()).thenReturn(profiles);
+        CachedBluetoothDevice expectedDevice = mCachedDevice1;
+
+        assertThat(
+                mCsipDeviceManager.getPreferredMainDevice(GROUP1,
+                        mCsipDeviceManager.getGroupDevicesFromAllOfDevicesList(GROUP1)))
+                .isEqualTo(expectedDevice);
+    }
+
+    @Test
+    public void addMemberDevicesIntoMainDevice_noPreferredDevice_returnFalseAndNoChangeList() {
+        CachedBluetoothDevice preferredDevice = null;
+        List<CachedBluetoothDevice> expectedList = new ArrayList<>();
+        for (CachedBluetoothDevice item : mCachedDevices) {
+            expectedList.add(item);
+        }
+
+        assertThat(mCsipDeviceManager.addMemberDevicesIntoMainDevice(GROUP1, preferredDevice))
+                .isFalse();
+        for (CachedBluetoothDevice expectedItem : expectedList) {
+            assertThat(mCachedDevices.contains(expectedItem)).isTrue();
+        }
+    }
+
+    @Test
+    public void addMemberDevicesIntoMainDevice_preferredDeviceIsMainAndNoOtherInList_noChangeList()
+    {
+        // Condition: The preferredDevice is main and no other main device in top list
+        // Expected Result: return false and the list is no changed
+        CachedBluetoothDevice preferredDevice = mCachedDevice1;
+        List<CachedBluetoothDevice> expectedList = new ArrayList<>();
+        for (CachedBluetoothDevice item : mCachedDevices) {
+            expectedList.add(item);
+        }
+
+        assertThat(mCsipDeviceManager.addMemberDevicesIntoMainDevice(GROUP1, preferredDevice))
+                .isFalse();
+        for (CachedBluetoothDevice expectedItem : expectedList) {
+            assertThat(mCachedDevices.contains(expectedItem)).isTrue();
+        }
+    }
+
+    @Test
+    public void addMemberDevicesIntoMainDevice_preferredDeviceIsMainAndTwoMain_returnTrue() {
+        // Condition: The preferredDevice is main and there is another main device in top list
+        // Expected Result: return true and there is the preferredDevice in top list
+        CachedBluetoothDevice preferredDevice = mCachedDevice1;
+        mCachedDevice1.getMemberDevice().clear();
+        mCachedDevices.clear();
+        mCachedDevices.add(preferredDevice);
+        mCachedDevices.add(mCachedDevice2);
+        mCachedDevices.add(mCachedDevice3);
+
+
+        assertThat(mCsipDeviceManager.addMemberDevicesIntoMainDevice(GROUP1, preferredDevice))
+                .isTrue();
+        assertThat(mCachedDevices.contains(preferredDevice)).isTrue();
+        assertThat(mCachedDevices.contains(mCachedDevice2)).isFalse();
+        assertThat(mCachedDevices.contains(mCachedDevice3)).isTrue();
+        assertThat(preferredDevice.getMemberDevice()).contains(mCachedDevice2);
+    }
+
+    @Test
+    public void addMemberDevicesIntoMainDevice_preferredDeviceIsMember_returnTrue() {
+        // Condition: The preferredDevice is member
+        // Expected Result: return true and there is the preferredDevice in top list
+        CachedBluetoothDevice preferredDevice = mCachedDevice2;
+        BluetoothDevice expectedMainBluetoothDevice = preferredDevice.getDevice();
+
+        assertThat(mCsipDeviceManager.addMemberDevicesIntoMainDevice(GROUP1, preferredDevice))
+                .isTrue();
+        // expected main is mCachedDevice1 which is the main of preferredDevice, since system
+        // switch the relationship between preferredDevice and the main of preferredDevice
+        assertThat(mCachedDevices.contains(mCachedDevice1)).isTrue();
+        assertThat(mCachedDevices.contains(mCachedDevice2)).isFalse();
+        assertThat(mCachedDevices.contains(mCachedDevice3)).isTrue();
+        assertThat(mCachedDevice1.getMemberDevice()).contains(mCachedDevice2);
+        assertThat(mCachedDevice1.getDevice()).isEqualTo(expectedMainBluetoothDevice);
+    }
+
+    @Test
+    public void addMemberDevicesIntoMainDevice_preferredDeviceIsMemberAndTwoMain_returnTrue() {
+        // Condition: The preferredDevice is member and there are two main device in top list
+        // Expected Result: return true and there is the preferredDevice in top list
+        CachedBluetoothDevice preferredDevice = mCachedDevice2;
+        BluetoothDevice expectedMainBluetoothDevice = preferredDevice.getDevice();
+        mCachedDevice3.setGroupId(GROUP1);
+
+        assertThat(mCsipDeviceManager.addMemberDevicesIntoMainDevice(GROUP1, preferredDevice))
+                .isTrue();
+        // expected main is mCachedDevice1 which is the main of preferredDevice, since system
+        // switch the relationship between preferredDevice and the main of preferredDevice
+        assertThat(mCachedDevices.contains(mCachedDevice1)).isTrue();
+        assertThat(mCachedDevices.contains(mCachedDevice2)).isFalse();
+        assertThat(mCachedDevices.contains(mCachedDevice3)).isFalse();
+        assertThat(mCachedDevice1.getMemberDevice()).contains(mCachedDevice2);
+        assertThat(mCachedDevice1.getMemberDevice()).contains(mCachedDevice3);
+        assertThat(mCachedDevice1.getMemberDevice()).contains(mCachedDevice3);
+        assertThat(mCachedDevice1.getDevice()).isEqualTo(expectedMainBluetoothDevice);
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
index a839136..0d5de88 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
@@ -478,37 +478,24 @@
     }
 
     @Test
-    public void onProfileConnectionStateChanged_connected_callSetStrategies() {
+    public void onActiveDeviceChanged_connected_callSetStrategies() {
         when(mHelper.getMatchedHearingDeviceAttributes(mCachedDevice1)).thenReturn(
                 mHearingDeviceAttribute);
+        when(mCachedDevice1.isActiveDevice(BluetoothProfile.HEARING_AID)).thenReturn(true);
 
-        mHearingAidDeviceManager.onProfileConnectionStateChangedIfProcessed(mCachedDevice1,
-                BluetoothProfile.STATE_CONNECTED);
+        mHearingAidDeviceManager.onActiveDeviceChanged(mCachedDevice1);
 
         verify(mHelper, atLeastOnce()).setPreferredDeviceRoutingStrategies(
                 eq(List.of(mAudioStrategy)), any(AudioDeviceAttributes.class), anyInt());
     }
 
     @Test
-    public void onProfileConnectionStateChanged_disconnected_callSetStrategiesWithAutoValue() {
+    public void onActiveDeviceChanged_disconnected_callSetStrategiesWithAutoValue() {
         when(mHelper.getMatchedHearingDeviceAttributes(mCachedDevice1)).thenReturn(
                 mHearingDeviceAttribute);
+        when(mCachedDevice1.isActiveDevice(BluetoothProfile.HEARING_AID)).thenReturn(false);
 
-        mHearingAidDeviceManager.onProfileConnectionStateChangedIfProcessed(mCachedDevice1,
-                BluetoothProfile.STATE_DISCONNECTED);
-
-        verify(mHelper, atLeastOnce()).setPreferredDeviceRoutingStrategies(
-                eq(List.of(mAudioStrategy)), /* hearingDevice= */ isNull(),
-                eq(HearingAidAudioRoutingConstants.RoutingValue.AUTO));
-    }
-    @Test
-    public void onProfileConnectionStateChanged_unpairing_callSetStrategiesWithAutoValue() {
-        when(mHelper.getMatchedHearingDeviceAttributes(mCachedDevice1)).thenReturn(
-                mHearingDeviceAttribute);
-
-        when(mCachedDevice1.getUnpairing()).thenReturn(true);
-        mHearingAidDeviceManager.onProfileConnectionStateChangedIfProcessed(mCachedDevice1,
-                BluetoothProfile.STATE_DISCONNECTED);
+        mHearingAidDeviceManager.onActiveDeviceChanged(mCachedDevice1);
 
         verify(mHelper, atLeastOnce()).setPreferredDeviceRoutingStrategies(
                 eq(List.of(mAudioStrategy)), /* hearingDevice= */ isNull(),
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/dream/DreamBackendTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/dream/DreamBackendTest.java
index 22ec12d..2edf403 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/dream/DreamBackendTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/dream/DreamBackendTest.java
@@ -28,6 +28,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Resources;
+import android.provider.Settings;
 
 import org.junit.After;
 import org.junit.Before;
@@ -84,6 +85,7 @@
 
     @Test
     public void testComplicationsEnabledByDefault() {
+        setControlsEnabledOnLockscreen(true);
         assertThat(mBackend.getComplicationsEnabled()).isTrue();
         assertThat(mBackend.getEnabledComplications()).containsExactlyElementsIn(
                 SUPPORTED_DREAM_COMPLICATIONS_LIST);
@@ -91,6 +93,7 @@
 
     @Test
     public void testEnableComplicationExplicitly() {
+        setControlsEnabledOnLockscreen(true);
         mBackend.setComplicationsEnabled(true);
         assertThat(mBackend.getEnabledComplications()).containsExactlyElementsIn(
                 SUPPORTED_DREAM_COMPLICATIONS_LIST);
@@ -99,6 +102,7 @@
 
     @Test
     public void testDisableComplications() {
+        setControlsEnabledOnLockscreen(true);
         mBackend.setComplicationsEnabled(false);
         assertThat(mBackend.getEnabledComplications())
                 .containsExactly(COMPLICATION_TYPE_HOME_CONTROLS);
@@ -107,6 +111,7 @@
 
     @Test
     public void testHomeControlsDisabled_ComplicationsEnabled() {
+        setControlsEnabledOnLockscreen(true);
         mBackend.setComplicationsEnabled(true);
         mBackend.setHomeControlsEnabled(false);
         // Home controls should not be enabled, only date and time.
@@ -118,6 +123,7 @@
 
     @Test
     public void testHomeControlsDisabled_ComplicationsDisabled() {
+        setControlsEnabledOnLockscreen(true);
         mBackend.setComplicationsEnabled(false);
         mBackend.setHomeControlsEnabled(false);
         assertThat(mBackend.getEnabledComplications()).isEmpty();
@@ -125,9 +131,9 @@
 
     @Test
     public void testHomeControlsEnabled_ComplicationsDisabled() {
+        setControlsEnabledOnLockscreen(true);
         mBackend.setComplicationsEnabled(false);
         mBackend.setHomeControlsEnabled(true);
-        // Home controls should not be enabled, only date and time.
         final List<Integer> enabledComplications =
                 Collections.singletonList(COMPLICATION_TYPE_HOME_CONTROLS);
         assertThat(mBackend.getEnabledComplications())
@@ -136,9 +142,9 @@
 
     @Test
     public void testHomeControlsEnabled_ComplicationsEnabled() {
+        setControlsEnabledOnLockscreen(true);
         mBackend.setComplicationsEnabled(true);
         mBackend.setHomeControlsEnabled(true);
-        // Home controls should not be enabled, only date and time.
         final List<Integer> enabledComplications =
                 Arrays.asList(
                         COMPLICATION_TYPE_HOME_CONTROLS,
@@ -148,4 +154,26 @@
         assertThat(mBackend.getEnabledComplications())
                 .containsExactlyElementsIn(enabledComplications);
     }
+
+    @Test
+    public void testHomeControlsEnabled_lockscreenDisabled() {
+        setControlsEnabledOnLockscreen(false);
+        mBackend.setComplicationsEnabled(true);
+        mBackend.setHomeControlsEnabled(true);
+        // Home controls should not be enabled, only date and time.
+        final List<Integer> enabledComplications =
+                Arrays.asList(
+                        COMPLICATION_TYPE_DATE,
+                        COMPLICATION_TYPE_TIME
+                );
+        assertThat(mBackend.getEnabledComplications())
+                .containsExactlyElementsIn(enabledComplications);
+    }
+
+    private void setControlsEnabledOnLockscreen(boolean enabled) {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(),
+                Settings.Secure.LOCKSCREEN_SHOW_CONTROLS,
+                enabled ? 1 : 0);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java
index c45b7f3..67a045e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java
@@ -16,11 +16,14 @@
 
 package com.android.settingslib.media;
 
-import static android.media.MediaRoute2Info.FEATURE_REMOTE_AUDIO_PLAYBACK;
-import static android.media.MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK;
-import static android.media.MediaRoute2Info.FEATURE_REMOTE_VIDEO_PLAYBACK;
 import static android.media.MediaRoute2Info.TYPE_GROUP;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_CAR;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_COMPUTER;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_GAME_CONSOLE;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_SMARTWATCH;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_TABLET;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_TABLET_DOCKED;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -41,8 +44,6 @@
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 
-import java.util.ArrayList;
-
 @RunWith(RobolectricTestRunner.class)
 public class InfoMediaDeviceTest {
 
@@ -100,40 +101,47 @@
     public void getDrawableResId_returnCorrectResId() {
         when(mRouteInfo.getType()).thenReturn(TYPE_REMOTE_TV);
 
-        assertThat(mInfoMediaDevice.getDrawableResId()).isEqualTo(
+        assertThat(mInfoMediaDevice.getDrawableResIdByType()).isEqualTo(
                 R.drawable.ic_media_display_device);
 
         when(mRouteInfo.getType()).thenReturn(TYPE_REMOTE_SPEAKER);
 
-        assertThat(mInfoMediaDevice.getDrawableResId()).isEqualTo(
+        assertThat(mInfoMediaDevice.getDrawableResIdByType()).isEqualTo(
                 R.drawable.ic_media_speaker_device);
 
         when(mRouteInfo.getType()).thenReturn(TYPE_GROUP);
 
-        assertThat(mInfoMediaDevice.getDrawableResId()).isEqualTo(R.drawable.ic_media_group_device);
-    }
-
-    @Test
-    public void getDrawableResIdByFeature_returnCorrectResId() {
-        final ArrayList<String> features = new ArrayList<>();
-        features.add(FEATURE_REMOTE_VIDEO_PLAYBACK);
-        when(mRouteInfo.getFeatures()).thenReturn(features);
-
-        assertThat(mInfoMediaDevice.getDrawableResIdByFeature()).isEqualTo(
-                R.drawable.ic_media_display_device);
-
-        features.clear();
-        features.add(FEATURE_REMOTE_AUDIO_PLAYBACK);
-        when(mRouteInfo.getFeatures()).thenReturn(features);
-
-        assertThat(mInfoMediaDevice.getDrawableResIdByFeature()).isEqualTo(
-                R.drawable.ic_media_speaker_device);
-
-        features.clear();
-        features.add(FEATURE_REMOTE_GROUP_PLAYBACK);
-        when(mRouteInfo.getFeatures()).thenReturn(features);
-
-        assertThat(mInfoMediaDevice.getDrawableResIdByFeature()).isEqualTo(
+        assertThat(mInfoMediaDevice.getDrawableResIdByType()).isEqualTo(
                 R.drawable.ic_media_group_device);
+
+        when(mRouteInfo.getType()).thenReturn(TYPE_REMOTE_TABLET);
+
+        assertThat(mInfoMediaDevice.getDrawableResIdByType()).isEqualTo(
+                R.drawable.ic_media_tablet);
+
+        when(mRouteInfo.getType()).thenReturn(TYPE_REMOTE_TABLET_DOCKED);
+
+        assertThat(mInfoMediaDevice.getDrawableResIdByType()).isEqualTo(
+                R.drawable.ic_dock_device);
+
+        when(mRouteInfo.getType()).thenReturn(TYPE_REMOTE_COMPUTER);
+
+        assertThat(mInfoMediaDevice.getDrawableResIdByType()).isEqualTo(
+                R.drawable.ic_media_computer);
+
+        when(mRouteInfo.getType()).thenReturn(TYPE_REMOTE_GAME_CONSOLE);
+
+        assertThat(mInfoMediaDevice.getDrawableResIdByType()).isEqualTo(
+                R.drawable.ic_media_game_console);
+
+        when(mRouteInfo.getType()).thenReturn(TYPE_REMOTE_CAR);
+
+        assertThat(mInfoMediaDevice.getDrawableResIdByType()).isEqualTo(
+                R.drawable.ic_media_car);
+
+        when(mRouteInfo.getType()).thenReturn(TYPE_REMOTE_SMARTWATCH);
+
+        assertThat(mInfoMediaDevice.getDrawableResIdByType()).isEqualTo(
+                R.drawable.ic_media_smartwatch);
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/CreateUserDialogControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/CreateUserDialogControllerTest.java
new file mode 100644
index 0000000..e989ed2
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/CreateUserDialogControllerTest.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.users;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.RadioButton;
+
+import androidx.fragment.app.FragmentActivity;
+
+import com.android.settingslib.R;
+import com.android.settingslib.RestrictedLockUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.android.controller.ActivityController;
+
+@RunWith(RobolectricTestRunner.class)
+public class CreateUserDialogControllerTest {
+
+    @Mock
+    private ActivityStarter mActivityStarter;
+
+    private boolean mPhotoRestrictedByBase;
+    private Activity mActivity;
+    private TestCreateUserDialogController mUnderTest;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mActivity = spy(ActivityController.of(new FragmentActivity()).get());
+        mActivity.setTheme(R.style.Theme_AppCompat_DayNight);
+        mUnderTest = new TestCreateUserDialogController();
+        mPhotoRestrictedByBase = false;
+    }
+
+    @Test
+    public void positiveButton_grantAdminStage_noValue_OkButtonShouldBeDisabled() {
+        Runnable cancelCallback = mock(Runnable.class);
+
+        final AlertDialog dialog = (AlertDialog) mUnderTest.createDialog(mActivity,
+                mActivityStarter, true, null,
+                cancelCallback);
+        dialog.show();
+        assertThat(dialog.findViewById(R.id.button_ok).isEnabled()).isEqualTo(true);
+        Button next = dialog.findViewById(R.id.button_ok);
+        next.performClick();
+        assertThat(dialog.findViewById(R.id.button_ok).isEnabled()).isEqualTo(false);
+        ((RadioButton) dialog.findViewById(R.id.grant_admin_yes)).setChecked(true);
+        assertThat(dialog.findViewById(R.id.button_ok).isEnabled()).isEqualTo(true);
+        dialog.dismiss();
+    }
+
+    @Test
+    public void positiveButton_MultipleAdminDisabled_shouldSkipGrantAdminStage() {
+        Runnable cancelCallback = mock(Runnable.class);
+
+        final AlertDialog dialog = (AlertDialog) mUnderTest.createDialog(mActivity,
+                mActivityStarter, false, null,
+                cancelCallback);
+        dialog.show();
+        assertThat(dialog.findViewById(R.id.grant_admin_view).getVisibility()).isEqualTo(View.GONE);
+        assertThat(dialog.findViewById(R.id.button_ok).isEnabled()).isEqualTo(true);
+        Button next = dialog.findViewById(R.id.button_ok);
+        next.performClick();
+        assertThat(dialog.findViewById(R.id.grant_admin_view).getVisibility()).isEqualTo(View.GONE);
+        assertThat(dialog.findViewById(R.id.button_ok).isEnabled()).isEqualTo(true);
+        Button back = dialog.findViewById(R.id.button_cancel);
+        back.performClick();
+        assertThat(dialog.findViewById(R.id.grant_admin_view).getVisibility()).isEqualTo(View.GONE);
+        dialog.dismiss();
+    }
+
+    @Test
+    public void editUserInfoController_shouldOnlyBeVisibleOnLastStage() {
+        Runnable cancelCallback = mock(Runnable.class);
+        final AlertDialog dialog = (AlertDialog) mUnderTest.createDialog(mActivity,
+                mActivityStarter, true, null,
+                cancelCallback);
+        dialog.show();
+        assertThat(dialog.findViewById(R.id.user_info_scroll).getVisibility()).isEqualTo(View.GONE);
+        Button next = dialog.findViewById(R.id.button_ok);
+        next.performClick();
+        ((RadioButton) dialog.findViewById(R.id.grant_admin_yes)).setChecked(true);
+        assertThat(dialog.findViewById(R.id.user_info_scroll).getVisibility()).isEqualTo(View.GONE);
+        next.performClick();
+        assertThat(dialog.findViewById(R.id.user_info_scroll).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        dialog.dismiss();
+    }
+
+    @Test
+    public void positiveButton_MultipleAdminEnabled_shouldShowGrantAdminStage() {
+        Runnable cancelCallback = mock(Runnable.class);
+
+        final AlertDialog dialog = (AlertDialog) mUnderTest.createDialog(mActivity,
+                mActivityStarter, true, null,
+                cancelCallback);
+        dialog.show();
+        assertThat(dialog.findViewById(R.id.grant_admin_view).getVisibility()).isEqualTo(View.GONE);
+        assertThat(dialog.findViewById(R.id.button_ok).isEnabled()).isEqualTo(true);
+        Button next = dialog.findViewById(R.id.button_ok);
+        next.performClick();
+        assertThat(dialog.findViewById(R.id.grant_admin_view).getVisibility())
+                .isEqualTo(View.VISIBLE);
+        ((RadioButton) dialog.findViewById(R.id.grant_admin_yes)).setChecked(true);
+        next.performClick();
+        assertThat(dialog.findViewById(R.id.grant_admin_view).getVisibility()).isEqualTo(View.GONE);
+        dialog.dismiss();
+    }
+
+    @Test
+    public void cancelCallback_isCalled_whenCancelled() {
+        NewUserData successCallback = mock(NewUserData.class);
+        Runnable cancelCallback = mock(Runnable.class);
+
+        AlertDialog dialog = (AlertDialog) mUnderTest.createDialog(mActivity,
+                mActivityStarter, true, successCallback,
+                cancelCallback);
+        dialog.show();
+        dialog.cancel();
+        verifyNoInteractions(successCallback);
+        verify(cancelCallback, times(1))
+                .run();
+    }
+
+    @Test
+    public void cancelCallback_isCalled_whenNegativeButtonClickedOnFirstStage() {
+        NewUserData successCallback = mock(NewUserData.class);
+        Runnable cancelCallback = mock(Runnable.class);
+
+        AlertDialog dialog = (AlertDialog) mUnderTest.createDialog(mActivity,
+                mActivityStarter, true, successCallback,
+                cancelCallback);
+        dialog.show();
+        Button back = dialog.findViewById(R.id.button_cancel);
+        back.performClick();
+        verifyNoInteractions(successCallback);
+        verify(cancelCallback, times(1))
+                .run();
+    }
+
+    @Test
+    public void cancelCallback_isNotCalled_whenNegativeButtonClickedOnSecondStage() {
+        NewUserData successCallback = mock(NewUserData.class);
+        Runnable cancelCallback = mock(Runnable.class);
+
+        AlertDialog dialog = (AlertDialog) mUnderTest.createDialog(mActivity,
+                mActivityStarter, true, successCallback,
+                cancelCallback);
+        dialog.show();
+        Button next = dialog.findViewById(R.id.button_ok);
+        next.performClick();
+        Button back = dialog.findViewById(R.id.button_cancel);
+        back.performClick();
+        verifyNoInteractions(successCallback);
+        verifyNoInteractions(cancelCallback);
+        dialog.dismiss();
+    }
+
+    @Test
+    public void successCallback_isCalled_setNameAndAdminStatus() {
+        NewUserData successCallback = mock(NewUserData.class);
+        Runnable cancelCallback = mock(Runnable.class);
+
+        AlertDialog dialog = (AlertDialog) mUnderTest.createDialog(mActivity,
+                mActivityStarter, true, successCallback,
+                cancelCallback);
+        // No photo chosen
+        when(mUnderTest.getPhotoController().getNewUserPhotoDrawable()).thenReturn(null);
+        dialog.show();
+        Button next = dialog.findViewById(R.id.button_ok);
+        next.performClick();
+        ((RadioButton) dialog.findViewById(R.id.grant_admin_yes)).setChecked(true);
+        next.performClick();
+        String expectedNewName = "Test";
+        EditText editText = dialog.findViewById(R.id.user_name);
+        editText.setText(expectedNewName);
+        next.performClick();
+        verify(successCallback, times(1))
+                .onSuccess(expectedNewName, null, true);
+    }
+
+    @Test
+    public void successCallback_isCalled_setName_MultipleAdminDisabled() {
+        NewUserData successCallback = mock(NewUserData.class);
+        Runnable cancelCallback = mock(Runnable.class);
+
+        AlertDialog dialog = (AlertDialog) mUnderTest.createDialog(mActivity,
+                mActivityStarter, false, successCallback,
+                cancelCallback);
+        // No photo chosen
+        when(mUnderTest.getPhotoController().getNewUserPhotoDrawable()).thenReturn(null);
+        dialog.show();
+        Button next = dialog.findViewById(R.id.button_ok);
+        next.performClick();
+        String expectedNewName = "Test";
+        EditText editText = dialog.findViewById(R.id.user_name);
+        editText.setText(expectedNewName);
+        next.performClick();
+        verify(successCallback, times(1))
+                .onSuccess(expectedNewName, null, false);
+    }
+
+    private class TestCreateUserDialogController extends CreateUserDialogController {
+        private EditUserPhotoController mPhotoController;
+
+        TestCreateUserDialogController() {
+            super("file_authority");
+        }
+
+        private EditUserPhotoController getPhotoController() {
+            return mPhotoController;
+        }
+
+        @Override
+        EditUserPhotoController createEditUserPhotoController(ImageView userPhotoView) {
+            mPhotoController = mock(EditUserPhotoController.class, Answers.RETURNS_DEEP_STUBS);
+            return mPhotoController;
+        }
+        @Override
+        RestrictedLockUtils.EnforcedAdmin getChangePhotoAdminRestriction(Context context) {
+            return null;
+        }
+
+        @Override
+        boolean isChangePhotoRestrictedByBase(Context context) {
+            return mPhotoRestrictedByBase;
+        }
+    }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 1fd84c7..a83bfda 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -785,12 +785,6 @@
                 Settings.Global.ANGLE_EGL_FEATURES,
                 GlobalSettingsProto.Gpu.ANGLE_EGL_FEATURES);
         dumpSetting(s, p,
-                Settings.Global.ANGLE_DEFERLIST,
-                GlobalSettingsProto.Gpu.ANGLE_DEFERLIST);
-        dumpSetting(s, p,
-                Settings.Global.ANGLE_DEFERLIST_MODE,
-                GlobalSettingsProto.Gpu.ANGLE_DEFERLIST_MODE);
-        dumpSetting(s, p,
                 Settings.Global.SHOW_ANGLE_IN_USE_DIALOG_BOX,
                 GlobalSettingsProto.Gpu.SHOW_ANGLE_IN_USE_DIALOG);
         dumpSetting(s, p,
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 9d3620e..873b434 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -116,6 +116,7 @@
                     Settings.Global.ADD_USERS_WHEN_LOCKED,
                     Settings.Global.AIRPLANE_MODE_ON,
                     Settings.Global.AIRPLANE_MODE_RADIOS,
+                    Settings.Global.ALLOW_WORK_PROFILE_TELEPHONY_FOR_NON_DPM_ROLE_HOLDERS,
                     Settings.Global.SATELLITE_MODE_RADIOS,
                     Settings.Global.SATELLITE_MODE_ENABLED,
                     Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
@@ -517,8 +518,6 @@
                     Settings.Global.ANGLE_GL_DRIVER_SELECTION_PKGS,
                     Settings.Global.ANGLE_GL_DRIVER_SELECTION_VALUES,
                     Settings.Global.ANGLE_EGL_FEATURES,
-                    Settings.Global.ANGLE_DEFERLIST,
-                    Settings.Global.ANGLE_DEFERLIST_MODE,
                     Settings.Global.UPDATABLE_DRIVER_ALL_APPS,
                     Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS,
                     Settings.Global.UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS,
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 8b3fd41..43f98c3 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -837,6 +837,8 @@
     <uses-permission android:name="android.permission.USE_ATTESTATION_VERIFICATION_SERVICE" />
     <!-- Permission required for GTS test - GtsCredentialsTestCases -->
     <uses-permission android:name="android.permission.LAUNCH_CREDENTIAL_SELECTOR" />
+    <!-- Permission required for CTS test IntentRedirectionTest -->
+    <uses-permission android:name="android.permission.QUERY_CLONED_APPS" />
 
     <application
         android:label="@string/app_label"
diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING
index bdd941d..aee829d 100644
--- a/packages/SystemUI/TEST_MAPPING
+++ b/packages/SystemUI/TEST_MAPPING
@@ -90,63 +90,6 @@
   //
   // If you don't use @Postsubmit, your new test will immediately
   // block presubmit, which is probably not what you want!
-  "sysui-platinum-postsubmit": [
-    {
-      "name": "PlatformScenarioTests",
-      "options": [
-        {
-            "include-filter": "android.platform.test.scenario.sysui"
-        },
-        {
-            "include-annotation": "android.platform.test.scenario.annotation.Scenario"
-        },
-        {
-            "exclude-annotation": "org.junit.Ignore"
-        },
-        {
-            "exclude-annotation": "androidx.test.filters.FlakyTest"
-        },
-        {
-            "exclude-annotation": "android.platform.test.annotations.FlakyTest"
-        }
-      ]
-    }
-  ],
-  "sysui-staged-platinum-postsubmit": [
-    {
-      "name": "PlatformScenarioTests",
-      "options": [
-        {
-            "include-filter": "android.platform.test.scenario.sysui"
-        },
-        {
-            "include-annotation": "android.platform.test.scenario.annotation.Scenario"
-        },
-        {
-            "exclude-annotation": "org.junit.Ignore"
-        }
-      ]
-    }
-  ],
-  "ironwood-postsubmit": [
-    {
-      "name": "PlatformScenarioTests",
-      "options": [
-        {
-            "include-annotation": "android.platform.test.annotations.IwTest"
-        },
-        {
-            "exclude-annotation": "org.junit.Ignore"
-        },
-        {
-            "include-filter": "android.platform.test.scenario.sysui"
-        },
-        {
-            "exclude-annotation": "android.platform.test.annotations.FlakyTest"
-        }
-      ]
-    }
-  ],
   "auto-end-to-end-postsubmit": [
     {
       "name": "AndroidAutomotiveHomeTests",
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr/strings.xml
index 140caff..0445e8d 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr/strings.xml
@@ -2,7 +2,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="accessibility_menu_service_name" msgid="730136711554740131">"Menu Accessibilité"</string>
-    <string name="accessibility_menu_intro" msgid="3164193281544042394">"Le menu d\'accessibilité s\'affiche en grand sur votre écran pour vous permettre de contrôler votre appareil. Vous pouvez verrouiller votre appareil, ajuster le volume et la luminosité, réaliser des captures d\'écran, et plus encore."</string>
+    <string name="accessibility_menu_intro" msgid="3164193281544042394">"Le menu Accessibilité s\'affiche en grand sur votre écran pour vous permettre de contrôler votre appareil. Vous pouvez verrouiller votre appareil, ajuster le volume et la luminosité, réaliser des captures d\'écran, et plus encore."</string>
     <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
     <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
     <string name="a11y_settings_label" msgid="3977714687248445050">"Accessibilité"</string>
@@ -20,7 +20,7 @@
     <string name="brightness_down_label" msgid="7115662941913272072">"Baisser luminosité"</string>
     <string name="previous_button_content_description" msgid="840869171117765966">"Revenir à l\'écran précédent"</string>
     <string name="next_button_content_description" msgid="6810058269847364406">"Accéder à l\'écran suivant"</string>
-    <string name="accessibility_menu_description" msgid="4458354794093858297">"Le menu d\'accessibilité s\'affiche en grand sur votre écran pour vous permettre de contrôler votre appareil. Vous pouvez verrouiller votre appareil, ajuster le volume et la luminosité, réaliser des captures d\'écran, et plus encore."</string>
+    <string name="accessibility_menu_description" msgid="4458354794093858297">"Le menu Accessibilité s\'affiche en grand sur votre écran pour vous permettre de contrôler votre appareil. Vous pouvez verrouiller votre appareil, ajuster le volume et la luminosité, réaliser des captures d\'écran, et plus encore."</string>
     <string name="accessibility_menu_summary" msgid="340071398148208130">"Contrôler l\'appareil via un grand menu"</string>
     <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Paramètres du menu d\'accessibilité"</string>
     <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Boutons de grande taille"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ko/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ko/strings.xml
index b06e432..92d7049 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ko/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ko/strings.xml
@@ -9,7 +9,7 @@
     <string name="power_label" msgid="7699720321491287839">"전원"</string>
     <string name="power_utterance" msgid="7444296686402104807">"전원 옵션"</string>
     <string name="recent_apps_label" msgid="6583276995616385847">"최근 앱"</string>
-    <string name="lockscreen_label" msgid="648347953557887087">"잠금 화면"</string>
+    <string name="lockscreen_label" msgid="648347953557887087">"화면 잠금"</string>
     <string name="quick_settings_label" msgid="2999117381487601865">"빠른 설정"</string>
     <string name="notifications_label" msgid="6829741046963013567">"알림"</string>
     <string name="screenshot_label" msgid="863978141223970162">"스크린샷"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rTW/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rTW/strings.xml
index 40c961c..ac6b5c3 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-zh-rTW/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="accessibility_menu_service_name" msgid="730136711554740131">"無障礙選單"</string>
+    <string name="accessibility_menu_service_name" msgid="730136711554740131">"無障礙工具選單"</string>
     <string name="accessibility_menu_intro" msgid="3164193281544042394">"無障礙工具選單是螢幕上的大型選單,可用來操控裝置,方便你鎖定裝置、控制音量和亮度、擷取螢幕畫面,以及執行其他功能。"</string>
     <string name="assistant_label" msgid="6796392082252272356">"Google 助理"</string>
     <string name="assistant_utterance" msgid="65509599221141377">"Google 助理"</string>
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt
deleted file mode 100644
index 197b217..0000000
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.animation
-
-import android.annotation.SuppressLint
-import android.app.WindowConfiguration
-import android.graphics.Point
-import android.graphics.Rect
-import android.os.IBinder
-import android.os.RemoteException
-import android.util.ArrayMap
-import android.util.Log
-import android.util.RotationUtils
-import android.view.IRemoteAnimationFinishedCallback
-import android.view.IRemoteAnimationRunner
-import android.view.RemoteAnimationAdapter
-import android.view.RemoteAnimationTarget
-import android.view.SurfaceControl
-import android.view.WindowManager
-import android.window.IRemoteTransition
-import android.window.IRemoteTransitionFinishedCallback
-import android.window.RemoteTransition
-import android.window.TransitionInfo
-
-class RemoteTransitionAdapter {
-    companion object {
-        /**
-         * Almost a copy of Transitions#setupStartState.
-         *
-         * TODO: remove when there is proper cross-process transaction sync.
-         */
-        @SuppressLint("NewApi")
-        private fun setupLeash(
-            leash: SurfaceControl,
-            change: TransitionInfo.Change,
-            layer: Int,
-            info: TransitionInfo,
-            t: SurfaceControl.Transaction
-        ) {
-            val isOpening =
-                info.type == WindowManager.TRANSIT_OPEN ||
-                    info.type == WindowManager.TRANSIT_TO_FRONT
-            // Put animating stuff above this line and put static stuff below it.
-            val zSplitLine = info.changes.size
-            // changes should be ordered top-to-bottom in z
-            val mode = change.mode
-
-            var rootIdx = info.findRootIndex(change.endDisplayId)
-            if (rootIdx < 0) rootIdx = 0
-            // Launcher animates leaf tasks directly, so always reparent all task leashes to root.
-            t.reparent(leash, info.getRoot(rootIdx).leash)
-            t.setPosition(
-                leash,
-                (change.startAbsBounds.left - info.getRoot(rootIdx).offset.x).toFloat(),
-                (change.startAbsBounds.top - info.getRoot(rootIdx).offset.y).toFloat()
-            )
-            t.show(leash)
-            // Put all the OPEN/SHOW on top
-            if (mode == WindowManager.TRANSIT_OPEN || mode == WindowManager.TRANSIT_TO_FRONT) {
-                if (isOpening) {
-                    t.setLayer(leash, zSplitLine + info.changes.size - layer)
-                    if (
-                        change.flags and TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT == 0
-                    ) {
-                        // if transferred, it should be left visible.
-                        t.setAlpha(leash, 0f)
-                    }
-                } else {
-                    // put on bottom and leave it visible
-                    t.setLayer(leash, zSplitLine - layer)
-                }
-            } else if (
-                mode == WindowManager.TRANSIT_CLOSE || mode == WindowManager.TRANSIT_TO_BACK
-            ) {
-                if (isOpening) {
-                    // put on bottom and leave visible
-                    t.setLayer(leash, zSplitLine - layer)
-                } else {
-                    // put on top
-                    t.setLayer(leash, zSplitLine + info.changes.size - layer)
-                }
-            } else { // CHANGE
-                t.setLayer(leash, zSplitLine + info.changes.size - layer)
-            }
-        }
-
-        @SuppressLint("NewApi")
-        private fun createLeash(
-            info: TransitionInfo,
-            change: TransitionInfo.Change,
-            order: Int,
-            t: SurfaceControl.Transaction
-        ): SurfaceControl {
-            // TODO: once we can properly sync transactions across process, then get rid of this.
-            if (change.parent != null && change.flags and TransitionInfo.FLAG_IS_WALLPAPER != 0) {
-                // Special case for wallpaper atm. Normally these are left alone; but, a quirk of
-                // making leashes means we have to handle them specially.
-                return change.leash
-            }
-            val leashSurface =
-                SurfaceControl.Builder()
-                    .setName(change.leash.toString() + "_transition-leash")
-                    .setContainerLayer()
-                    .setParent(
-                        if (change.parent == null) {
-                            var rootIdx = info.findRootIndex(change.endDisplayId)
-                            if (rootIdx < 0) rootIdx = 0
-                            info.getRoot(rootIdx).leash
-                        } else info.getChange(change.parent!!)!!.leash
-                    )
-                    .build()
-            // Copied Transitions setup code (which expects bottom-to-top order, so we swap here)
-            setupLeash(leashSurface, change, info.changes.size - order, info, t)
-            t.reparent(change.leash, leashSurface)
-            t.setAlpha(change.leash, 1.0f)
-            t.show(change.leash)
-            t.setPosition(change.leash, 0f, 0f)
-            t.setLayer(change.leash, 0)
-            return leashSurface
-        }
-
-        private fun newModeToLegacyMode(newMode: Int): Int {
-            return when (newMode) {
-                WindowManager.TRANSIT_OPEN,
-                WindowManager.TRANSIT_TO_FRONT -> RemoteAnimationTarget.MODE_OPENING
-                WindowManager.TRANSIT_CLOSE,
-                WindowManager.TRANSIT_TO_BACK -> RemoteAnimationTarget.MODE_CLOSING
-                else -> RemoteAnimationTarget.MODE_CHANGING
-            }
-        }
-
-        private fun rectOffsetTo(rect: Rect, offset: Point): Rect {
-            val out = Rect(rect)
-            out.offsetTo(offset.x, offset.y)
-            return out
-        }
-
-        fun createTarget(
-            change: TransitionInfo.Change,
-            order: Int,
-            info: TransitionInfo,
-            t: SurfaceControl.Transaction
-        ): RemoteAnimationTarget {
-            val target =
-                RemoteAnimationTarget(
-                    /* taskId */ if (change.taskInfo != null) change.taskInfo!!.taskId else -1,
-                    /* mode */ newModeToLegacyMode(change.mode),
-                    /* leash */ createLeash(info, change, order, t),
-                    /* isTranslucent */ (change.flags and TransitionInfo.FLAG_TRANSLUCENT != 0 ||
-                        change.flags and TransitionInfo.FLAG_SHOW_WALLPAPER != 0),
-                    /* clipRect */ null,
-                    /* contentInsets */ Rect(0, 0, 0, 0),
-                    /* prefixOrderIndex */ order,
-                    /* position */ null,
-                    /* localBounds */ rectOffsetTo(change.endAbsBounds, change.endRelOffset),
-                    /* screenSpaceBounds */ Rect(change.endAbsBounds),
-                    /* windowConfig */ if (change.taskInfo != null)
-                        change.taskInfo!!.configuration.windowConfiguration
-                    else WindowConfiguration(),
-                    /* isNotInRecents */ if (change.taskInfo != null) !change.taskInfo!!.isRunning
-                    else true,
-                    /* startLeash */ null,
-                    /* startBounds */ Rect(change.startAbsBounds),
-                    /* taskInfo */ change.taskInfo,
-                    /* allowEnterPip */ change.allowEnterPip,
-                    /* windowType */ WindowManager.LayoutParams.INVALID_WINDOW_TYPE
-                )
-            target.backgroundColor = change.backgroundColor
-            return target
-        }
-
-        /**
-         * Represents a TransitionInfo object as an array of old-style targets
-         *
-         * @param wallpapers If true, this will return wallpaper targets; otherwise it returns
-         *   non-wallpaper targets.
-         * @param leashMap Temporary map of change leash -> launcher leash. Is an output, so should
-         *   be populated by this function. If null, it is ignored.
-         */
-        fun wrapTargets(
-            info: TransitionInfo,
-            wallpapers: Boolean,
-            t: SurfaceControl.Transaction,
-            leashMap: ArrayMap<SurfaceControl, SurfaceControl>?
-        ): Array<RemoteAnimationTarget> {
-            val out = ArrayList<RemoteAnimationTarget>()
-            for (i in info.changes.indices) {
-                val change = info.changes[i]
-                if (change.hasFlags(TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY)) {
-                    // For embedded container, when the parent Task is also in the transition, we
-                    // should only animate the parent Task.
-                    if (change.parent != null) continue
-                    // For embedded container without parent, we should only animate if it fills
-                    // the Task. Otherwise we may animate only partial of the Task.
-                    if (!change.hasFlags(TransitionInfo.FLAG_FILLS_TASK)) continue
-                }
-                // Check if it is wallpaper
-                if (wallpapers != change.hasFlags(TransitionInfo.FLAG_IS_WALLPAPER)) continue
-                out.add(createTarget(change, info.changes.size - i, info, t))
-                if (leashMap != null) {
-                    leashMap[change.leash] = out[out.size - 1].leash
-                }
-            }
-            return out.toTypedArray()
-        }
-
-        @JvmStatic
-        fun adaptRemoteRunner(runner: IRemoteAnimationRunner): IRemoteTransition.Stub {
-            return object : IRemoteTransition.Stub() {
-                override fun startAnimation(
-                    token: IBinder,
-                    info: TransitionInfo,
-                    t: SurfaceControl.Transaction,
-                    finishCallback: IRemoteTransitionFinishedCallback
-                ) {
-                    val leashMap = ArrayMap<SurfaceControl, SurfaceControl>()
-                    val appsCompat = wrapTargets(info, false /* wallpapers */, t, leashMap)
-                    val wallpapersCompat = wrapTargets(info, true /* wallpapers */, t, leashMap)
-                    // TODO(bc-unlock): Build wrapped object for non-apps target.
-                    val nonAppsCompat = arrayOfNulls<RemoteAnimationTarget>(0)
-
-                    // TODO(b/177438007): Move this set-up logic into launcher's animation impl.
-                    var isReturnToHome = false
-                    var launcherTask: TransitionInfo.Change? = null
-                    var wallpaper: TransitionInfo.Change? = null
-                    var launcherLayer = 0
-                    var rotateDelta = 0
-                    var displayW = 0f
-                    var displayH = 0f
-                    for (i in info.changes.indices.reversed()) {
-                        val change = info.changes[i]
-                        if (
-                            change.taskInfo != null &&
-                                change.taskInfo!!.activityType ==
-                                    WindowConfiguration.ACTIVITY_TYPE_HOME
-                        ) {
-                            isReturnToHome =
-                                (change.mode == WindowManager.TRANSIT_OPEN ||
-                                    change.mode == WindowManager.TRANSIT_TO_FRONT)
-                            launcherTask = change
-                            launcherLayer = info.changes.size - i
-                        } else if (change.flags and TransitionInfo.FLAG_IS_WALLPAPER != 0) {
-                            wallpaper = change
-                        }
-                        if (
-                            change.parent == null &&
-                                change.endRotation >= 0 &&
-                                change.endRotation != change.startRotation
-                        ) {
-                            rotateDelta = change.endRotation - change.startRotation
-                            displayW = change.endAbsBounds.width().toFloat()
-                            displayH = change.endAbsBounds.height().toFloat()
-                        }
-                    }
-
-                    // Prepare for rotation if there is one
-                    val counterLauncher = CounterRotator()
-                    val counterWallpaper = CounterRotator()
-                    if (launcherTask != null && rotateDelta != 0 && launcherTask.parent != null) {
-                        counterLauncher.setup(
-                            t,
-                            info.getChange(launcherTask.parent!!)!!.leash,
-                            rotateDelta,
-                            displayW,
-                            displayH
-                        )
-                        if (counterLauncher.surface != null) {
-                            t.setLayer(counterLauncher.surface!!, launcherLayer)
-                        }
-                    }
-                    if (isReturnToHome) {
-                        if (counterLauncher.surface != null) {
-                            t.setLayer(counterLauncher.surface!!, info.changes.size * 3)
-                        }
-                        // Need to "boost" the closing things since that's what launcher expects.
-                        for (i in info.changes.indices.reversed()) {
-                            val change = info.changes[i]
-                            val leash = leashMap[change.leash]
-                            val mode = info.changes[i].mode
-                            // Only deal with independent layers
-                            if (!TransitionInfo.isIndependent(change, info)) continue
-                            if (
-                                mode == WindowManager.TRANSIT_CLOSE ||
-                                    mode == WindowManager.TRANSIT_TO_BACK
-                            ) {
-                                t.setLayer(leash!!, info.changes.size * 3 - i)
-                                counterLauncher.addChild(t, leash)
-                            }
-                        }
-                        // Make wallpaper visible immediately since sysui apparently won't do this.
-                        for (i in wallpapersCompat.indices.reversed()) {
-                            t.show(wallpapersCompat[i].leash)
-                            t.setAlpha(wallpapersCompat[i].leash, 1f)
-                        }
-                    } else {
-                        if (launcherTask != null) {
-                            counterLauncher.addChild(t, leashMap[launcherTask.leash])
-                        }
-                        if (wallpaper != null && rotateDelta != 0 && wallpaper.parent != null) {
-                            counterWallpaper.setup(
-                                t,
-                                info.getChange(wallpaper.parent!!)!!.leash,
-                                rotateDelta,
-                                displayW,
-                                displayH
-                            )
-                            if (counterWallpaper.surface != null) {
-                                t.setLayer(counterWallpaper.surface!!, -1)
-                                counterWallpaper.addChild(t, leashMap[wallpaper.leash])
-                            }
-                        }
-                    }
-                    t.apply()
-                    val animationFinishedCallback =
-                        object : IRemoteAnimationFinishedCallback {
-                            override fun onAnimationFinished() {
-                                val finishTransaction = SurfaceControl.Transaction()
-                                counterLauncher.cleanUp(finishTransaction)
-                                counterWallpaper.cleanUp(finishTransaction)
-                                // Release surface references now. This is apparently to free GPU
-                                // memory while doing quick operations (eg. during CTS).
-                                info.releaseAllSurfaces()
-                                for (i in leashMap.size - 1 downTo 0) {
-                                    leashMap.valueAt(i).release()
-                                }
-                                try {
-                                    finishCallback.onTransitionFinished(
-                                        null /* wct */,
-                                        finishTransaction
-                                    )
-                                    finishTransaction.close()
-                                } catch (e: RemoteException) {
-                                    Log.e(
-                                        "ActivityOptionsCompat",
-                                        "Failed to call app controlled" +
-                                            " animation finished callback",
-                                        e
-                                    )
-                                }
-                            }
-
-                            override fun asBinder(): IBinder? {
-                                return null
-                            }
-                        }
-                    // TODO(bc-unlcok): Pass correct transit type.
-                    runner.onAnimationStart(
-                        WindowManager.TRANSIT_OLD_NONE,
-                        appsCompat,
-                        wallpapersCompat,
-                        nonAppsCompat,
-                        animationFinishedCallback
-                    )
-                }
-
-                override fun mergeAnimation(
-                    token: IBinder,
-                    info: TransitionInfo,
-                    t: SurfaceControl.Transaction,
-                    mergeTarget: IBinder,
-                    finishCallback: IRemoteTransitionFinishedCallback
-                ) {
-                    // TODO: hook up merge to recents onTaskAppeared if applicable. Until then,
-                    //       ignore any incoming merges.
-                    // Clean up stuff though cuz GC takes too long for benchmark tests.
-                    t.close()
-                    info.releaseAllSurfaces()
-                }
-            }
-        }
-
-        @JvmStatic
-        fun adaptRemoteAnimation(
-            adapter: RemoteAnimationAdapter,
-            debugName: String
-        ): RemoteTransition {
-            return RemoteTransition(
-                adaptRemoteRunner(adapter.runner),
-                adapter.callingApplication,
-                debugName
-            )
-        }
-    }
-
-    /** Utility class that takes care of counter-rotating surfaces during a transition animation. */
-    class CounterRotator {
-        /** Gets the surface with the counter-rotation. */
-        var surface: SurfaceControl? = null
-            private set
-
-        /**
-         * Sets up this rotator.
-         *
-         * @param rotateDelta is the forward rotation change (the rotation the display is making).
-         * @param parentW (and H) Is the size of the rotating parent.
-         */
-        fun setup(
-            t: SurfaceControl.Transaction,
-            parent: SurfaceControl,
-            rotateDelta: Int,
-            parentW: Float,
-            parentH: Float
-        ) {
-            if (rotateDelta == 0) return
-            val surface =
-                SurfaceControl.Builder()
-                    .setName("Transition Unrotate")
-                    .setContainerLayer()
-                    .setParent(parent)
-                    .build()
-            // Rotate forward to match the new rotation (rotateDelta is the forward rotation the
-            // parent already took). Child surfaces will be in the old rotation relative to the new
-            // parent rotation, so we need to forward-rotate the child surfaces to match.
-            RotationUtils.rotateSurface(t, surface, rotateDelta)
-            val tmpPt = Point(0, 0)
-            // parentW/H are the size in the END rotation, the rotation utilities expect the
-            // starting size. So swap them if necessary
-            val flipped = rotateDelta % 2 != 0
-            val pw = if (flipped) parentH else parentW
-            val ph = if (flipped) parentW else parentH
-            RotationUtils.rotatePoint(tmpPt, rotateDelta, pw.toInt(), ph.toInt())
-            t.setPosition(surface, tmpPt.x.toFloat(), tmpPt.y.toFloat())
-            t.show(surface)
-        }
-
-        /** Adds a surface that needs to be counter-rotate. */
-        fun addChild(t: SurfaceControl.Transaction, child: SurfaceControl?) {
-            if (surface == null) return
-            t.reparent(child!!, surface)
-        }
-
-        /**
-         * Clean-up. Since finishTransaction should reset all change leashes, we only need to remove
-         * the counter rotation surface.
-         */
-        fun cleanUp(finishTransaction: SurfaceControl.Transaction) {
-            if (surface == null) return
-            finishTransaction.remove(surface!!)
-        }
-    }
-}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/MultiRippleController.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/MultiRippleController.kt
index 8cd8bf6..d8e17c9 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/MultiRippleController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/MultiRippleController.kt
@@ -21,20 +21,9 @@
 /** Controller that handles playing [RippleAnimation]. */
 class MultiRippleController(private val multipleRippleView: MultiRippleView) {
 
-    private val ripplesFinishedListeners = ArrayList<RipplesFinishedListener>()
-
     companion object {
         /** Max number of ripple animations at a time. */
         @VisibleForTesting const val MAX_RIPPLE_NUMBER = 10
-
-        interface RipplesFinishedListener {
-            /** Triggered when all the ripples finish running. */
-            fun onRipplesFinish()
-        }
-    }
-
-    fun addRipplesFinishedListener(listener: RipplesFinishedListener) {
-        ripplesFinishedListeners.add(listener)
     }
 
     /** Updates all the ripple colors during the animation. */
@@ -52,9 +41,6 @@
         rippleAnimation.play {
             // Remove ripple once the animation is done
             multipleRippleView.ripples.remove(rippleAnimation)
-            if (multipleRippleView.ripples.isEmpty()) {
-                ripplesFinishedListeners.forEach { listener -> listener.onRipplesFinish() }
-            }
         }
 
         // Trigger drawing
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt b/packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt
index d1ee18a..25269dc 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt
@@ -85,7 +85,7 @@
 
 @Composable
 private fun filledButtonColors(): ButtonColors {
-    val colors = LocalAndroidColorScheme.current
+    val colors = LocalAndroidColorScheme.current.deprecated
     return ButtonDefaults.buttonColors(
         containerColor = colors.colorAccentPrimary,
         contentColor = colors.textColorOnAccent,
@@ -94,7 +94,7 @@
 
 @Composable
 private fun outlineButtonColors(): ButtonColors {
-    val colors = LocalAndroidColorScheme.current
+    val colors = LocalAndroidColorScheme.current.deprecated
     return ButtonDefaults.outlinedButtonColors(
         contentColor = colors.textColorPrimary,
     )
@@ -102,7 +102,7 @@
 
 @Composable
 private fun outlineButtonBorder(): BorderStroke {
-    val colors = LocalAndroidColorScheme.current
+    val colors = LocalAndroidColorScheme.current.deprecated
     return BorderStroke(
         width = 1.dp,
         color = colors.colorAccentPrimaryVariant,
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/grid/Grids.kt b/packages/SystemUI/compose/core/src/com/android/compose/grid/Grids.kt
new file mode 100644
index 0000000..5224c51
--- /dev/null
+++ b/packages/SystemUI/compose/core/src/com/android/compose/grid/Grids.kt
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.grid
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.constrainWidth
+import androidx.compose.ui.unit.dp
+import kotlin.math.ceil
+import kotlin.math.max
+import kotlin.math.roundToInt
+
+/**
+ * Renders a grid with [columns] columns.
+ *
+ * Child composables will be arranged row by row.
+ *
+ * Each column is spaced from the columns to its left and right by [horizontalSpacing]. Each cell
+ * inside a column is spaced from the cells above and below it with [verticalSpacing].
+ */
+@Composable
+fun VerticalGrid(
+    columns: Int,
+    modifier: Modifier = Modifier,
+    verticalSpacing: Dp = 0.dp,
+    horizontalSpacing: Dp = 0.dp,
+    content: @Composable () -> Unit,
+) {
+    Grid(
+        primarySpaces = columns,
+        isVertical = true,
+        modifier = modifier,
+        verticalSpacing = verticalSpacing,
+        horizontalSpacing = horizontalSpacing,
+        content = content,
+    )
+}
+
+/**
+ * Renders a grid with [rows] rows.
+ *
+ * Child composables will be arranged column by column.
+ *
+ * Each column is spaced from the columns to its left and right by [horizontalSpacing]. Each cell
+ * inside a column is spaced from the cells above and below it with [verticalSpacing].
+ */
+@Composable
+fun HorizontalGrid(
+    rows: Int,
+    modifier: Modifier = Modifier,
+    verticalSpacing: Dp = 0.dp,
+    horizontalSpacing: Dp = 0.dp,
+    content: @Composable () -> Unit,
+) {
+    Grid(
+        primarySpaces = rows,
+        isVertical = false,
+        modifier = modifier,
+        verticalSpacing = verticalSpacing,
+        horizontalSpacing = horizontalSpacing,
+        content = content,
+    )
+}
+
+@Composable
+private fun Grid(
+    primarySpaces: Int,
+    isVertical: Boolean,
+    modifier: Modifier = Modifier,
+    verticalSpacing: Dp,
+    horizontalSpacing: Dp,
+    content: @Composable () -> Unit,
+) {
+    check(primarySpaces > 0) {
+        "Must provide a positive number of ${if (isVertical) "columns" else "rows"}"
+    }
+
+    val sizeCache = remember {
+        object {
+            var rowHeights = intArrayOf()
+            var columnWidths = intArrayOf()
+        }
+    }
+
+    Layout(
+        modifier = modifier,
+        content = content,
+    ) { measurables, constraints ->
+        val cells = measurables.size
+        val columns: Int
+        val rows: Int
+        if (isVertical) {
+            columns = primarySpaces
+            rows = ceil(cells.toFloat() / primarySpaces).toInt()
+        } else {
+            columns = ceil(cells.toFloat() / primarySpaces).toInt()
+            rows = primarySpaces
+        }
+
+        if (sizeCache.rowHeights.size != rows) {
+            sizeCache.rowHeights = IntArray(rows) { 0 }
+        }
+        if (sizeCache.columnWidths.size != columns) {
+            sizeCache.columnWidths = IntArray(columns) { 0 }
+        }
+
+        val totalHorizontalSpacingBetweenChildren =
+            ((columns - 1) * horizontalSpacing.toPx()).roundToInt()
+        val totalVerticalSpacingBetweenChildren = ((rows - 1) * verticalSpacing.toPx()).roundToInt()
+        val childConstraints =
+            Constraints().apply {
+                if (constraints.maxWidth != Constraints.Infinity) {
+                    constrainWidth(
+                        (constraints.maxWidth - totalHorizontalSpacingBetweenChildren) / columns
+                    )
+                }
+                if (constraints.maxHeight != Constraints.Infinity) {
+                    constrainWidth(
+                        (constraints.maxHeight - totalVerticalSpacingBetweenChildren) / rows
+                    )
+                }
+            }
+
+        val placeables = buildList {
+            for (cellIndex in measurables.indices) {
+                val column: Int
+                val row: Int
+                if (isVertical) {
+                    column = cellIndex % columns
+                    row = cellIndex / columns
+                } else {
+                    column = cellIndex / rows
+                    row = cellIndex % rows
+                }
+
+                val placeable = measurables[cellIndex].measure(childConstraints)
+                sizeCache.rowHeights[row] = max(sizeCache.rowHeights[row], placeable.height)
+                sizeCache.columnWidths[column] =
+                    max(sizeCache.columnWidths[column], placeable.width)
+                add(placeable)
+            }
+        }
+
+        var totalWidth = totalHorizontalSpacingBetweenChildren
+        for (column in sizeCache.columnWidths.indices) {
+            totalWidth += sizeCache.columnWidths[column]
+        }
+
+        var totalHeight = totalVerticalSpacingBetweenChildren
+        for (row in sizeCache.rowHeights.indices) {
+            totalHeight += sizeCache.rowHeights[row]
+        }
+
+        layout(totalWidth, totalHeight) {
+            var y = 0
+            repeat(rows) { row ->
+                var x = 0
+                var maxChildHeight = 0
+                repeat(columns) { column ->
+                    val cellIndex = row * columns + column
+                    if (cellIndex < cells) {
+                        val placeable = placeables[cellIndex]
+                        placeable.placeRelative(x, y)
+                        x += placeable.width + horizontalSpacing.roundToPx()
+                        maxChildHeight = max(maxChildHeight, placeable.height)
+                    }
+                }
+                y += maxChildHeight + verticalSpacing.roundToPx()
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/theme/AndroidColorScheme.kt b/packages/SystemUI/compose/core/src/com/android/compose/theme/AndroidColorScheme.kt
index 4f1657f..1d6f813 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/theme/AndroidColorScheme.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/theme/AndroidColorScheme.kt
@@ -37,33 +37,83 @@
  * Important: Use M3 colors from MaterialTheme.colorScheme whenever possible instead. In the future,
  * most of the colors in this class will be removed in favor of their M3 counterpart.
  */
-class AndroidColorScheme internal constructor(context: Context) {
-    val colorPrimary = getColor(context, R.attr.colorPrimary)
-    val colorPrimaryDark = getColor(context, R.attr.colorPrimaryDark)
-    val colorAccent = getColor(context, R.attr.colorAccent)
-    val colorAccentPrimary = getColor(context, R.attr.colorAccentPrimary)
-    val colorAccentSecondary = getColor(context, R.attr.colorAccentSecondary)
-    val colorAccentTertiary = getColor(context, R.attr.colorAccentTertiary)
-    val colorAccentPrimaryVariant = getColor(context, R.attr.colorAccentPrimaryVariant)
-    val colorAccentSecondaryVariant = getColor(context, R.attr.colorAccentSecondaryVariant)
-    val colorAccentTertiaryVariant = getColor(context, R.attr.colorAccentTertiaryVariant)
-    val colorSurface = getColor(context, R.attr.colorSurface)
-    val colorSurfaceHighlight = getColor(context, R.attr.colorSurfaceHighlight)
-    val colorSurfaceVariant = getColor(context, R.attr.colorSurfaceVariant)
-    val colorSurfaceHeader = getColor(context, R.attr.colorSurfaceHeader)
-    val colorError = getColor(context, R.attr.colorError)
-    val colorBackground = getColor(context, R.attr.colorBackground)
-    val colorBackgroundFloating = getColor(context, R.attr.colorBackgroundFloating)
-    val panelColorBackground = getColor(context, R.attr.panelColorBackground)
-    val textColorPrimary = getColor(context, R.attr.textColorPrimary)
-    val textColorSecondary = getColor(context, R.attr.textColorSecondary)
-    val textColorTertiary = getColor(context, R.attr.textColorTertiary)
-    val textColorPrimaryInverse = getColor(context, R.attr.textColorPrimaryInverse)
-    val textColorSecondaryInverse = getColor(context, R.attr.textColorSecondaryInverse)
-    val textColorTertiaryInverse = getColor(context, R.attr.textColorTertiaryInverse)
-    val textColorOnAccent = getColor(context, R.attr.textColorOnAccent)
-    val colorForeground = getColor(context, R.attr.colorForeground)
-    val colorForegroundInverse = getColor(context, R.attr.colorForegroundInverse)
+class AndroidColorScheme(context: Context) {
+    val onSecondaryFixedVariant = getColor(context, R.attr.materialColorOnSecondaryFixedVariant)
+    val onTertiaryFixedVariant = getColor(context, R.attr.materialColorOnTertiaryFixedVariant)
+    val surfaceContainerLowest = getColor(context, R.attr.materialColorSurfaceContainerLowest)
+    val onPrimaryFixedVariant = getColor(context, R.attr.materialColorOnPrimaryFixedVariant)
+    val onSecondaryContainer = getColor(context, R.attr.materialColorOnSecondaryContainer)
+    val onTertiaryContainer = getColor(context, R.attr.materialColorOnTertiaryContainer)
+    val surfaceContainerLow = getColor(context, R.attr.materialColorSurfaceContainerLow)
+    val onPrimaryContainer = getColor(context, R.attr.materialColorOnPrimaryContainer)
+    val secondaryFixedDim = getColor(context, R.attr.materialColorSecondaryFixedDim)
+    val onErrorContainer = getColor(context, R.attr.materialColorOnErrorContainer)
+    val onSecondaryFixed = getColor(context, R.attr.materialColorOnSecondaryFixed)
+    val onSurfaceInverse = getColor(context, R.attr.materialColorOnSurfaceInverse)
+    val tertiaryFixedDim = getColor(context, R.attr.materialColorTertiaryFixedDim)
+    val onTertiaryFixed = getColor(context, R.attr.materialColorOnTertiaryFixed)
+    val primaryFixedDim = getColor(context, R.attr.materialColorPrimaryFixedDim)
+    val secondaryContainer = getColor(context, R.attr.materialColorSecondaryContainer)
+    val errorContainer = getColor(context, R.attr.materialColorErrorContainer)
+    val onPrimaryFixed = getColor(context, R.attr.materialColorOnPrimaryFixed)
+    val primaryInverse = getColor(context, R.attr.materialColorPrimaryInverse)
+    val secondaryFixed = getColor(context, R.attr.materialColorSecondaryFixed)
+    val surfaceInverse = getColor(context, R.attr.materialColorSurfaceInverse)
+    val surfaceVariant = getColor(context, R.attr.materialColorSurfaceVariant)
+    val tertiaryContainer = getColor(context, R.attr.materialColorTertiaryContainer)
+    val tertiaryFixed = getColor(context, R.attr.materialColorTertiaryFixed)
+    val primaryContainer = getColor(context, R.attr.materialColorPrimaryContainer)
+    val onBackground = getColor(context, R.attr.materialColorOnBackground)
+    val primaryFixed = getColor(context, R.attr.materialColorPrimaryFixed)
+    val onSecondary = getColor(context, R.attr.materialColorOnSecondary)
+    val onTertiary = getColor(context, R.attr.materialColorOnTertiary)
+    val surfaceDim = getColor(context, R.attr.materialColorSurfaceDim)
+    val surfaceBright = getColor(context, R.attr.materialColorSurfaceBright)
+    val onError = getColor(context, R.attr.materialColorOnError)
+    val surface = getColor(context, R.attr.materialColorSurface)
+    val surfaceContainerHigh = getColor(context, R.attr.materialColorSurfaceContainerHigh)
+    val surfaceContainerHighest = getColor(context, R.attr.materialColorSurfaceContainerHighest)
+    val onSurfaceVariant = getColor(context, R.attr.materialColorOnSurfaceVariant)
+    val outline = getColor(context, R.attr.materialColorOutline)
+    val outlineVariant = getColor(context, R.attr.materialColorOutlineVariant)
+    val onPrimary = getColor(context, R.attr.materialColorOnPrimary)
+    val onSurface = getColor(context, R.attr.materialColorOnSurface)
+    val surfaceContainer = getColor(context, R.attr.materialColorSurfaceContainer)
+    val primary = getColor(context, R.attr.materialColorPrimary)
+    val secondary = getColor(context, R.attr.materialColorSecondary)
+    val tertiary = getColor(context, R.attr.materialColorTertiary)
+
+    @Deprecated("Use the new android tokens: go/sysui-colors")
+    val deprecated = DeprecatedValues(context)
+
+    class DeprecatedValues(context: Context) {
+        val colorPrimary = getColor(context, R.attr.colorPrimary)
+        val colorPrimaryDark = getColor(context, R.attr.colorPrimaryDark)
+        val colorAccent = getColor(context, R.attr.colorAccent)
+        val colorAccentPrimary = getColor(context, R.attr.colorAccentPrimary)
+        val colorAccentSecondary = getColor(context, R.attr.colorAccentSecondary)
+        val colorAccentTertiary = getColor(context, R.attr.colorAccentTertiary)
+        val colorAccentPrimaryVariant = getColor(context, R.attr.colorAccentPrimaryVariant)
+        val colorAccentSecondaryVariant = getColor(context, R.attr.colorAccentSecondaryVariant)
+        val colorAccentTertiaryVariant = getColor(context, R.attr.colorAccentTertiaryVariant)
+        val colorSurface = getColor(context, R.attr.colorSurface)
+        val colorSurfaceHighlight = getColor(context, R.attr.colorSurfaceHighlight)
+        val colorSurfaceVariant = getColor(context, R.attr.colorSurfaceVariant)
+        val colorSurfaceHeader = getColor(context, R.attr.colorSurfaceHeader)
+        val colorError = getColor(context, R.attr.colorError)
+        val colorBackground = getColor(context, R.attr.colorBackground)
+        val colorBackgroundFloating = getColor(context, R.attr.colorBackgroundFloating)
+        val panelColorBackground = getColor(context, R.attr.panelColorBackground)
+        val textColorPrimary = getColor(context, R.attr.textColorPrimary)
+        val textColorSecondary = getColor(context, R.attr.textColorSecondary)
+        val textColorTertiary = getColor(context, R.attr.textColorTertiary)
+        val textColorPrimaryInverse = getColor(context, R.attr.textColorPrimaryInverse)
+        val textColorSecondaryInverse = getColor(context, R.attr.textColorSecondaryInverse)
+        val textColorTertiaryInverse = getColor(context, R.attr.textColorTertiaryInverse)
+        val textColorOnAccent = getColor(context, R.attr.textColorOnAccent)
+        val colorForeground = getColor(context, R.attr.colorForeground)
+        val colorForegroundInverse = getColor(context, R.attr.colorForegroundInverse)
+    }
 
     companion object {
         fun getColor(context: Context, attr: Int): Color {
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/theme/SystemUIThemeTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/theme/SystemUIThemeTest.kt
index 9bc6856..fe34017 100644
--- a/packages/SystemUI/compose/core/tests/src/com/android/compose/theme/SystemUIThemeTest.kt
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/theme/SystemUIThemeTest.kt
@@ -40,7 +40,9 @@
     @Test
     fun testAndroidColorsAreAvailableInsideTheme() {
         composeRule.setContent {
-            PlatformTheme { Text("foo", color = LocalAndroidColorScheme.current.colorAccent) }
+            PlatformTheme {
+                Text("foo", color = LocalAndroidColorScheme.current.deprecated.colorAccent)
+            }
         }
 
         composeRule.onNodeWithText("foo").assertIsDisplayed()
@@ -50,7 +52,7 @@
     fun testAccessingAndroidColorsWithoutThemeThrows() {
         assertThrows(IllegalStateException::class.java) {
             composeRule.setContent {
-                Text("foo", color = LocalAndroidColorScheme.current.colorAccent)
+                Text("foo", color = LocalAndroidColorScheme.current.deprecated.colorAccent)
             }
         }
     }
diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt
new file mode 100644
index 0000000..5413f90
--- /dev/null
+++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene.ui.composable
+
+import com.android.systemui.scene.shared.model.Scene
+import com.android.systemui.scene.shared.model.SceneContainerNames
+import dagger.Module
+import dagger.multibindings.Multibinds
+import javax.inject.Named
+
+@Module
+interface SceneModule {
+    @Multibinds @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) fun scenes(): Set<Scene>
+}
diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt
new file mode 100644
index 0000000..954bad56
--- /dev/null
+++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene.ui.composable
+
+import com.android.systemui.bouncer.ui.composable.BouncerScene
+import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.ui.composable.LockscreenScene
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel
+import com.android.systemui.qs.ui.composable.QuickSettingsScene
+import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneViewModel
+import com.android.systemui.scene.shared.model.Scene
+import com.android.systemui.scene.shared.model.SceneContainerNames
+import com.android.systemui.shade.ui.composable.ShadeScene
+import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
+import dagger.Module
+import dagger.Provides
+import javax.inject.Named
+import kotlinx.coroutines.CoroutineScope
+
+@Module
+object SceneModule {
+    @Provides
+    @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
+    fun scenes(
+        @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) bouncer: BouncerScene,
+        @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) gone: GoneScene,
+        @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) lockScreen: LockscreenScene,
+        @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) qs: QuickSettingsScene,
+        @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) shade: ShadeScene,
+    ): Set<Scene> {
+        return setOf(
+            bouncer,
+            gone,
+            lockScreen,
+            qs,
+            shade,
+        )
+    }
+
+    @Provides
+    @SysUISingleton
+    @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
+    fun bouncerScene(
+        viewModelFactory: BouncerViewModel.Factory,
+    ): BouncerScene {
+        return BouncerScene(
+            viewModel =
+                viewModelFactory.create(
+                    containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
+                ),
+        )
+    }
+
+    @Provides
+    @SysUISingleton
+    @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
+    fun goneScene(): GoneScene {
+        return GoneScene()
+    }
+
+    @Provides
+    @SysUISingleton
+    @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
+    fun lockscreenScene(
+        @Application applicationScope: CoroutineScope,
+        viewModelFactory: LockscreenSceneViewModel.Factory,
+    ): LockscreenScene {
+        return LockscreenScene(
+            applicationScope = applicationScope,
+            viewModel =
+                viewModelFactory.create(
+                    containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
+                ),
+        )
+    }
+
+    @Provides
+    @SysUISingleton
+    @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
+    fun quickSettingsScene(
+        viewModelFactory: QuickSettingsSceneViewModel.Factory,
+    ): QuickSettingsScene {
+        return QuickSettingsScene(
+            viewModel =
+                viewModelFactory.create(
+                    containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
+                ),
+        )
+    }
+
+    @Provides
+    @SysUISingleton
+    @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
+    fun shadeScene(
+        @Application applicationScope: CoroutineScope,
+        viewModelFactory: ShadeSceneViewModel.Factory,
+    ): ShadeScene {
+        return ShadeScene(
+            applicationScope = applicationScope,
+            viewModel =
+                viewModelFactory.create(
+                    containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
+                ),
+        )
+    }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
new file mode 100644
index 0000000..3c74ef5
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bouncer.ui.composable
+
+import androidx.compose.animation.Crossfade
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.android.systemui.bouncer.ui.viewmodel.AuthMethodBouncerViewModel
+import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
+import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel
+import com.android.systemui.bouncer.ui.viewmodel.PatternBouncerViewModel
+import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
+import com.android.systemui.scene.shared.model.UserAction
+import com.android.systemui.scene.ui.composable.ComposableScene
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+/** The bouncer scene displays authentication challenges like PIN, password, or pattern. */
+class BouncerScene(
+    private val viewModel: BouncerViewModel,
+) : ComposableScene {
+    override val key = SceneKey.Bouncer
+
+    override fun destinationScenes(
+        containerName: String,
+    ): StateFlow<Map<UserAction, SceneModel>> =
+        MutableStateFlow<Map<UserAction, SceneModel>>(
+                mapOf(
+                    UserAction.Back to SceneModel(SceneKey.Lockscreen),
+                )
+            )
+            .asStateFlow()
+
+    @Composable
+    override fun Content(
+        containerName: String,
+        modifier: Modifier,
+    ) = BouncerScene(viewModel, modifier)
+}
+
+@Composable
+private fun BouncerScene(
+    viewModel: BouncerViewModel,
+    modifier: Modifier = Modifier,
+) {
+    val message: String by viewModel.message.collectAsState()
+    val authMethodViewModel: AuthMethodBouncerViewModel? by viewModel.authMethod.collectAsState()
+
+    Column(
+        horizontalAlignment = Alignment.CenterHorizontally,
+        verticalArrangement = Arrangement.spacedBy(60.dp),
+        modifier =
+            modifier.background(MaterialTheme.colorScheme.surface).fillMaxSize().padding(32.dp)
+    ) {
+        Crossfade(
+            targetState = message,
+            label = "Bouncer message",
+        ) {
+            Text(
+                text = it,
+                color = MaterialTheme.colorScheme.onSurface,
+                style = MaterialTheme.typography.bodyLarge,
+            )
+        }
+
+        Box(Modifier.weight(1f)) {
+            when (val nonNullViewModel = authMethodViewModel) {
+                is PinBouncerViewModel ->
+                    PinBouncer(
+                        viewModel = nonNullViewModel,
+                        modifier = Modifier.align(Alignment.Center),
+                    )
+                is PasswordBouncerViewModel ->
+                    PasswordBouncer(
+                        viewModel = nonNullViewModel,
+                        modifier = Modifier.align(Alignment.Center),
+                    )
+                is PatternBouncerViewModel ->
+                    PatternBouncer(
+                        viewModel = nonNullViewModel,
+                        modifier =
+                            Modifier.aspectRatio(1f, matchHeightConstraintsFirst = false)
+                                .align(Alignment.BottomCenter),
+                    )
+                else -> Unit
+            }
+        }
+
+        Button(
+            onClick = viewModel::onEmergencyServicesButtonClicked,
+            colors =
+                ButtonDefaults.buttonColors(
+                    containerColor = MaterialTheme.colorScheme.tertiaryContainer,
+                    contentColor = MaterialTheme.colorScheme.onTertiaryContainer,
+                ),
+        ) {
+            Text(
+                text = stringResource(com.android.internal.R.string.lockscreen_emergency_call),
+                style = MaterialTheme.typography.bodyMedium,
+            )
+        }
+    }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt
new file mode 100644
index 0000000..4e85621
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PasswordBouncer.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bouncer.ui.composable
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.text.KeyboardActions
+import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.LocalTextStyle
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.TextField
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.text.input.ImeAction
+import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.text.input.PasswordVisualTransformation
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel
+
+/** UI for the input part of a password-requiring version of the bouncer. */
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+internal fun PasswordBouncer(
+    viewModel: PasswordBouncerViewModel,
+    modifier: Modifier = Modifier,
+) {
+    val focusRequester = remember { FocusRequester() }
+    val password: String by viewModel.password.collectAsState()
+
+    LaunchedEffect(Unit) {
+        // When the UI comes up, request focus on the TextField to bring up the software keyboard.
+        focusRequester.requestFocus()
+        // Also, report that the UI is shown to let the view-model runs some logic.
+        viewModel.onShown()
+    }
+
+    Column(
+        horizontalAlignment = Alignment.CenterHorizontally,
+        modifier = modifier,
+    ) {
+        val color = MaterialTheme.colorScheme.onSurfaceVariant
+        val lineWidthPx = with(LocalDensity.current) { 2.dp.toPx() }
+
+        TextField(
+            value = password,
+            onValueChange = viewModel::onPasswordInputChanged,
+            visualTransformation = PasswordVisualTransformation(),
+            singleLine = true,
+            textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
+            keyboardOptions =
+                KeyboardOptions(
+                    keyboardType = KeyboardType.Password,
+                    imeAction = ImeAction.Done,
+                ),
+            keyboardActions =
+                KeyboardActions(
+                    onDone = { viewModel.onAuthenticateKeyPressed() },
+                ),
+            modifier =
+                Modifier.focusRequester(focusRequester).drawBehind {
+                    drawLine(
+                        color = color,
+                        start = Offset(x = 0f, y = size.height - lineWidthPx),
+                        end = Offset(size.width, y = size.height - lineWidthPx),
+                        strokeWidth = lineWidthPx,
+                    )
+                },
+        )
+
+        Spacer(Modifier.height(100.dp))
+    }
+}
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
new file mode 100644
index 0000000..3afd33f
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bouncer.ui.composable
+
+import android.view.HapticFeedbackConstants
+import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.tween
+import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.gestures.detectDragGestures
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clipToBounds
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.StrokeCap
+import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.layout.onSizeChanged
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.res.integerResource
+import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.dp
+import com.android.internal.R
+import com.android.systemui.bouncer.ui.viewmodel.PatternBouncerViewModel
+import com.android.systemui.bouncer.ui.viewmodel.PatternDotViewModel
+import kotlin.math.min
+import kotlin.math.pow
+import kotlin.math.sqrt
+import kotlinx.coroutines.launch
+
+/**
+ * UI for the input part of a pattern-requiring version of the bouncer.
+ *
+ * The user can press, hold, and drag their pointer to select dots along a grid of dots.
+ */
+@Composable
+internal fun PatternBouncer(
+    viewModel: PatternBouncerViewModel,
+    modifier: Modifier = Modifier,
+) {
+    // Report that the UI is shown to let the view-model run some logic.
+    LaunchedEffect(Unit) { viewModel.onShown() }
+
+    val colCount = viewModel.columnCount
+    val rowCount = viewModel.rowCount
+
+    val dotColor = MaterialTheme.colorScheme.secondary
+    val dotRadius = with(LocalDensity.current) { 8.dp.toPx() }
+    val lineColor = MaterialTheme.colorScheme.primary
+    val lineStrokeWidth = dotRadius * 2 + with(LocalDensity.current) { 4.dp.toPx() }
+
+    var containerSize: IntSize by remember { mutableStateOf(IntSize(0, 0)) }
+    val horizontalSpacing = containerSize.width / colCount
+    val verticalSpacing = containerSize.height / rowCount
+    val spacing = min(horizontalSpacing, verticalSpacing).toFloat()
+    val verticalOffset = containerSize.height - spacing * rowCount
+
+    // All dots that should be rendered on the grid.
+    val dots: List<PatternDotViewModel> by viewModel.dots.collectAsState()
+    // The most recently selected dot, if the user is currently dragging.
+    val currentDot: PatternDotViewModel? by viewModel.currentDot.collectAsState()
+    // The dots selected so far, if the user is currently dragging.
+    val selectedDots: List<PatternDotViewModel> by viewModel.selectedDots.collectAsState()
+
+    // Map of animatables for the scale of each dot, keyed by dot.
+    val dotScalingAnimatables = remember(dots) { dots.associateWith { Animatable(1f) } }
+    // Map of animatables for the lines that connect between selected dots, keyed by the destination
+    // dot of the line.
+    val lineFadeOutAnimatables = remember(dots) { dots.associateWith { Animatable(1f) } }
+    val lineFadeOutAnimationDurationMs =
+        integerResource(R.integer.lock_pattern_line_fade_out_duration)
+    val lineFadeOutAnimationDelayMs = integerResource(R.integer.lock_pattern_line_fade_out_delay)
+
+    val scope = rememberCoroutineScope()
+    val view = LocalView.current
+
+    // When the current dot is changed, we need to update our animations.
+    LaunchedEffect(currentDot) {
+        view.performHapticFeedback(
+            HapticFeedbackConstants.VIRTUAL_KEY,
+            HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING,
+        )
+
+        // Make sure that the current dot is scaled up while the other dots are scaled back down.
+        dotScalingAnimatables.entries.forEach { (dot, animatable) ->
+            val isSelected = dot == currentDot
+            launch {
+                animatable.animateTo(if (isSelected) 2f else 1f)
+                if (isSelected) {
+                    animatable.animateTo(1f)
+                }
+            }
+        }
+
+        selectedDots.forEach { dot ->
+            lineFadeOutAnimatables[dot]?.let { line ->
+                if (!line.isRunning) {
+                    scope.launch {
+                        if (dot == currentDot) {
+                            // Reset the fade-out animation for the current dot. When the current
+                            // dot is switched, this entire code block runs again for the newly
+                            // selected dot.
+                            line.snapTo(1f)
+                        } else {
+                            // For all non-current dots, make sure that the lines are fading out.
+                            line.animateTo(
+                                targetValue = 0f,
+                                animationSpec =
+                                    tween(
+                                        durationMillis = lineFadeOutAnimationDurationMs,
+                                        delayMillis = lineFadeOutAnimationDelayMs,
+                                    ),
+                            )
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // This is the position of the input pointer.
+    var inputPosition: Offset? by remember { mutableStateOf(null) }
+
+    Canvas(
+        modifier
+            // Need to clip to bounds to make sure that the lines don't follow the input pointer
+            // when it leaves the bounds of the dot grid.
+            .clipToBounds()
+            .onSizeChanged { containerSize = it }
+            .pointerInput(Unit) {
+                detectDragGestures(
+                    onDragStart = { start ->
+                        inputPosition = start
+                        viewModel.onDragStart()
+                    },
+                    onDragEnd = {
+                        inputPosition = null
+                        lineFadeOutAnimatables.values.forEach { animatable ->
+                            scope.launch { animatable.animateTo(1f) }
+                        }
+                        viewModel.onDragEnd()
+                    },
+                ) { change, _ ->
+                    inputPosition = change.position
+                    viewModel.onDrag(
+                        xPx = change.position.x,
+                        yPx = change.position.y,
+                        containerSizePx = containerSize.width,
+                        verticalOffsetPx = verticalOffset,
+                    )
+                }
+            }
+    ) {
+        // Draw lines between dots.
+        selectedDots.forEachIndexed { index, dot ->
+            if (index > 0) {
+                val previousDot = selectedDots[index - 1]
+                val lineFadeOutAnimationProgress = lineFadeOutAnimatables[previousDot]!!.value
+                val startLerp = 1 - lineFadeOutAnimationProgress
+                val from = pixelOffset(previousDot, spacing, verticalOffset)
+                val to = pixelOffset(dot, spacing, verticalOffset)
+                val lerpedFrom =
+                    Offset(
+                        x = from.x + (to.x - from.x) * startLerp,
+                        y = from.y + (to.y - from.y) * startLerp,
+                    )
+                drawLine(
+                    start = lerpedFrom,
+                    end = to,
+                    cap = StrokeCap.Round,
+                    alpha = lineFadeOutAnimationProgress * lineAlpha(spacing),
+                    color = lineColor,
+                    strokeWidth = lineStrokeWidth,
+                )
+            }
+        }
+
+        // Draw the line between the most recently-selected dot and the input pointer position.
+        inputPosition?.let { lineEnd ->
+            currentDot?.let { dot ->
+                val from = pixelOffset(dot, spacing, verticalOffset)
+                val lineLength = sqrt((from.y - lineEnd.y).pow(2) + (from.x - lineEnd.x).pow(2))
+                drawLine(
+                    start = from,
+                    end = lineEnd,
+                    cap = StrokeCap.Round,
+                    alpha = lineAlpha(spacing, lineLength),
+                    color = lineColor,
+                    strokeWidth = lineStrokeWidth,
+                )
+            }
+        }
+
+        // Draw each dot on the grid.
+        dots.forEach { dot ->
+            drawCircle(
+                center = pixelOffset(dot, spacing, verticalOffset),
+                color = dotColor,
+                radius = dotRadius * (dotScalingAnimatables[dot]?.value ?: 1f),
+            )
+        }
+    }
+}
+
+/** Returns an [Offset] representation of the given [dot], in pixel coordinates. */
+private fun pixelOffset(
+    dot: PatternDotViewModel,
+    spacing: Float,
+    verticalOffset: Float,
+): Offset {
+    return Offset(
+        x = dot.x * spacing + spacing / 2,
+        y = dot.y * spacing + spacing / 2 + verticalOffset,
+    )
+}
+
+/**
+ * Returns the alpha for a line between dots where dots are normally [gridSpacing] apart from each
+ * other on the dot grid and the line ends [lineLength] away from the origin dot.
+ *
+ * The reason [lineLength] can be different from [gridSpacing] is that all lines originate in dots
+ * but one line might end where the user input pointer is, which isn't always a dot position.
+ */
+private fun lineAlpha(gridSpacing: Float, lineLength: Float = gridSpacing): Float {
+    // Custom curve for the alpha of a line as a function of its distance from its source dot. The
+    // farther the user input pointer goes from the line, the more opaque the line gets.
+    return ((lineLength / gridSpacing - 0.3f) * 4f).coerceIn(0f, 1f)
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
new file mode 100644
index 0000000..9c210c2
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalAnimationApi::class)
+
+package com.android.systemui.bouncer.ui.composable
+
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.ExperimentalAnimationApi
+import androidx.compose.animation.animateColorAsState
+import androidx.compose.animation.animateContentSize
+import androidx.compose.animation.core.animateDpAsState
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.animation.scaleIn
+import androidx.compose.animation.scaleOut
+import androidx.compose.animation.slideInHorizontally
+import androidx.compose.animation.slideOutHorizontally
+import androidx.compose.foundation.background
+import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.heightIn
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.geometry.CornerRadius
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import com.android.compose.grid.VerticalGrid
+import com.android.systemui.R
+import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.common.ui.compose.Icon
+import kotlin.math.max
+
+@Composable
+internal fun PinBouncer(
+    viewModel: PinBouncerViewModel,
+    modifier: Modifier = Modifier,
+) {
+    // Report that the UI is shown to let the view-model run some logic.
+    LaunchedEffect(Unit) { viewModel.onShown() }
+
+    // The length of the PIN input received so far, so we know how many dots to render.
+    val pinLength: Pair<Int, Int> by viewModel.pinLengths.collectAsState()
+
+    Column(
+        horizontalAlignment = Alignment.CenterHorizontally,
+        modifier = modifier,
+    ) {
+        Row(
+            horizontalArrangement = Arrangement.spacedBy(12.dp),
+            modifier = Modifier.heightIn(min = 16.dp).animateContentSize(),
+        ) {
+            // TODO(b/281871687): add support for dot shapes.
+            val (previousPinLength, currentPinLength) = pinLength
+            val dotCount = max(previousPinLength, currentPinLength) + 1
+            repeat(dotCount) { index ->
+                AnimatedVisibility(
+                    visible = index < currentPinLength,
+                    enter = fadeIn() + scaleIn() + slideInHorizontally(),
+                    exit = fadeOut() + scaleOut() + slideOutHorizontally(),
+                ) {
+                    Box(
+                        modifier =
+                            Modifier.size(16.dp)
+                                .background(
+                                    MaterialTheme.colorScheme.onSurfaceVariant,
+                                    CircleShape,
+                                )
+                    )
+                }
+            }
+        }
+
+        Spacer(Modifier.height(100.dp))
+
+        VerticalGrid(
+            columns = 3,
+            verticalSpacing = 12.dp,
+            horizontalSpacing = 20.dp,
+        ) {
+            repeat(9) { index ->
+                val digit = index + 1
+                PinButton(
+                    onClicked = { viewModel.onPinButtonClicked(digit) },
+                ) { contentColor ->
+                    PinDigit(digit, contentColor)
+                }
+            }
+
+            PinButton(
+                onClicked = { viewModel.onBackspaceButtonClicked() },
+                onLongPressed = { viewModel.onBackspaceButtonLongPressed() },
+                isHighlighted = true,
+            ) { contentColor ->
+                PinIcon(
+                    Icon.Resource(
+                        res = R.drawable.ic_backspace_24dp,
+                        contentDescription =
+                            ContentDescription.Resource(R.string.keyboardview_keycode_delete),
+                    ),
+                    contentColor,
+                )
+            }
+
+            PinButton(
+                onClicked = { viewModel.onPinButtonClicked(0) },
+            ) { contentColor ->
+                PinDigit(0, contentColor)
+            }
+
+            PinButton(
+                onClicked = { viewModel.onAuthenticateButtonClicked() },
+                isHighlighted = true,
+            ) { contentColor ->
+                PinIcon(
+                    Icon.Resource(
+                        res = R.drawable.ic_keyboard_tab_36dp,
+                        contentDescription =
+                            ContentDescription.Resource(R.string.keyboardview_keycode_enter),
+                    ),
+                    contentColor,
+                )
+            }
+        }
+    }
+}
+
+@Composable
+private fun PinDigit(
+    digit: Int,
+    contentColor: Color,
+) {
+    // TODO(b/281878426): once "color: () -> Color" (added to BasicText in aosp/2568972) makes it
+    //  into Text, use that here, to animate more efficiently.
+    Text(
+        text = digit.toString(),
+        style = MaterialTheme.typography.headlineLarge,
+        color = contentColor,
+    )
+}
+
+@Composable
+private fun PinIcon(
+    icon: Icon,
+    contentColor: Color,
+) {
+    Icon(
+        icon = icon,
+        tint = contentColor,
+    )
+}
+
+@Composable
+private fun PinButton(
+    onClicked: () -> Unit,
+    modifier: Modifier = Modifier,
+    onLongPressed: (() -> Unit)? = null,
+    isHighlighted: Boolean = false,
+    content: @Composable (contentColor: Color) -> Unit,
+) {
+    var isPressed: Boolean by remember { mutableStateOf(false) }
+    val cornerRadius: Dp by
+        animateDpAsState(
+            if (isPressed) 24.dp else PinButtonSize / 2,
+            label = "PinButton round corners",
+        )
+    val containerColor: Color by
+        animateColorAsState(
+            when {
+                isPressed -> MaterialTheme.colorScheme.primaryContainer
+                isHighlighted -> MaterialTheme.colorScheme.secondaryContainer
+                else -> MaterialTheme.colorScheme.surface
+            },
+            label = "Pin button container color",
+        )
+    val contentColor: Color by
+        animateColorAsState(
+            when {
+                isPressed -> MaterialTheme.colorScheme.onPrimaryContainer
+                isHighlighted -> MaterialTheme.colorScheme.onSecondaryContainer
+                else -> MaterialTheme.colorScheme.onSurface
+            },
+            label = "Pin button container color",
+        )
+
+    Box(
+        contentAlignment = Alignment.Center,
+        modifier =
+            modifier
+                .size(PinButtonSize)
+                .drawBehind {
+                    drawRoundRect(
+                        color = containerColor,
+                        cornerRadius = CornerRadius(cornerRadius.toPx()),
+                    )
+                }
+                .pointerInput(Unit) {
+                    detectTapGestures(
+                        onPress = {
+                            isPressed = true
+                            tryAwaitRelease()
+                            isPressed = false
+                        },
+                        onTap = { onClicked() },
+                        onLongPress = onLongPressed?.let { { onLongPressed() } },
+                    )
+                },
+    ) {
+        content(contentColor)
+    }
+}
+
+private val PinButtonSize = 84.dp
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
new file mode 100644
index 0000000..1065267
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.composable
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.material3.Button
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.common.ui.compose.Icon
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel
+import com.android.systemui.scene.shared.model.Direction
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
+import com.android.systemui.scene.shared.model.UserAction
+import com.android.systemui.scene.ui.composable.ComposableScene
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+/** The lock screen scene shows when the device is locked. */
+class LockscreenScene(
+    @Application private val applicationScope: CoroutineScope,
+    private val viewModel: LockscreenSceneViewModel,
+) : ComposableScene {
+    override val key = SceneKey.Lockscreen
+
+    override fun destinationScenes(
+        containerName: String,
+    ): StateFlow<Map<UserAction, SceneModel>> =
+        viewModel.upDestinationSceneKey
+            .map { pageKey -> destinationScenes(up = pageKey) }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.Eagerly,
+                initialValue = destinationScenes(up = viewModel.upDestinationSceneKey.value)
+            )
+
+    @Composable
+    override fun Content(
+        containerName: String,
+        modifier: Modifier,
+    ) {
+        LockscreenScene(
+            viewModel = viewModel,
+            modifier = modifier,
+        )
+    }
+
+    private fun destinationScenes(
+        up: SceneKey,
+    ): Map<UserAction, SceneModel> {
+        return mapOf(
+            UserAction.Swipe(Direction.UP) to SceneModel(up),
+            UserAction.Swipe(Direction.DOWN) to SceneModel(SceneKey.Shade)
+        )
+    }
+}
+
+@Composable
+private fun LockscreenScene(
+    viewModel: LockscreenSceneViewModel,
+    modifier: Modifier = Modifier,
+) {
+    // TODO(b/280879610): implement the real UI.
+
+    val lockButtonIcon: Icon by viewModel.lockButtonIcon.collectAsState()
+
+    Box(modifier = modifier) {
+        Column(
+            horizontalAlignment = Alignment.CenterHorizontally,
+            modifier = Modifier.align(Alignment.Center)
+        ) {
+            Text("Lockscreen", style = MaterialTheme.typography.headlineMedium)
+            Row(
+                horizontalArrangement = Arrangement.spacedBy(8.dp),
+            ) {
+                Button(onClick = { viewModel.onLockButtonClicked() }) { Icon(lockButtonIcon) }
+
+                Button(onClick = { viewModel.onContentClicked() }) { Text("Open some content") }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
index a74e56b..f88fc21 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
@@ -91,7 +91,7 @@
 
     // Make sure to use the Android colors and not the default Material3 colors to have the exact
     // same colors as the View implementation.
-    val androidColors = LocalAndroidColorScheme.current
+    val androidColors = LocalAndroidColorScheme.current.deprecated
     Surface(
         color = androidColors.colorBackground,
         contentColor = androidColors.textColorPrimary,
@@ -170,7 +170,7 @@
             stringResource(headerTextResource),
             Modifier.padding(start = 16.dp),
             style = MaterialTheme.typography.labelLarge,
-            color = LocalAndroidColorScheme.current.colorAccentPrimaryVariant,
+            color = LocalAndroidColorScheme.current.deprecated.colorAccentPrimaryVariant,
         )
 
         Spacer(Modifier.height(10.dp))
@@ -180,7 +180,7 @@
         if (index > 0) {
             item {
                 Divider(
-                    color = LocalAndroidColorScheme.current.colorBackground,
+                    color = LocalAndroidColorScheme.current.deprecated.colorBackground,
                     thickness = 2.dp,
                 )
             }
@@ -204,7 +204,7 @@
     withTopCornerRadius: Boolean,
     withBottomCornerRadius: Boolean,
 ) {
-    val androidColors = LocalAndroidColorScheme.current
+    val androidColors = LocalAndroidColorScheme.current.deprecated
     val cornerRadius = dimensionResource(R.dimen.people_space_widget_radius)
     val topCornerRadius = if (withTopCornerRadius) cornerRadius else 0.dp
     val bottomCornerRadius = if (withBottomCornerRadius) cornerRadius else 0.dp
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
index 0484ff4..1e6f4a2 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
@@ -76,8 +76,8 @@
             Modifier.fillMaxWidth().defaultMinSize(minHeight = 56.dp),
             colors =
                 ButtonDefaults.buttonColors(
-                    containerColor = androidColors.colorAccentPrimary,
-                    contentColor = androidColors.textColorOnAccent,
+                    containerColor = androidColors.deprecated.colorAccentPrimary,
+                    contentColor = androidColors.deprecated.textColorOnAccent,
                 )
         ) {
             Text(stringResource(R.string.got_it))
@@ -90,8 +90,8 @@
     val androidColors = LocalAndroidColorScheme.current
     Surface(
         shape = RoundedCornerShape(28.dp),
-        color = androidColors.colorSurface,
-        contentColor = androidColors.textColorPrimary,
+        color = androidColors.deprecated.colorSurface,
+        contentColor = androidColors.deprecated.textColorPrimary,
     ) {
         Row(
             Modifier.padding(vertical = 20.dp, horizontal = 16.dp),
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
index 349f5c3..75bf281 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
@@ -122,7 +122,7 @@
     }
 
     val backgroundColor = colorAttr(R.attr.underSurfaceColor)
-    val contentColor = LocalAndroidColorScheme.current.textColorPrimary
+    val contentColor = LocalAndroidColorScheme.current.deprecated.textColorPrimary
     val backgroundTopRadius = dimensionResource(R.dimen.qs_corner_radius)
     val backgroundModifier =
         remember(
@@ -287,7 +287,7 @@
                     number.toString(),
                     modifier = Modifier.align(Alignment.Center),
                     style = MaterialTheme.typography.bodyLarge,
-                    color = LocalAndroidColorScheme.current.textColorPrimary,
+                    color = LocalAndroidColorScheme.current.deprecated.textColorPrimary,
                     // TODO(b/242040009): This should only use a standard text style instead and
                     // should not override the text size.
                     fontSize = 18.sp,
@@ -305,7 +305,7 @@
 @Composable
 private fun NewChangesDot(modifier: Modifier = Modifier) {
     val contentDescription = stringResource(R.string.fgs_dot_content_description)
-    val color = LocalAndroidColorScheme.current.colorAccentTertiary
+    val color = LocalAndroidColorScheme.current.deprecated.colorAccentTertiary
 
     Canvas(modifier.size(12.dp).semantics { this.contentDescription = contentDescription }) {
         drawCircle(color)
@@ -324,8 +324,9 @@
     Expandable(
         shape = CircleShape,
         color = colorAttr(R.attr.underSurfaceColor),
-        contentColor = LocalAndroidColorScheme.current.textColorSecondary,
-        borderStroke = BorderStroke(1.dp, LocalAndroidColorScheme.current.colorBackground),
+        contentColor = LocalAndroidColorScheme.current.deprecated.textColorSecondary,
+        borderStroke =
+            BorderStroke(1.dp, LocalAndroidColorScheme.current.deprecated.colorBackground),
         modifier = modifier.padding(horizontal = 4.dp),
         onClick = onClick,
     ) {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
new file mode 100644
index 0000000..30b80ca
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.ui.composable
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.material3.Button
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneViewModel
+import com.android.systemui.scene.shared.model.Direction
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
+import com.android.systemui.scene.shared.model.UserAction
+import com.android.systemui.scene.ui.composable.ComposableScene
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+/** The Quick Settings (AKA "QS") scene shows the quick setting tiles. */
+class QuickSettingsScene(
+    private val viewModel: QuickSettingsSceneViewModel,
+) : ComposableScene {
+    override val key = SceneKey.QuickSettings
+
+    override fun destinationScenes(
+        containerName: String,
+    ): StateFlow<Map<UserAction, SceneModel>> =
+        MutableStateFlow<Map<UserAction, SceneModel>>(
+                mapOf(
+                    UserAction.Swipe(Direction.UP) to SceneModel(SceneKey.Shade),
+                )
+            )
+            .asStateFlow()
+
+    @Composable
+    override fun Content(
+        containerName: String,
+        modifier: Modifier,
+    ) {
+        QuickSettingsScene(
+            viewModel = viewModel,
+            modifier = modifier,
+        )
+    }
+}
+
+@Composable
+private fun QuickSettingsScene(
+    viewModel: QuickSettingsSceneViewModel,
+    modifier: Modifier = Modifier,
+) {
+    // TODO(b/280887232): implement the real UI.
+
+    Box(modifier = modifier) {
+        Column(
+            horizontalAlignment = Alignment.CenterHorizontally,
+            modifier = Modifier.align(Alignment.Center)
+        ) {
+            Text("Quick settings", style = MaterialTheme.typography.headlineMedium)
+            Row(
+                horizontalArrangement = Arrangement.spacedBy(8.dp),
+            ) {
+                Button(onClick = { viewModel.onContentClicked() }) { Text("Open some content") }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/ComposableScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/ComposableScene.kt
new file mode 100644
index 0000000..6f3363e
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/ComposableScene.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene.ui.composable
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import com.android.systemui.scene.shared.model.Scene
+
+/** Compose-capable extension of [Scene]. */
+interface ComposableScene : Scene {
+    @Composable fun Content(containerName: String, modifier: Modifier)
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
new file mode 100644
index 0000000..0a4da1d
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene.ui.composable
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import com.android.systemui.scene.shared.model.Direction
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
+import com.android.systemui.scene.shared.model.UserAction
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+/**
+ * "Gone" is not a real scene but rather the absence of scenes when we want to skip showing any
+ * content from the scene framework.
+ */
+class GoneScene : ComposableScene {
+    override val key = SceneKey.Gone
+
+    override fun destinationScenes(
+        containerName: String,
+    ): StateFlow<Map<UserAction, SceneModel>> =
+        MutableStateFlow<Map<UserAction, SceneModel>>(
+                mapOf(
+                    UserAction.Swipe(Direction.DOWN) to SceneModel(SceneKey.Shade),
+                )
+            )
+            .asStateFlow()
+
+    @Composable
+    override fun Content(
+        containerName: String,
+        modifier: Modifier,
+    ) {
+        /*
+         * TODO(b/279501596): once we start testing with the real Content Dynamics Framework,
+         *  replace this with an error to make sure it doesn't get rendered.
+         */
+        Box(modifier = modifier) {
+            Column(
+                horizontalAlignment = Alignment.CenterHorizontally,
+                modifier = Modifier.align(Alignment.Center)
+            ) {
+                Text("Gone", style = MaterialTheme.typography.headlineMedium)
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
new file mode 100644
index 0000000..5e07610
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalAnimationApi::class)
+
+package com.android.systemui.scene.ui.composable
+
+import androidx.activity.compose.BackHandler
+import androidx.compose.animation.AnimatedContent
+import androidx.compose.animation.ExperimentalAnimationApi
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material3.Button
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import com.android.systemui.scene.shared.model.Direction
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
+import com.android.systemui.scene.shared.model.UserAction
+import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
+import java.util.Locale
+
+/**
+ * Renders a container of a collection of "scenes" that the user can switch between using certain
+ * user actions (for instance, swiping up and down) or that can be switched automatically based on
+ * application business logic in response to certain events (for example, the device unlocking).
+ *
+ * It's possible for the application to host several such scene containers, the configuration system
+ * allows configuring each container with its own set of scenes. Scenes can be present in multiple
+ * containers.
+ *
+ * @param viewModel The UI state holder for this container.
+ * @param sceneByKey Mapping of [ComposableScene] by [SceneKey], ordered by z-order such that the
+ *   last scene is rendered on top of all other scenes. It's critical that this map contains exactly
+ *   and only the scenes on this container. In other words: (a) there should be no scene in this map
+ *   that is not in the configuration for this container and (b) all scenes in the configuration
+ *   must have entries in this map.
+ * @param modifier A modifier.
+ */
+@Composable
+fun SceneContainer(
+    viewModel: SceneContainerViewModel,
+    sceneByKey: Map<SceneKey, ComposableScene>,
+    modifier: Modifier = Modifier,
+) {
+    val currentScene: SceneModel by viewModel.currentScene.collectAsState()
+
+    AnimatedContent(
+        targetState = currentScene.key,
+        label = "scene container",
+        modifier = modifier,
+    ) { currentSceneKey ->
+        sceneByKey.forEach { (key, composableScene) ->
+            if (key == currentSceneKey) {
+                Scene(
+                    scene = composableScene,
+                    containerName = viewModel.containerName,
+                    onSceneChanged = viewModel::setCurrentScene,
+                    modifier = Modifier.fillMaxSize(),
+                )
+            }
+        }
+    }
+}
+
+/** Renders the given [ComposableScene]. */
+@Composable
+private fun Scene(
+    scene: ComposableScene,
+    containerName: String,
+    onSceneChanged: (SceneModel) -> Unit,
+    modifier: Modifier = Modifier,
+) {
+    // TODO(b/280880714): replace with the real UI and make sure to call onTransitionProgress.
+    Box(modifier) {
+        Column(
+            horizontalAlignment = Alignment.CenterHorizontally,
+            modifier = Modifier.align(Alignment.Center),
+        ) {
+            scene.Content(
+                containerName = containerName,
+                modifier = Modifier,
+            )
+
+            val destinationScenes: Map<UserAction, SceneModel> by
+                scene.destinationScenes(containerName).collectAsState()
+            val swipeLeftDestinationScene = destinationScenes[UserAction.Swipe(Direction.LEFT)]
+            val swipeUpDestinationScene = destinationScenes[UserAction.Swipe(Direction.UP)]
+            val swipeRightDestinationScene = destinationScenes[UserAction.Swipe(Direction.RIGHT)]
+            val swipeDownDestinationScene = destinationScenes[UserAction.Swipe(Direction.DOWN)]
+            val backDestinationScene = destinationScenes[UserAction.Back]
+
+            Row(
+                horizontalArrangement = Arrangement.spacedBy(8.dp),
+            ) {
+                DirectionalButton(Direction.LEFT, swipeLeftDestinationScene, onSceneChanged)
+                DirectionalButton(Direction.UP, swipeUpDestinationScene, onSceneChanged)
+                DirectionalButton(Direction.RIGHT, swipeRightDestinationScene, onSceneChanged)
+                DirectionalButton(Direction.DOWN, swipeDownDestinationScene, onSceneChanged)
+            }
+
+            if (backDestinationScene != null) {
+                BackHandler { onSceneChanged.invoke(backDestinationScene) }
+            }
+        }
+    }
+}
+
+@Composable
+private fun DirectionalButton(
+    direction: Direction,
+    destinationScene: SceneModel?,
+    onSceneChanged: (SceneModel) -> Unit,
+    modifier: Modifier = Modifier,
+) {
+    Button(
+        onClick = { destinationScene?.let { onSceneChanged.invoke(it) } },
+        enabled = destinationScene != null,
+        modifier = modifier,
+    ) {
+        Text(direction.name.lowercase(Locale.getDefault()))
+    }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
new file mode 100644
index 0000000..20e1751
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade.ui.composable
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.material3.Button
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.scene.shared.model.Direction
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
+import com.android.systemui.scene.shared.model.UserAction
+import com.android.systemui.scene.ui.composable.ComposableScene
+import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+/** The shade scene shows scrolling list of notifications and some of the quick setting tiles. */
+class ShadeScene(
+    @Application private val applicationScope: CoroutineScope,
+    private val viewModel: ShadeSceneViewModel,
+) : ComposableScene {
+    override val key = SceneKey.Shade
+
+    override fun destinationScenes(
+        containerName: String,
+    ): StateFlow<Map<UserAction, SceneModel>> =
+        viewModel.upDestinationSceneKey
+            .map { sceneKey -> destinationScenes(up = sceneKey) }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.Eagerly,
+                initialValue = destinationScenes(up = viewModel.upDestinationSceneKey.value),
+            )
+
+    @Composable
+    override fun Content(
+        containerName: String,
+        modifier: Modifier,
+    ) {
+        ShadeScene(
+            viewModel = viewModel,
+            modifier = modifier,
+        )
+    }
+
+    private fun destinationScenes(
+        up: SceneKey,
+    ): Map<UserAction, SceneModel> {
+        return mapOf(
+            UserAction.Swipe(Direction.UP) to SceneModel(up),
+            UserAction.Swipe(Direction.DOWN) to SceneModel(SceneKey.QuickSettings),
+        )
+    }
+}
+
+@Composable
+private fun ShadeScene(
+    viewModel: ShadeSceneViewModel,
+    modifier: Modifier = Modifier,
+) {
+    // TODO(b/280887022): implement the real UI.
+
+    Box(modifier = modifier) {
+        Column(
+            horizontalAlignment = Alignment.CenterHorizontally,
+            modifier = Modifier.align(Alignment.Center)
+        ) {
+            Text("Shade", style = MaterialTheme.typography.headlineMedium)
+            Row(
+                horizontalArrangement = Arrangement.spacedBy(8.dp),
+            ) {
+                Button(
+                    onClick = { viewModel.onContentClicked() },
+                ) {
+                    Text("Open some content")
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
index 8dd2c39..465b73e 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
@@ -272,6 +272,7 @@
             color = lockScreenColor,
             animate = isAnimationEnabled,
             duration = APPEAR_ANIM_DURATION,
+            interpolator = Interpolators.EMPHASIZED_DECELERATE,
             delay = 0,
             onAnimationEnd = null
         )
@@ -562,7 +563,7 @@
         private const val DOUBLE_LINE_FORMAT_12_HOUR = "hh\nmm"
         private const val DOUBLE_LINE_FORMAT_24_HOUR = "HH\nmm"
         private const val DOZE_ANIM_DURATION: Long = 300
-        private const val APPEAR_ANIM_DURATION: Long = 350
+        private const val APPEAR_ANIM_DURATION: Long = 833
         private const val CHARGE_ANIM_DURATION_PHASE_0: Long = 500
         private const val CHARGE_ANIM_DURATION_PHASE_1: Long = 1000
         private const val COLOR_ANIM_DURATION: Long = 400
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
index aa1bb3f..7c76281 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
@@ -404,14 +404,12 @@
         }
 
         scope.launch(bgDispatcher) {
-            Log.i(TAG, "verifyLoadedProviders: ${availableClocks.size}")
             if (keepAllLoaded) {
                 // Enforce that all plugins are loaded if requested
                 for ((_, info) in availableClocks) {
                     info.manager?.loadPlugin()
                 }
                 isVerifying.set(false)
-                Log.i(TAG, "verifyLoadedProviders: keepAllLoaded=true, load all")
                 return@launch
             }
 
@@ -422,21 +420,16 @@
                     info.manager?.unloadPlugin()
                 }
                 isVerifying.set(false)
-                Log.i(TAG, "verifyLoadedProviders: currentClock unavailable, unload all")
                 return@launch
             }
 
             val currentManager = currentClock.manager
             currentManager?.loadPlugin()
-            Log.i(TAG, "verifyLoadedProviders: load ${currentClock.metadata.clockId}")
 
             for ((_, info) in availableClocks) {
                 val manager = info.manager
                 if (manager != null && manager.isLoaded && currentManager != manager) {
-                    Log.i(TAG, "verifyLoadedProviders: unload ${info.metadata.clockId}")
                     manager.unloadPlugin()
-                } else {
-                    Log.i(TAG, "verifyLoadedProviders: skip unload of ${info.metadata.clockId}")
                 }
             }
             isVerifying.set(false)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
index 6aa74fb..252c8e3 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
@@ -265,7 +265,7 @@
             }
         }
 
-        override fun onPickerCarouselSwiping(swipingFraction: Float, previewRatio: Float) {
+        override fun onPickerCarouselSwiping(swipingFraction: Float) {
             // TODO(b/278936436): refactor this part when we change recomputePadding
             // when on the side, swipingFraction = 0, translationY should offset
             // the top margin change in recomputePadding to make clock be centered
diff --git a/packages/SystemUI/docs/device-entry/keyguard.md b/packages/SystemUI/docs/device-entry/keyguard.md
index 8634c95..1898b97 100644
--- a/packages/SystemUI/docs/device-entry/keyguard.md
+++ b/packages/SystemUI/docs/device-entry/keyguard.md
@@ -20,6 +20,10 @@
 
 An indication to power off the device most likely comes from one of two signals: the user presses the power button or the screen timeout has passed. This may [lock the device](#How-the-device-locks)
 
+#### Long-pressing on keyguard
+
+OEMs may choose to enable a long-press action that displays a button at the bottom of lockscreen. This button links to lockscreen customization. This can be achieved by overriding the `long_press_keyguard_customize_lockscreen_enabled` resource in `packages/SystemUI/res/values/config.xml`.
+
 #### On Lockscreen
 
 #### On Lockscreen, occluded by an activity
diff --git a/packages/SystemUI/docs/device-entry/quickaffordance.md b/packages/SystemUI/docs/device-entry/quickaffordance.md
index d662649..afcf846 100644
--- a/packages/SystemUI/docs/device-entry/quickaffordance.md
+++ b/packages/SystemUI/docs/device-entry/quickaffordance.md
@@ -17,7 +17,9 @@
 By default, AOSP ships with a "bottom right" and a "bottom left" slot, each with a slot capacity of `1`, allowing only one Quick Affordance on each side of the lock screen.
 
 ### Customizing Slots
-OEMs may choose to override the IDs and number of slots and/or override the default capacities. This can be achieved by overridding the `config_keyguardQuickAffordanceSlots` resource in `packages/SystemUI/res/values/config.xml`.
+OEMs may choose to enable customization of slots. An entry point in settings will appear when overriding the `custom_lockscreen_shortcuts_enabled` resource in `packages/SystemUI/res/values/config.xml`.
+
+OEMs may also choose to override the IDs and number of slots and/or override the default capacities. This can be achieved by overridding the `config_keyguardQuickAffordanceSlots` resource in `packages/SystemUI/res/values/config.xml`.
 
 ### Default Quick Affordances
 OEMs may also choose to predefine default Quick Affordances for each slot. To achieve this, a developer may override the `config_keyguardQuickAffordanceDefaults` resource in `packages/SystemUI/res/values/config.xml`. Note that defaults only work until the user of the device selects a different quick affordance for that slot, even if they select the "None" option.
diff --git a/packages/SystemUI/log/src/com/android/systemui/log/LogBuffer.kt b/packages/SystemUI/log/src/com/android/systemui/log/LogBuffer.kt
index af1a11f..2007e76 100644
--- a/packages/SystemUI/log/src/com/android/systemui/log/LogBuffer.kt
+++ b/packages/SystemUI/log/src/com/android/systemui/log/LogBuffer.kt
@@ -271,11 +271,13 @@
     }
 
     private fun echoToSystrace(message: LogMessage, strMessage: String) {
-        Trace.instantForTrack(
-            Trace.TRACE_TAG_APP,
-            "UI Events",
-            "$name - ${message.level.shortString} ${message.tag}: $strMessage"
-        )
+        if (Trace.isTagEnabled(Trace.TRACE_TAG_APP)) {
+            Trace.instantForTrack(
+                Trace.TRACE_TAG_APP,
+                "UI Events",
+                "$name - ${message.level.shortString} ${message.tag}: $strMessage"
+            )
+        }
     }
 
     private fun echoToLogcat(message: LogMessage, strMessage: String) {
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
index 33c7c11..2baeaf6 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
@@ -61,7 +61,6 @@
      */
     void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade, int flags);
     void startActivity(Intent intent, boolean dismissShade);
-
     default void startActivity(Intent intent, boolean dismissShade,
             @Nullable ActivityLaunchAnimator.Controller animationController) {
         startActivity(intent, dismissShade, animationController,
@@ -105,6 +104,11 @@
     /** Starts an activity and dismisses keyguard. */
     void startActivityDismissingKeyguard(Intent intent,
             boolean onlyProvisioned,
+            boolean dismissShade);
+
+    /** Starts an activity and dismisses keyguard. */
+    void startActivityDismissingKeyguard(Intent intent,
+            boolean onlyProvisioned,
             boolean dismissShade,
             boolean disallowEnterPictureInPictureWhileLaunching,
             Callback callback,
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
index 7bf139e..5d0a3af 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
@@ -156,7 +156,7 @@
      * Runs when swiping clock picker, swipingFraction: 1.0 -> clock is scaled up in the preview,
      * 0.0 -> clock is scaled down in the shade; previewRatio is previewSize / screenSize
      */
-    fun onPickerCarouselSwiping(swipingFraction: Float, previewRatio: Float) {}
+    fun onPickerCarouselSwiping(swipingFraction: Float) {}
 }
 
 /** Events that have specific data about the related face */
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt
index 2dd146c5..a4b1cee 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt
@@ -1,6 +1,7 @@
 package com.android.systemui.plugins
 
 import android.os.Bundle
+import android.util.Log
 import androidx.annotation.VisibleForTesting
 
 class WeatherData
@@ -11,6 +12,7 @@
     val temperature: Int,
 ) {
     companion object {
+        const val DEBUG = true
         private const val TAG = "WeatherData"
         @VisibleForTesting const val DESCRIPTION_KEY = "description"
         @VisibleForTesting const val STATE_KEY = "state"
@@ -23,20 +25,29 @@
             val state =
                 WeatherStateIcon.fromInt(extras.getInt(STATE_KEY, INVALID_WEATHER_ICON_STATE))
             val temperature = readIntFromBundle(extras, TEMPERATURE_KEY)
-            return if (
+            if (
                 description == null ||
                     state == null ||
                     !extras.containsKey(USE_CELSIUS_KEY) ||
                     temperature == null
-            )
-                null
-            else
-                WeatherData(
-                    description = description,
-                    state = state,
-                    useCelsius = extras.getBoolean(USE_CELSIUS_KEY),
-                    temperature = temperature
-                )
+            ) {
+                if (DEBUG) {
+                    Log.w(TAG, "Weather data did not parse from $extras")
+                }
+                return null
+            } else {
+                val result =
+                    WeatherData(
+                        description = description,
+                        state = state,
+                        useCelsius = extras.getBoolean(USE_CELSIUS_KEY),
+                        temperature = temperature
+                    )
+                if (DEBUG) {
+                    Log.i(TAG, "Weather data parsed $result from $extras")
+                }
+                return result
+            }
         }
 
         private fun readIntFromBundle(extras: Bundle, key: String): Int? =
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/TableLogBufferBase.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/TableLogBufferBase.kt
new file mode 100644
index 0000000..50b3f78
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/log/TableLogBufferBase.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.plugins.log
+
+/**
+ * Base interface for a logger that logs changes in table format.
+ *
+ * This is a plugin interface for classes outside of SystemUI core.
+ */
+interface TableLogBufferBase {
+    /**
+     * Logs a String? change.
+     *
+     * For Java overloading.
+     */
+    fun logChange(prefix: String, columnName: String, value: String?) {
+        logChange(prefix, columnName, value, isInitial = false)
+    }
+
+    /** Logs a String? change. */
+    fun logChange(prefix: String, columnName: String, value: String?, isInitial: Boolean)
+
+    /**
+     * Logs a Boolean change.
+     *
+     * For Java overloading.
+     */
+    fun logChange(prefix: String, columnName: String, value: Boolean) {
+        logChange(prefix, columnName, value, isInitial = false)
+    }
+
+    /** Logs a Boolean change. */
+    fun logChange(prefix: String, columnName: String, value: Boolean, isInitial: Boolean)
+
+    /**
+     * Logs an Int? change.
+     *
+     * For Java overloading.
+     */
+    fun logChange(prefix: String, columnName: String, value: Int?) {
+        logChange(prefix, columnName, value, isInitial = false)
+    }
+
+    /** Logs an Int? change. */
+    fun logChange(prefix: String, columnName: String, value: Int?, isInitial: Boolean)
+}
diff --git a/packages/SystemUI/res-keyguard/layout/bouncer_message_view.xml b/packages/SystemUI/res-keyguard/layout/bouncer_message_view.xml
new file mode 100644
index 0000000..f7dac13
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/bouncer_message_view.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <com.android.keyguard.BouncerKeyguardMessageArea
+        android:id="@+id/bouncer_primary_message_area"
+        style="@style/Keyguard.Bouncer.PrimaryMessage"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/keyguard_lock_padding"
+        android:focusable="true"
+         />
+
+    <com.android.keyguard.BouncerKeyguardMessageArea
+        android:id="@+id/bouncer_secondary_message_area"
+        style="@style/Keyguard.Bouncer.SecondaryMessage"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/secondary_message_padding"
+        android:focusable="true" />
+
+</merge>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
index 4b94707..3fc0965 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
@@ -25,7 +25,7 @@
     android:layout_height="wrap_content"
     android:clipChildren="false"
     android:layout_gravity="center_horizontal|top">
-    <FrameLayout
+    <com.android.keyguard.KeyguardClockFrame
         android:id="@+id/lockscreen_clock_view"
         android:layout_width="wrap_content"
         android:layout_height="@dimen/small_clock_height"
@@ -34,7 +34,7 @@
         android:clipChildren="false"
         android:paddingStart="@dimen/clock_padding_start"
         android:visibility="invisible" />
-    <FrameLayout
+    <com.android.keyguard.KeyguardClockFrame
         android:id="@+id/lockscreen_clock_view_large"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_emergency_carrier_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_emergency_carrier_area.xml
index 8bb7877..371670c 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_emergency_carrier_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_emergency_carrier_area.xml
@@ -39,7 +39,8 @@
         android:ellipsize="marquee"
         android:visibility="gone"
         android:gravity="center"
-        androidprv:allCaps="@bool/kg_use_all_caps" />
+        androidprv:allCaps="@bool/kg_use_all_caps"
+        androidprv:debugLocation="Emergency" />
 
     <com.android.keyguard.EmergencyButton
         android:id="@+id/emergency_call_button"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
index 6ec65ce..3412a30 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
@@ -29,6 +29,13 @@
     >
     <include layout="@layout/keyguard_bouncer_message_area"/>
 
+    <com.android.systemui.keyguard.bouncer.ui.BouncerMessageView
+        android:id="@+id/bouncer_message_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+    />
+
     <Space
         android:layout_width="match_parent"
         android:layout_height="0dp"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
index c772c96..78a7c17 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
@@ -33,6 +33,12 @@
     android:clipToPadding="false">
     <include layout="@layout/keyguard_bouncer_message_area"/>
 
+    <com.android.systemui.keyguard.bouncer.ui.BouncerMessageView
+        android:id="@+id/bouncer_message_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical" />
+
     <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/pattern_container"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
index f61df05..01c5443 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
@@ -29,6 +29,12 @@
     androidprv:layout_maxWidth="@dimen/keyguard_security_width">
 <include layout="@layout/keyguard_bouncer_message_area"/>
 
+<com.android.systemui.keyguard.bouncer.ui.BouncerMessageView
+    android:id="@+id/bouncer_message_view"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical" />
+
 <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/pin_container"
         android:layout_width="match_parent"
@@ -76,7 +82,7 @@
             androidprv:layout_constraintGuide_percent="0"
             android:orientation="horizontal" />
 
-        <androidx.constraintlayout.helper.widget.Flow
+        <com.android.keyguard.KeyguardPinFlowView
             android:id="@+id/flow1"
             android:layout_width="0dp"
             android:layout_height="0dp"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml
index 751b07a..dc58d50 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml
@@ -19,9 +19,7 @@
 
 <com.android.keyguard.KeyguardSecurityContainer
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:id="@+id/keyguard_security_container"
-    android:background="?androidprv:attr/materialColorSurfaceContainer"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:clipChildren="false"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index 647abee..557fbf2 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -30,7 +30,7 @@
     android:clipChildren="false"
     android:layout_width="0dp"
     android:layout_height="wrap_content">
-    <LinearLayout
+    <com.android.keyguard.KeyguardStatusContainer
         android:id="@+id/status_view_container"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
@@ -48,5 +48,5 @@
             android:layout_height="wrap_content"
             android:padding="@dimen/qs_media_padding"
             />
-    </LinearLayout>
+    </com.android.keyguard.KeyguardStatusContainer>
 </com.android.keyguard.KeyguardStatusView>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index 89c3635..8b31fe0 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -61,7 +61,7 @@
     <string name="kg_wrong_pin" msgid="4160978845968732624">"El PIN no és correcte"</string>
     <string name="kg_wrong_pin_try_again" msgid="3129729383303430190">"PIN incorrecte. Torna-hi."</string>
     <string name="kg_wrong_input_try_fp_suggestion" msgid="3143861542242024833">"O desbloqueja amb l\'empremta digital"</string>
-    <string name="kg_fp_not_recognized" msgid="5183108260932029241">"L\'empremta no es reconeix"</string>
+    <string name="kg_fp_not_recognized" msgid="5183108260932029241">"L\'empremta no s\'ha reconegut"</string>
     <string name="bouncer_face_not_recognized" msgid="1666128054475597485">"No s\'ha reconegut la cara"</string>
     <string name="kg_bio_try_again_or_pin" msgid="4752168242723808390">"Torna-ho a provar o introdueix el PIN"</string>
     <string name="kg_bio_try_again_or_password" msgid="1473132729225398039">"Torna-ho a provar o introdueix la contrasenya"</string>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index be03ec4..b0dc3be 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -41,7 +41,7 @@
     <string name="keyguard_missing_sim_instructions" msgid="7735360104844653246">"Gehitu SIM bat."</string>
     <string name="keyguard_missing_sim_instructions_long" msgid="3451467338947610268">"SIMa falta da, edo ezin da irakurri. Gehitu SIM bat."</string>
     <string name="keyguard_permanent_disabled_sim_message_short" msgid="3955052454216046100">"Ezin da erabili SIMa."</string>
-    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Betiko desaktibatu da SIMa.\n Jarri harremanetan operadorearekin beste SIM bat eskuratzeko."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5034635040020685428">"Betiko desaktibatu da SIMa.\n Jarri operadorearekin harremanetan beste SIM bat eskuratzeko."</string>
     <string name="keyguard_sim_locked_message" msgid="7095293254587575270">"SIMa blokeatuta dago."</string>
     <string name="keyguard_sim_puk_locked_message" msgid="2503428315518592542">"SIMa PUKaren bidez desblokeatu behar da."</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="8489092646014631659">"SIMa desblokeatzen…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml
index 9aa47a7..985f77ac 100644
--- a/packages/SystemUI/res-keyguard/values-hy/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml
@@ -124,5 +124,5 @@
     <string name="clock_title_default" msgid="6342735240617459864">"Կանխադրված"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Պղպջակ"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Անալոգային"</string>
-    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Շարունակելու համար ապակողպեք ձեր սարքը"</string>
+    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Շարունակելու համար ապակողպեք սարքը"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index 28d1910..666f9b1 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -112,9 +112,9 @@
     <string name="kg_prompt_reason_restart_pattern" msgid="3321211830602827742">"デバイスの再起動後はパターンの入力が必要になります"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="2672166323886110512">"デバイスの再起動後は PIN の入力が必要になります"</string>
     <string name="kg_prompt_reason_restart_password" msgid="3967993994418885887">"デバイスの再起動後はパスワードの入力が必要になります"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"セキュリティを強化するには代わりにパターンを使用してください"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"セキュリティを強化するには代わりに PIN を使用してください"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"セキュリティを強化するには代わりにパスワードを使用してください"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="5514969660010197363">"画面ロックを解除するにはパターンを入力してください"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="4227962059353859376">"画面ロックを解除するには PIN を入力してください"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="8810879144143933690">"画面ロックを解除するにはパスワードを入力してください"</string>
     <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"デバイスは管理者によりロックされています"</string>
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"デバイスは手動でロックされました"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"認識されませんでした"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml
index dbb5b35..5fadaab 100644
--- a/packages/SystemUI/res-keyguard/values-ko/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml
@@ -124,5 +124,5 @@
     <string name="clock_title_default" msgid="6342735240617459864">"기본"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"버블"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"아날로그"</string>
-    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"기기를 잠금 해제하여 계속"</string>
+    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"계속하려면 기기 잠금 해제"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml
index b063471..2c42f2b 100644
--- a/packages/SystemUI/res-keyguard/values-ms/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml
@@ -124,5 +124,5 @@
     <string name="clock_title_default" msgid="6342735240617459864">"Lalai"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Gelembung"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
-    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Buka kunci peranti anda untuk meneruskan"</string>
+    <string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Buka kunci peranti untuk meneruskan"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-or/strings.xml b/packages/SystemUI/res-keyguard/values-or/strings.xml
index 9760967..510ff7d 100644
--- a/packages/SystemUI/res-keyguard/values-or/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-or/strings.xml
@@ -49,7 +49,7 @@
     <string name="keyguard_accessibility_password" msgid="3524161948484801450">"ଡିଭାଇସ୍ ପାସ୍‍ୱର୍ଡ"</string>
     <string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"SIM PIN ଅଞ୍ଚଳ"</string>
     <string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"SIM PUK ଅଞ୍ଚଳ"</string>
-    <string name="keyboardview_keycode_delete" msgid="8489719929424895174">"ଡିଲିଟ୍‌ କରନ୍ତୁ"</string>
+    <string name="keyboardview_keycode_delete" msgid="8489719929424895174">"ଡିଲିଟ କରନ୍ତୁ"</string>
     <string name="disable_carrier_button_text" msgid="7153361131709275746">"eSIM ଅକ୍ଷମ କରନ୍ତୁ"</string>
     <string name="error_disable_esim_title" msgid="3802652622784813119">"eSIMକୁ ଅକ୍ଷମ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="error_disable_esim_msg" msgid="2441188596467999327">"ଗୋଟିଏ ତ୍ରୁଟି କାରଣରୁ eSIMକୁ ଅକ୍ଷମ କରାଯାଇପାରିବ ନାହିଁ।"</string>
diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_move_down.xml b/packages/SystemUI/res-keyguard/values-sw600dp-land/integers.xml
similarity index 61%
rename from libs/WindowManager/Shell/res/drawable/pip_ic_move_down.xml
rename to packages/SystemUI/res-keyguard/values-sw600dp-land/integers.xml
index d8f3561..2a80920 100644
--- a/libs/WindowManager/Shell/res/drawable/pip_ic_move_down.xml
+++ b/packages/SystemUI/res-keyguard/values-sw600dp-land/integers.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2021 The Android Open Source Project
+  ~ Copyright (C) 2023 The Android Open Source Project
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
@@ -14,12 +14,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24">
-    <path
-        android:fillColor="@color/tv_pip_menu_focus_border"
-        android:pathData="M7,10l5,5 5,-5H7z"/>
-</vector>
\ No newline at end of file
+<resources>
+     <!-- Invisibility to use for the date & weather view when it is disabled by a clock -->
+    <integer name="keyguard_date_weather_view_invisibility">8</integer>
+</resources>
diff --git a/packages/SystemUI/res-keyguard/values/config.xml b/packages/SystemUI/res-keyguard/values/config.xml
index a25ab51..d503551 100644
--- a/packages/SystemUI/res-keyguard/values/config.xml
+++ b/packages/SystemUI/res-keyguard/values/config.xml
@@ -28,6 +28,8 @@
     <!-- Will display the bouncer on one side of the display, and the current user icon and
          user switcher on the other side -->
     <bool name="config_enableBouncerUserSwitcher">false</bool>
+    <!-- Will enable custom clocks on the lockscreen -->
+    <bool name="config_enableLockScreenCustomClocks">true</bool>
     <!-- Time to be considered a consecutive fingerprint failure in ms -->
     <integer name="fp_consecutive_failure_time_ms">3500</integer>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index cad2c16..4b79689 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -96,6 +96,7 @@
 
     <!-- additional offset for clock switch area items -->
     <dimen name="small_clock_height">114dp</dimen>
+    <dimen name="small_clock_padding_top">28dp</dimen>
     <dimen name="clock_padding_start">28dp</dimen>
     <dimen name="below_clock_padding_start">32dp</dimen>
     <dimen name="below_clock_padding_end">16dp</dimen>
diff --git a/packages/SystemUI/res-keyguard/values/integers.xml b/packages/SystemUI/res-keyguard/values/integers.xml
index c6e90c0..b08fde3 100644
--- a/packages/SystemUI/res-keyguard/values/integers.xml
+++ b/packages/SystemUI/res-keyguard/values/integers.xml
@@ -27,4 +27,7 @@
 
          0x50 = bottom, 0x01 = center_horizontal -->
     <integer name="keyguard_host_view_one_handed_gravity">0x51</integer>
+
+     <!-- Invisibility to use for the date & weather view when it is disabled by a clock -->
+    <integer name="keyguard_date_weather_view_invisibility">4</integer>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 4d289eb..88f7bcd 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -23,6 +23,26 @@
     <style name="Keyguard.TextView" parent="@android:style/Widget.DeviceDefault.TextView">
         <item name="android:textSize">@dimen/kg_status_line_font_size</item>
         <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
+        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+    </style>
+    <style name="Keyguard.Bouncer.PrimaryMessage" parent="Theme.SystemUI">
+        <item name="android:textSize">18sp</item>
+        <item name="android:lineHeight">24dp</item>
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+        <item name="android:singleLine">true</item>
+        <item name="android:textAlignment">center</item>
+        <item name="android:ellipsize">marquee</item>
+    </style>
+    <style name="Keyguard.Bouncer.SecondaryMessage" parent="Theme.SystemUI">
+        <item name="android:textSize">14sp</item>
+        <item name="android:lineHeight">20dp</item>
+        <item name="android:maxLines">@integer/bouncer_secondary_message_lines</item>
+        <item name="android:lines">@integer/bouncer_secondary_message_lines</item>
+        <item name="android:textAlignment">center</item>
+        <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
+        <item name="android:ellipsize">end</item>
+        <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
     </style>
     <style name="Keyguard.TextView.EmergencyButton" parent="Theme.SystemUI">
         <item name="android:textColor">?androidprv:attr/materialColorOnTertiaryFixed</item>
diff --git a/packages/SystemUI/res/drawable/dream_overlay_bottom_affordance_bg.xml b/packages/SystemUI/res/drawable/dream_overlay_bottom_affordance_bg.xml
index 3b67ddd..bab604d 100644
--- a/packages/SystemUI/res/drawable/dream_overlay_bottom_affordance_bg.xml
+++ b/packages/SystemUI/res/drawable/dream_overlay_bottom_affordance_bg.xml
@@ -18,9 +18,7 @@
 -->
 <shape
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:shape="rectangle">
-  <solid android:color="?androidprv:attr/colorSurface"/>
   <size
       android:width="@dimen/dream_overlay_bottom_affordance_height"
       android:height="@dimen/dream_overlay_bottom_affordance_width"/>
diff --git a/packages/SystemUI/res/drawable/media_output_dialog_seekbar_background.xml b/packages/SystemUI/res/drawable/media_output_dialog_seekbar_background.xml
index 43cf003..adeb81f 100644
--- a/packages/SystemUI/res/drawable/media_output_dialog_seekbar_background.xml
+++ b/packages/SystemUI/res/drawable/media_output_dialog_seekbar_background.xml
@@ -18,8 +18,8 @@
     <item android:id="@android:id/background">
         <shape>
             <corners
-                     android:bottomRightRadius="28dp"
-                     android:topRightRadius="28dp"
+                     android:bottomRightRadius="@dimen/media_output_dialog_active_background_radius"
+                     android:topRightRadius="@dimen/media_output_dialog_active_background_radius"
             />
             <solid android:color="@android:color/transparent" />
             <size
diff --git a/packages/SystemUI/res/drawable/media_output_item_background_active.xml b/packages/SystemUI/res/drawable/media_output_item_background_active.xml
index 839db4a..826e0ca 100644
--- a/packages/SystemUI/res/drawable/media_output_item_background_active.xml
+++ b/packages/SystemUI/res/drawable/media_output_item_background_active.xml
@@ -17,6 +17,6 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
     <corners
-        android:radius="28dp"/>
+        android:radius="@dimen/media_output_dialog_active_background_radius"/>
     <solid android:color="@color/media_dialog_item_background" />
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/auth_biometric_contents.xml b/packages/SystemUI/res/layout/auth_biometric_contents.xml
index b3b40f3..8169189 100644
--- a/packages/SystemUI/res/layout/auth_biometric_contents.xml
+++ b/packages/SystemUI/res/layout/auth_biometric_contents.xml
@@ -13,7 +13,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-
+<!-- TODO(b/251476085): inline in biometric_prompt_layout after Biometric*Views are un-flagged -->
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 
     <TextView
diff --git a/packages/SystemUI/res/layout/auth_biometric_face_view.xml b/packages/SystemUI/res/layout/auth_biometric_face_view.xml
index be30f21..e3d0732 100644
--- a/packages/SystemUI/res/layout/auth_biometric_face_view.xml
+++ b/packages/SystemUI/res/layout/auth_biometric_face_view.xml
@@ -13,7 +13,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-
+<!-- TODO(b/251476085): remove after BiometricFaceView is un-flagged -->
 <com.android.systemui.biometrics.AuthBiometricFaceView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/contents"
diff --git a/packages/SystemUI/res/layout/auth_biometric_fingerprint_and_face_view.xml b/packages/SystemUI/res/layout/auth_biometric_fingerprint_and_face_view.xml
index 05ca2a7..896d836 100644
--- a/packages/SystemUI/res/layout/auth_biometric_fingerprint_and_face_view.xml
+++ b/packages/SystemUI/res/layout/auth_biometric_fingerprint_and_face_view.xml
@@ -13,7 +13,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-
+<!-- TODO(b/251476085): remove after BiometricFingerprintAndFaceView is un-flagged -->
 <com.android.systemui.biometrics.AuthBiometricFingerprintAndFaceView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/contents"
diff --git a/packages/SystemUI/res/layout/auth_biometric_fingerprint_view.xml b/packages/SystemUI/res/layout/auth_biometric_fingerprint_view.xml
index 01ea31f..e36f9796 100644
--- a/packages/SystemUI/res/layout/auth_biometric_fingerprint_view.xml
+++ b/packages/SystemUI/res/layout/auth_biometric_fingerprint_view.xml
@@ -13,7 +13,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-
+<!-- TODO(b/251476085): remove after BiometricFingerprintView is un-flagged -->
 <com.android.systemui.biometrics.AuthBiometricFingerprintView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/contents"
diff --git a/packages/SystemUI/res/layout/biometric_prompt_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_layout.xml
new file mode 100644
index 0000000..05ff1b1
--- /dev/null
+++ b/packages/SystemUI/res/layout/biometric_prompt_layout.xml
@@ -0,0 +1,176 @@
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<com.android.systemui.biometrics.ui.BiometricPromptLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/contents"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/title"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="@integer/biometric_dialog_text_gravity"
+        android:singleLine="true"
+        android:marqueeRepeatLimit="1"
+        android:ellipsize="marquee"
+        android:importantForAccessibility="no"
+        style="@style/TextAppearance.AuthCredential.Title"/>
+
+    <TextView
+        android:id="@+id/subtitle"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="@integer/biometric_dialog_text_gravity"
+        android:singleLine="true"
+        android:marqueeRepeatLimit="1"
+        android:ellipsize="marquee"
+        style="@style/TextAppearance.AuthCredential.Subtitle"/>
+
+    <TextView
+        android:id="@+id/description"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:scrollbars ="vertical"
+        android:importantForAccessibility="no"
+        style="@style/TextAppearance.AuthCredential.Description"/>
+
+    <Space android:id="@+id/space_above_icon"
+        android:layout_width="match_parent"
+        android:layout_height="48dp" />
+
+    <FrameLayout
+        android:id="@+id/biometric_icon_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center">
+
+        <com.airbnb.lottie.LottieAnimationView
+            android:id="@+id/biometric_icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:contentDescription="@null"
+            android:scaleType="fitXY" />
+
+        <com.airbnb.lottie.LottieAnimationView
+            android:id="@+id/biometric_icon_overlay"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:contentDescription="@null"
+            android:scaleType="fitXY" />
+    </FrameLayout>
+
+    <!-- For sensors such as UDFPS, this view is used during custom measurement/layout to add extra
+         padding so that the biometric icon is always in the right physical position. -->
+    <Space android:id="@+id/space_below_icon"
+        android:layout_width="match_parent"
+        android:layout_height="12dp" />
+
+    <TextView
+        android:id="@+id/indicator"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingHorizontal="24dp"
+        android:textSize="12sp"
+        android:gravity="center_horizontal"
+        android:accessibilityLiveRegion="polite"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:marqueeRepeatLimit="marquee_forever"
+        android:scrollHorizontally="true"
+        android:fadingEdge="horizontal"
+        android:textColor="@color/biometric_dialog_gray"/>
+
+    <LinearLayout
+        android:id="@+id/button_bar"
+        android:layout_width="match_parent"
+        android:layout_height="88dp"
+        style="?android:attr/buttonBarStyle"
+        android:orientation="horizontal"
+        android:paddingTop="24dp">
+
+        <Space android:id="@+id/leftSpacer"
+            android:layout_width="8dp"
+            android:layout_height="match_parent"
+            android:visibility="visible" />
+
+        <!-- Negative Button, reserved for app -->
+        <Button android:id="@+id/button_negative"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+            android:layout_gravity="center_vertical"
+            android:ellipsize="end"
+            android:maxLines="2"
+            android:maxWidth="@dimen/biometric_dialog_button_negative_max_width"
+            android:visibility="gone"/>
+        <!-- Cancel Button, replaces negative button when biometric is accepted -->
+        <Button android:id="@+id/button_cancel"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+            android:layout_gravity="center_vertical"
+            android:maxWidth="@dimen/biometric_dialog_button_negative_max_width"
+            android:text="@string/cancel"
+            android:visibility="gone"/>
+        <!-- "Use Credential" Button, replaces if device credential is allowed -->
+        <Button android:id="@+id/button_use_credential"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+            android:layout_gravity="center_vertical"
+            android:maxWidth="@dimen/biometric_dialog_button_negative_max_width"
+            android:visibility="gone"/>
+
+        <Space android:id="@+id/middleSpacer"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:visibility="visible"/>
+
+        <!-- Positive Button -->
+        <Button android:id="@+id/button_confirm"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            style="@*android:style/Widget.DeviceDefault.Button.Colored"
+            android:layout_gravity="center_vertical"
+            android:ellipsize="end"
+            android:maxLines="2"
+            android:maxWidth="@dimen/biometric_dialog_button_positive_max_width"
+            android:text="@string/biometric_dialog_confirm"
+            android:visibility="gone"/>
+        <!-- Try Again Button -->
+        <Button android:id="@+id/button_try_again"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            style="@*android:style/Widget.DeviceDefault.Button.Colored"
+            android:layout_gravity="center_vertical"
+            android:ellipsize="end"
+            android:maxLines="2"
+            android:maxWidth="@dimen/biometric_dialog_button_positive_max_width"
+            android:text="@string/biometric_dialog_try_again"
+            android:visibility="gone"/>
+
+        <Space android:id="@+id/rightSpacer"
+            android:layout_width="8dp"
+            android:layout_height="match_parent"
+            android:visibility="visible" />
+    </LinearLayout>
+
+</com.android.systemui.biometrics.ui.BiometricPromptLayout>
diff --git a/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml b/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml
index 0cd0623..e8a48c7 100644
--- a/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml
@@ -21,8 +21,6 @@
     android:layout_width="@dimen/dream_overlay_bottom_affordance_width"
     android:layout_gravity="bottom|start"
     android:padding="@dimen/dream_overlay_bottom_affordance_padding"
-    android:background="@drawable/dream_overlay_bottom_affordance_bg"
     android:scaleType="fitCenter"
     android:tint="?android:attr/textColorPrimary"
-    android:src="@drawable/controls_icon"
     android:contentDescription="@string/quick_controls_title" />
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index e9acf3f..a3a7135 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -59,55 +59,44 @@
 
     </LinearLayout>
 
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:layout_gravity="bottom"
-        android:layout_marginHorizontal="@dimen/keyguard_affordance_horizontal_offset"
+    <com.android.systemui.animation.view.LaunchableImageView
+        android:id="@+id/start_button"
+        android:layout_height="@dimen/keyguard_affordance_fixed_height"
+        android:layout_width="@dimen/keyguard_affordance_fixed_width"
+        android:layout_gravity="start|bottom"
+        android:layout_marginStart="@dimen/keyguard_affordance_horizontal_offset"
         android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
-        android:gravity="bottom"
-        >
+        android:scaleType="fitCenter"
+        android:padding="@dimen/keyguard_affordance_fixed_padding"
+        android:tint="?android:attr/textColorPrimary"
+        android:background="@drawable/keyguard_bottom_affordance_bg"
+        android:foreground="@drawable/keyguard_bottom_affordance_selected_border"
+        android:visibility="invisible" />
 
-        <com.android.systemui.animation.view.LaunchableImageView
-            android:id="@+id/start_button"
-            android:layout_height="@dimen/keyguard_affordance_fixed_height"
-            android:layout_width="@dimen/keyguard_affordance_fixed_width"
-            android:scaleType="fitCenter"
-            android:padding="@dimen/keyguard_affordance_fixed_padding"
-            android:tint="?android:attr/textColorPrimary"
-            android:background="@drawable/keyguard_bottom_affordance_bg"
-            android:foreground="@drawable/keyguard_bottom_affordance_selected_border"
-            android:visibility="invisible" />
+    <com.android.systemui.animation.view.LaunchableImageView
+        android:id="@+id/end_button"
+        android:layout_height="@dimen/keyguard_affordance_fixed_height"
+        android:layout_width="@dimen/keyguard_affordance_fixed_width"
+        android:layout_gravity="end|bottom"
+        android:layout_marginEnd="@dimen/keyguard_affordance_horizontal_offset"
+        android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
+        android:scaleType="fitCenter"
+        android:padding="@dimen/keyguard_affordance_fixed_padding"
+        android:tint="?android:attr/textColorPrimary"
+        android:background="@drawable/keyguard_bottom_affordance_bg"
+        android:foreground="@drawable/keyguard_bottom_affordance_selected_border"
+        android:visibility="invisible" />
 
-        <FrameLayout
-            android:layout_width="0dp"
-            android:layout_weight="1"
-            android:layout_height="wrap_content"
-            android:paddingHorizontal="24dp"
-            >
-            <include
-                android:id="@+id/keyguard_settings_button"
-                layout="@layout/keyguard_settings_popup_menu"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center"
-                android:visibility="gone"
-                />
-        </FrameLayout>
-
-        <com.android.systemui.animation.view.LaunchableImageView
-            android:id="@+id/end_button"
-            android:layout_height="@dimen/keyguard_affordance_fixed_height"
-            android:layout_width="@dimen/keyguard_affordance_fixed_width"
-            android:scaleType="fitCenter"
-            android:padding="@dimen/keyguard_affordance_fixed_padding"
-            android:tint="?android:attr/textColorPrimary"
-            android:background="@drawable/keyguard_bottom_affordance_bg"
-            android:foreground="@drawable/keyguard_bottom_affordance_selected_border"
-            android:visibility="invisible" />
-
-    </LinearLayout>
+    <include
+        android:id="@+id/keyguard_settings_button"
+        layout="@layout/keyguard_settings_popup_menu"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom|center"
+        android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
+        android:layout_marginHorizontal="@dimen/keyguard_affordance_horizontal_offset"
+        android:visibility="gone"
+        />
 
     <FrameLayout
         android:id="@+id/overlay_container"
diff --git a/packages/SystemUI/res/layout/keyguard_status_bar.xml b/packages/SystemUI/res/layout/keyguard_status_bar.xml
index 8b85940..64c4eff 100644
--- a/packages/SystemUI/res/layout/keyguard_status_bar.xml
+++ b/packages/SystemUI/res/layout/keyguard_status_bar.xml
@@ -78,6 +78,7 @@
         android:textColor="?attr/wallpaperTextColorSecondary"
         android:singleLine="true"
         systemui:showMissingSim="true"
-        systemui:showAirplaneMode="true" />
+        systemui:showAirplaneMode="true"
+        systemui:debugLocation="Keyguard" />
 
 </com.android.systemui.statusbar.phone.KeyguardStatusBarView>
diff --git a/packages/SystemUI/res/layout/media_output_dialog.xml b/packages/SystemUI/res/layout/media_output_dialog.xml
index e182a6a..9c1dc64 100644
--- a/packages/SystemUI/res/layout/media_output_dialog.xml
+++ b/packages/SystemUI/res/layout/media_output_dialog.xml
@@ -31,7 +31,7 @@
         android:paddingStart="16dp"
         android:paddingTop="16dp"
         android:paddingEnd="16dp"
-        android:paddingBottom="24dp"
+        android:paddingBottom="16dp"
         android:orientation="horizontal">
         <ImageView
             android:id="@+id/header_icon"
@@ -113,6 +113,8 @@
         <androidx.recyclerview.widget.RecyclerView
             android:id="@+id/list_result"
             android:scrollbars="vertical"
+            android:paddingTop="8dp"
+            android:clipToPadding="false"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"/>
     </LinearLayout>
diff --git a/packages/SystemUI/res/layout/media_output_list_item_advanced.xml b/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
index a650512..054193a 100644
--- a/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
+++ b/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
@@ -50,12 +50,16 @@
             android:id="@+id/icon_area"
             android:layout_width="64dp"
             android:layout_height="64dp"
+            android:focusable="false"
+            android:importantForAccessibility="no"
             android:background="@drawable/media_output_title_icon_area"
             android:layout_gravity="center_vertical|start">
             <ImageView
                 android:id="@+id/title_icon"
                 android:layout_width="24dp"
                 android:layout_height="24dp"
+                android:focusable="false"
+                android:importantForAccessibility="no"
                 android:animateLayoutChanges="true"
                 android:layout_gravity="center"/>
             <TextView
diff --git a/packages/SystemUI/res/layout/screen_record_dialog.xml b/packages/SystemUI/res/layout/screen_record_dialog.xml
index ae052502..bbf3adf 100644
--- a/packages/SystemUI/res/layout/screen_record_dialog.xml
+++ b/packages/SystemUI/res/layout/screen_record_dialog.xml
@@ -73,7 +73,7 @@
                         android:tint="?android:attr/textColorSecondary"
                         android:layout_gravity="center"
                         android:layout_weight="0"
-                        android:layout_marginRight="@dimen/screenrecord_option_padding"/>
+                        android:layout_marginEnd="@dimen/screenrecord_option_padding"/>
                     <Spinner
                         android:id="@+id/screen_recording_options"
                         android:layout_width="0dp"
@@ -106,7 +106,7 @@
                         android:src="@drawable/ic_touch"
                         android:tint="?android:attr/textColorSecondary"
                         android:layout_gravity="center"
-                        android:layout_marginRight="@dimen/screenrecord_option_padding"/>
+                        android:layout_marginEnd="@dimen/screenrecord_option_padding"/>
                     <TextView
                         android:layout_width="0dp"
                         android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/layout/screen_share_dialog.xml b/packages/SystemUI/res/layout/screen_share_dialog.xml
index 0d86e0a..ab522a3 100644
--- a/packages/SystemUI/res/layout/screen_share_dialog.xml
+++ b/packages/SystemUI/res/layout/screen_share_dialog.xml
@@ -36,7 +36,7 @@
             android:layout_width="@dimen/screenrecord_logo_size"
             android:layout_height="@dimen/screenrecord_logo_size"
             android:src="@drawable/ic_media_projection_permission"
-            android:tint="?androidprv:attr/colorAccentPrimary"
+            android:tint="?androidprv:attr/colorAccentPrimaryVariant"
             android:importantForAccessibility="no"/>
         <TextView
             android:id="@+id/screen_share_dialog_title"
diff --git a/packages/SystemUI/res/layout/volume_ringer_drawer.xml b/packages/SystemUI/res/layout/volume_ringer_drawer.xml
index 1112bcd..9b1fa23 100644
--- a/packages/SystemUI/res/layout/volume_ringer_drawer.xml
+++ b/packages/SystemUI/res/layout/volume_ringer_drawer.xml
@@ -85,7 +85,7 @@
                     android:layout_height="@dimen/volume_ringer_drawer_icon_size"
                     android:layout_gravity="center"
                     android:tint="?android:attr/textColorPrimary"
-                    android:src="@drawable/ic_volume_ringer_mute" />
+                    android:src="@drawable/ic_speaker_mute" />
 
             </FrameLayout>
 
@@ -102,7 +102,7 @@
                     android:layout_height="@dimen/volume_ringer_drawer_icon_size"
                     android:layout_gravity="center"
                     android:tint="?android:attr/textColorPrimary"
-                    android:src="@drawable/ic_volume_ringer" />
+                    android:src="@drawable/ic_speaker_on" />
 
             </FrameLayout>
 
diff --git a/packages/SystemUI/res/layout/window_magnification_settings_view.xml b/packages/SystemUI/res/layout/window_magnification_settings_view.xml
index db8191b..a8febe7 100644
--- a/packages/SystemUI/res/layout/window_magnification_settings_view.xml
+++ b/packages/SystemUI/res/layout/window_magnification_settings_view.xml
@@ -112,9 +112,13 @@
         android:focusable="true">
 
         <TextView
+            android:id="@+id/magnifier_horizontal_lock_title"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_weight="1"
+            android:singleLine="true"
+            android:scrollHorizontally="true"
+            android:ellipsize="marquee"
             android:text="@string/accessibility_allow_diagonal_scrolling"
             android:textAppearance="@style/TextAppearance.MagnificationSetting.Title"
             android:layout_gravity="center_vertical" />
diff --git a/packages/SystemUI/res/raw/sfps_pulse.json b/packages/SystemUI/res/raw/sfps_pulse.json
index c4903a2..2a72dfb 100644
--- a/packages/SystemUI/res/raw/sfps_pulse.json
+++ b/packages/SystemUI/res/raw/sfps_pulse.json
@@ -1 +1 @@
-{"v":"5.7.6","fr":60,"ip":0,"op":300,"w":42,"h":80,"nm":"Fingerprint Pulse Motion","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".black","cl":"black","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":0,"s":[28,40,0],"to":[0.751,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":30,"s":[32.503,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":60,"s":[28,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":90,"s":[32.503,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":120,"s":[28,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":150,"s":[32.503,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":180,"s":[28,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":210,"s":[32.503,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":240,"s":[28,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":270,"s":[32.503,40,0],"to":[0,0,0],"ti":[0.751,0,0]},{"t":300,"s":[28,40,0]}],"ix":2,"l":2},"a":{"a":0,"k":[28.253,40,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1.566,0],[-3.929,-5.503],[-2.751,-6.68],[3.929,0],[-2.751,6.68],[-3.929,5.503]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[30.218,40],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue600","cl":"blue600","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[41.878,40,0],"ix":2,"l":2},"a":{"a":0,"k":[28.253,40,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[55,55],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 2","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[28.253,40],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[20]},{"t":30,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":-30,"s":[55,55]},{"t":30,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-30,"op":30,"st":-30,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":40,"s":[20]},{"t":60,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[55,55]},{"t":60,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":70,"s":[20]},{"t":90,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":30,"s":[55,55]},{"t":90,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":90,"st":30,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":100,"s":[20]},{"t":120,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":60,"s":[55,55]},{"t":120,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":60,"op":120,"st":60,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":130,"s":[20]},{"t":150,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":90,"s":[55,55]},{"t":150,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":90,"op":150,"st":90,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":160,"s":[20]},{"t":180,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":120,"s":[55,55]},{"t":180,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":120,"op":180,"st":120,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":190,"s":[20]},{"t":210,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":150,"s":[55,55]},{"t":210,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":150,"op":210,"st":150,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":220,"s":[20]},{"t":240,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":180,"s":[55,55]},{"t":240,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":180,"op":240,"st":180,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":250,"s":[20]},{"t":270,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":210,"s":[55,55]},{"t":270,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":210,"op":270,"st":210,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":280,"s":[20]},{"t":300,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":240,"s":[55,55]},{"t":300,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":240,"op":300,"st":240,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":310,"s":[20]},{"t":330,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":270,"s":[55,55]},{"t":330,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":270,"op":330,"st":270,"bm":0}],"markers":[]}
\ No newline at end of file
+{"v":"5.7.14","fr":60,"ip":0,"op":300,"w":42,"h":80,"nm":"sfps_pulse_motion_04","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".black","cl":"black","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.617,"y":0.539},"o":{"x":0.477,"y":0},"t":0,"s":[28,40,0],"to":[0.365,0,0],"ti":[-1.009,0,0]},{"i":{"x":0.436,"y":1},"o":{"x":0.17,"y":0.547},"t":10,"s":[30.576,40,0],"to":[1.064,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":30,"s":[32.503,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":60,"s":[28,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":90,"s":[32.503,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":120,"s":[28,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":150,"s":[32.503,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":180,"s":[28,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":210,"s":[32.503,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":240,"s":[28,40,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":270,"s":[32.503,40,0],"to":[0,0,0],"ti":[0.751,0,0]},{"t":300,"s":[28,40,0]}],"ix":2,"l":2},"a":{"a":0,"k":[28.253,40,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1.566,0],[-3.929,-5.503],[-2.751,-6.68],[3.929,0],[-2.751,6.68],[-3.929,5.503]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[30.218,40],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue600","cl":"blue600","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[41.878,40,0],"ix":2,"l":2},"a":{"a":0,"k":[28.253,40,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[55,55],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 2","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[28.253,40],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[75]},{"t":30,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":-30,"s":[55,55]},{"t":30,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-30,"op":30,"st":-30,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":40,"s":[75]},{"t":60,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[55,55]},{"t":60,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":70,"s":[75]},{"t":90,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":30,"s":[55,55]},{"t":90,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":90,"st":30,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":100,"s":[75]},{"t":120,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":60,"s":[55,55]},{"t":120,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":60,"op":120,"st":60,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":130,"s":[75]},{"t":150,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":90,"s":[55,55]},{"t":150,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":90,"op":150,"st":90,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":160,"s":[75]},{"t":180,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":120,"s":[55,55]},{"t":180,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":120,"op":180,"st":120,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":190,"s":[75]},{"t":210,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":150,"s":[55,55]},{"t":210,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":150,"op":210,"st":150,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":220,"s":[75]},{"t":240,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":180,"s":[55,55]},{"t":240,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":180,"op":240,"st":180,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":250,"s":[75]},{"t":270,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":210,"s":[55,55]},{"t":270,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":210,"op":270,"st":210,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":280,"s":[75]},{"t":300,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":240,"s":[55,55]},{"t":300,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":240,"op":300,"st":240,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":310,"s":[75]},{"t":330,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[25.587,40,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":270,"s":[55,55]},{"t":330,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":270,"op":330,"st":270,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/sfps_pulse_landscape.json b/packages/SystemUI/res/raw/sfps_pulse_landscape.json
index 8c91762..42b92eb 100644
--- a/packages/SystemUI/res/raw/sfps_pulse_landscape.json
+++ b/packages/SystemUI/res/raw/sfps_pulse_landscape.json
@@ -1 +1 @@
-{"v":"5.7.6","fr":60,"ip":0,"op":300,"w":80,"h":42,"nm":"Fingerprint Pulse Motion Portrait","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".black","cl":"black","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":0,"s":[40,14,0],"to":[0,-0.751,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":30,"s":[40,9.497,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":60,"s":[40,14,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":90,"s":[40,9.497,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":120,"s":[40,14,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":150,"s":[40,9.497,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":180,"s":[40,14,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":210,"s":[40,9.497,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":240,"s":[40,14,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":270,"s":[40,9.497,0],"to":[0,0,0],"ti":[0,-0.751,0]},{"t":300,"s":[40,14,0]}],"ix":2,"l":2},"a":{"a":0,"k":[28.253,40,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1.566,0],[-3.929,-5.503],[-2.751,-6.68],[3.929,0],[-2.751,6.68],[-3.929,5.503]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[30.218,40],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue600","cl":"blue600","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,0.122,0],"ix":2,"l":2},"a":{"a":0,"k":[28.253,40,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[55,55],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 2","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[28.253,40],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[20]},{"t":30,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":-30,"s":[55,55]},{"t":30,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-30,"op":30,"st":-30,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":40,"s":[20]},{"t":60,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[55,55]},{"t":60,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":70,"s":[20]},{"t":90,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":30,"s":[55,55]},{"t":90,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":90,"st":30,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":100,"s":[20]},{"t":120,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":60,"s":[55,55]},{"t":120,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":60,"op":120,"st":60,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":130,"s":[20]},{"t":150,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":90,"s":[55,55]},{"t":150,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":90,"op":150,"st":90,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":160,"s":[20]},{"t":180,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":120,"s":[55,55]},{"t":180,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":120,"op":180,"st":120,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":190,"s":[20]},{"t":210,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":150,"s":[55,55]},{"t":210,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":150,"op":210,"st":150,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":220,"s":[20]},{"t":240,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":180,"s":[55,55]},{"t":240,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":180,"op":240,"st":180,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":250,"s":[20]},{"t":270,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":210,"s":[55,55]},{"t":270,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":210,"op":270,"st":210,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":280,"s":[20]},{"t":300,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":240,"s":[55,55]},{"t":300,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":240,"op":300,"st":240,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":310,"s":[20]},{"t":330,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":270,"s":[55,55]},{"t":330,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":270,"op":330,"st":270,"bm":0}],"markers":[]}
\ No newline at end of file
+{"v":"5.7.13","fr":60,"ip":0,"op":300,"w":80,"h":42,"nm":"sfps_pulse_motion_portrait","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".black","cl":"black","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":0,"s":[40,14,0],"to":[0,-0.751,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":30,"s":[40,9.497,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":60,"s":[40,14,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":90,"s":[40,9.497,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":120,"s":[40,14,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":150,"s":[40,9.497,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":180,"s":[40,14,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":210,"s":[40,9.497,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":1},"o":{"x":0.3,"y":0},"t":240,"s":[40,14,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.7,"y":1},"o":{"x":0.3,"y":0},"t":270,"s":[40,9.497,0],"to":[0,0,0],"ti":[0,-0.751,0]},{"t":300,"s":[40,14,0]}],"ix":2,"l":2},"a":{"a":0,"k":[28.253,40,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[1.566,0],[-3.929,-5.503],[-2.751,-6.68],[3.929,0],[-2.751,6.68],[-3.929,5.503]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[30.218,40],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue600","cl":"blue600","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,0.122,0],"ix":2,"l":2},"a":{"a":0,"k":[28.253,40,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[55,55],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 2","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.101960785687,0.450980395079,0.909803926945,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[28.253,40],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[75]},{"t":30,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":-30,"s":[55,55]},{"t":30,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-30,"op":30,"st":-30,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":40,"s":[75]},{"t":60,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":0,"s":[55,55]},{"t":60,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":70,"s":[75]},{"t":90,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":30,"s":[55,55]},{"t":90,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":90,"st":30,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":100,"s":[75]},{"t":120,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":60,"s":[55,55]},{"t":120,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":60,"op":120,"st":60,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":130,"s":[75]},{"t":150,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":90,"s":[55,55]},{"t":150,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":90,"op":150,"st":90,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":160,"s":[75]},{"t":180,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":120,"s":[55,55]},{"t":180,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":120,"op":180,"st":120,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":190,"s":[75]},{"t":210,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":150,"s":[55,55]},{"t":210,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":150,"op":210,"st":150,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":220,"s":[75]},{"t":240,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":180,"s":[55,55]},{"t":240,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":180,"op":240,"st":180,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":250,"s":[75]},{"t":270,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":210,"s":[55,55]},{"t":270,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":210,"op":270,"st":210,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":280,"s":[75]},{"t":300,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":240,"s":[55,55]},{"t":300,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":240,"op":300,"st":240,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".blue400","cl":"blue400","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":310,"s":[75]},{"t":330,"s":[0]}],"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[40,16.413,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.25,0.25],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":270,"s":[55,55]},{"t":330,"s":[80,80]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[16.338,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":270,"op":330,"st":270,"bm":0}],"markers":[]}
\ 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 93b6cda..f7f45e2 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Deel"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Skermopname is gestoor"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Tik om te bekyk"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Kon nie skermopname uitvee nie"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Kon nie skermopname stoor nie"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Kon nie skermopname begin nie"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Terug"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Tuis"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Gesig is gestaaf"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bevestig"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tik op Bevestig om te voltooi"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ontsluit met gesig. Druk die ontsluitikoon om voort te gaan."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ontsluit met gesig. Druk om voort te gaan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gesig is herken. Druk om voort te gaan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gesig is herken. Druk die ontsluitikoon om voort te gaan."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktiveer"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Klank en vibrasie"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Instellings"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Verlaag na veiliger volume"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Die volume was langer as wat aanbeveel word hoog"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume is verlaag na ’n veiliger vlak"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Oorfoonvolume was langer as wat aanbeveel word hoog"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Oorfoonvolume het die veilige limiet vir hierdie week oorskry"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Hou aan luister"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Stel volume sagter"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Program is vasgespeld"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Dit hou dit in sig totdat jy dit ontspeld. Raak en hou Terug en Oorsig om dit te ontspeld."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Dit hou dit in sig totdat jy dit ontspeld. Raak en hou Terug en Tuis om dit te ontspeld."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Instellings"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> deur <xliff:g id="ARTIST_NAME">%2$s</xliff:g> speel tans vanaf <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> van <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> loop tans"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Speel"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Onderbreek"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Vorige snit"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Koppel jou stilus aan ’n laaier"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Stilus se battery is amper pap"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Kan nie van hierdie profiel af bel nie"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Jou werkbeleid laat jou toe om slegs van die werkprofiel af foonoproepe te maak"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Kan nie van ’n persoonlike app af bel nie"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Jou organisasie laat jou net toe om oproepe van werkapps af te maak"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skakel oor na werkprofiel"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Maak toe"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installeer ’n werkfoonapp"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Kanselleer"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Pasmaak sluitskerm"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Ontsluit om sluitskerm te pasmaak"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-fi is nie beskikbaar nie"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 34548b0..17f7d5a 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"አጋራ"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"የማያ ገፅ ቀረጻ ተቀምጧል"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"ለመመልከት መታ ያድርጉ"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"የማያ ገፅ ቀረጻን መሰረዝ ላይ ስህተት"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"የማያ ገጽ ቀረጻን ማስቀመጥ ላይ ስህተት"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"የማያ ገፅ ቀረጻን መጀመር ላይ ስህተት"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"ተመለስ"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"መነሻ"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"መልክ ተረጋግጧል"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ተረጋግጧል"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ለማጠናቀቅ አረጋግጥን መታ ያድርጉ"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"በመልክ ተከፍቷል። ለመቀጠል የመክፈቻ አዶውን ይጫኑ።"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"በመልክ ተከፍቷል። ለመቀጠል ይጫኑ።"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"መልክ ተለይቶ ታውቋል። ለመቀጠል ይጫኑ።"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"መልክ ተለይቶ ታውቋል። ለመቀጠል የመክፈቻ አዶውን ይጫኑ።"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"አሰናክል"</string>
     <string name="sound_settings" msgid="8874581353127418308">"ድምፅ እና ንዝረት"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ቅንብሮች"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"ደህንነቱ ወደ የተጠበቀ ድምፅ ተቀንሷል"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"ድምፁ ከሚመከረው በላይ ረዘም ላለ ጊዜ ከፍተኛ ነበር"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"የድምፅ መጠን ይበልጥ ደህንነቱ ወደተጠበቀ ደረጃ ዝቅ ተደርጓል"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"የራስ ላይ ማዳመጫ የድምፅ መጠን ከሚመከረው በላይ ረዘም ላለ ጊዜ ከፍተኛ ነበር"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"የራስ ላይ ማዳመጫ የድምፅ መጠን ለዚህ ሳምንት ደህንነቱ ከተጠበቀው ገደብ አልፏል"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"ማዳመጡን ይቀጥሉ"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"ዝቅተኛ የድምፅ መጠን"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"መተግበሪያ ተሰክቷል"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"ይሄ እስኪነቅሉት ድረስ በእይታ ውስጥ ያስቀምጠዋል። ለመንቀል ተመለስ እና አጠቃላይ ዕይታ የሚለውን ይጫኑ እና ይያዙ።"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"ይሄ እስኪነቅሉት ድረስ በእይታ ውስጥ ያስቀምጠዋል። ለመንቀል ተመለስ እና መነሻ የሚለውን ይንኩ እና ይያዙ።"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ቅንብሮች"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> በ<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ከ<xliff:g id="APP_LABEL">%3$s</xliff:g> እየተጫወተ ነው"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> ከ<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> እያሄደ ነው"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"አጫውት"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"ላፍታ አቁም"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"ቀዳሚ ትራክ"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ድምጽ ማውጫዎች እና ማሳያዎች"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"የተጠቆሙ መሣሪያዎች"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"ሚዲያን ወደ ሌላ መሣሪያ ለማንቀሳቀስ የተጋራውን ክፍለ ጊዜዎን ያቁሙ"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"አቁም"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ማሰራጨት እንዴት እንደሚሠራ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ስርጭት"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ተኳሃኝ የብሉቱዝ መሣሪያዎች ያላቸው በአቅራቢያዎ ያሉ ሰዎች እርስዎ እያሰራጩት ያሉትን ሚዲያ ማዳመጥ ይችላሉ"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ብሮስፌዎን ከኃይል መሙያ ጋር ያገናኙ"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"የብሮስፌ ባትሪ ዝቅተኛ ነው"</string>
     <string name="video_camera" msgid="7654002575156149298">"የቪድዮ ካሜራ"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"ከዚህ መገለጫ መደወል አይቻልም"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"የሥራ መመሪያዎ እርስዎ ከሥራ መገለጫው ብቻ ጥሪ እንዲያደርጉ ይፈቅድልዎታል"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"ከግል መተግበሪያ መደወል አይቻልም"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"ድርጅትዎ ከሥራ መተግበሪያዎች ብቻ ጥሪዎችን እንዲያደርጉ ይፈቅድልዎታል"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ወደ የሥራ መገለጫ ቀይር"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"ዝጋ"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"የስልክ መተግበሪያ ጫን"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"ይቅር"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ማያ ገፅ ቁልፍን አብጅ"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"የማያ ገጽ ቁልፍን ለማበጀት ይክፈቱ"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi አይገኝም"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 03a1ed3..71266fb 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"مشاركة"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"تم حفظ تسجيل الشاشة"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"انقر لعرض التسجيل."</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"حدث خطأ أثناء حذف تسجيل الشاشة."</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"حدث خطأ أثناء حفظ تسجيل محتوى الشاشة."</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"حدث خطأ في بدء تسجيل الشاشة"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"رجوع"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"الرئيسية"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"تمّت مصادقة الوجه."</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تمّ التأكيد."</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"يمكنك النقر على \"تأكيد\" لإكمال المهمة."</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"تم فتح القفل بالتعرّف على وجهك. للمتابعة، اضغط على رمز فتح القفل."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"تم فتح قفل جهازك عند تقريبه من وجهك. اضغط للمتابعة."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"تم التعرّف على الوجه. اضغط للمتابعة."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"تم التعرّف على الوجه. للمتابعة، اضغط على رمز فتح القفل."</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"تم تثبيت مرجع مصدّق على هذا الجهاز. قد تتم مراقبة حركة بيانات شبكتك الآمنة أو تعديلها."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"شغَّل المشرف ميزة تسجيل بيانات الشبكة، والتي يتم من خلالها مراقبة حركة البيانات على جهازك."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"شغَّل المشرف ميزة تسجيل بيانات الشبكة، والتي يتم من خلالها مراقبة حركة البيانات في ملفك الشخصي للعمل ولكن لا تتم مراقبتها في ملفك الشخصي."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"‏هذا الجهاز متّصل بالإنترنت من خلال \"<xliff:g id="VPN_APP">%1$s</xliff:g>\". تجدر الإشارة إلى أنّ أنشطة الشبكة، بما في ذلك الرسائل الإلكترونية وبيانات التصفُّح، مرئية لمقدِّم خدمات VPN."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"‏هذا الجهاز متّصل بالإنترنت من خلال \"<xliff:g id="VPN_APP">%1$s</xliff:g>\". ويمكن لمقدِّم شبكة VPN الاطّلاع على أنشطة الشبكة، بما في ذلك الرسائل الإلكترونية وبيانات التصفّح."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"هذا الجهاز متّصل بالإنترنت من خلال \"<xliff:g id="VPN_APP">%1$s</xliff:g>\". تجدر الإشارة إلى أنّ أنشطة الشبكة، بما في ذلك الرسائل الإلكترونية وبيانات التصفُّح، مرئية لمشرف تكنولوجيا المعلومات في مؤسستك."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"هذا الجهاز متّصل بالإنترنت من خلال <xliff:g id="VPN_APP_0">%1$s</xliff:g> و<xliff:g id="VPN_APP_1">%2$s</xliff:g>. يمكن لمشرف تكنولوجيا المعلومات رؤية أنشطة الشبكة، بما في ذلك الرسائل الإلكترونية وبيانات التصفُّح."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"‏تطبيقات العمل الخاصة بك متّصلة بالإنترنت من خلال <xliff:g id="VPN_APP">%1$s</xliff:g>. يمكن لمشرف تكنولوجيا المعلومات ومزوّد خدمة الشبكة الافتراضية الخاصة (VPN) رؤية أنشطة الشبكة في تطبيقات العمل، بما في ذلك الرسائل الإلكترونية وبيانات التصفُّح."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"إيقاف"</string>
     <string name="sound_settings" msgid="8874581353127418308">"الصوت والاهتزاز"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"الإعدادات"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"تم خفض الصوت إلى المستوى الآمن"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"كان مستوى الصوت مرتفعًا لمدة أطول مما يُنصَح به."</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"تم خفض مستوى الصوت إلى مستوى أكثر أمانًا"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"كان مستوى صوت سمّاعة الرأس مرتفعًا لمدة أطول مما يُنصَح به."</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"تجاوز مستوى صوت سمّاعة الرأس الحد الآمن هذا الأسبوع."</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"مواصلة الاستماع"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"خفض مستوى الصوت"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"تم تثبيت الشاشة على التطبيق"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"يؤدي هذا إلى استمرار عرض الشاشة المُختارة إلى أن تتم إزالة تثبيتها. المس مع الاستمرار الزرين \"رجوع\" و\"نظرة عامة\" لإزالة التثبيت."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"يؤدي هذا إلى استمرار عرض الشاشة المُختارة إلى أن تتم إزالة تثبيتها. المس مع الاستمرار الزرين \"رجوع\" و\"الشاشة الرئيسية\" لإزالة التثبيت."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"الإعدادات"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"يتم تشغيل <xliff:g id="SONG_NAME">%1$s</xliff:g> للفنان <xliff:g id="ARTIST_NAME">%2$s</xliff:g> من تطبيق <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> من إجمالي <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"\"<xliff:g id="APP_NAME">%1$s</xliff:g>\" قيد التشغيل"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"تشغيل"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"إيقاف مؤقت"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"المقطع الصوتي السابق"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%%<xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"مكبّرات الصوت والشاشات"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"الأجهزة المقترَحة"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"أوقِف الجلسة المشتركة لنقل الوسائط إلى جهاز آخر."</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"إيقاف"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"كيفية عمل البث"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"البث"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"يمكن للأشخاص القريبين منك الذين لديهم أجهزة متوافقة تتضمّن بلوتوث الاستماع إلى الوسائط التي تبثها."</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"عليك توصيل قلم الشاشة بشاحن."</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"بطارية قلم الشاشة منخفضة"</string>
     <string name="video_camera" msgid="7654002575156149298">"كاميرا فيديو"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"لا يمكن الاتصال باستخدام هذا الملف الشخصي."</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"تسمح لك سياسة العمل بإجراء المكالمات الهاتفية من الملف الشخصي للعمل فقط."</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"لا يمكن الاتصال من تطبيق شخصي"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"تسمح لك مؤسستك بإجراء المكالمات من تطبيقات العمل فقط."</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"التبديل إلى الملف الشخصي للعمل"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"إغلاق"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"تثبيت تطبيق الهاتف في الملف الشخصي للعمل"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"إلغاء"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"تخصيص شاشة القفل"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"الفتح لتخصيص شاشة القفل"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"‏لا يتوفّر اتصال Wi-Fi."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 978130e..02637642 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"শ্বেয়াৰ কৰক"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"স্ক্ৰীন ৰেকৰ্ডিং ছেভ কৰা হ’ল"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"চাবলৈ টিপক"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"স্ক্রীন ৰেকৰ্ডিং মচি থাকোঁতে কিবা আসোঁৱাহ হ’ল"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"ৰেকৰ্ড কৰা স্ক্ৰীন ছেভ কৰোঁতে আসোঁৱাহ হৈছে"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"স্ক্রীন ৰেকৰ্ড কৰা আৰম্ভ কৰোঁতে আসোঁৱাহ হৈছে"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"উভতি যাওক"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"গৃহ পৃষ্ঠাৰ বুটাম"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"নিশ্চিত কৰিলে"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"সম্পূৰ্ণ কৰিবলৈ নিশ্চিত কৰক-ত টিপক"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। অব্যাহত ৰাখিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। অব্যাহত ৰাখিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"অক্ষম কৰক"</string>
     <string name="sound_settings" msgid="8874581353127418308">"ধ্বনি আৰু কম্পন"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ছেটিং"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"নিৰাপদ ভলিউমলৈ কমোৱা হৈছে"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"চুপাৰিছ কৰাতকৈ দীঘলীয়া সময়ৰ বাবে ভলিউম উচ্চ হৈ আছিল"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ভলিউম সুৰক্ষিত স্তৰলৈ কম কৰা হৈছে"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"চুপাৰিছ কৰাতকৈ দীঘলীয়া সময়ৰ বাবে হেডফ’নৰ ভলিউম উচ্চ হৈ আছে"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"হেডফ’নৰ ভলিউমে এই সপ্তাহৰ বাবে সুৰক্ষিত সীমা অতিক্ৰম কৰিছে"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"শুনি থাকক"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"ভলিউম কমাওক"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"এপ্‌টো পিন কৰা আছে"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"এই কাৰ্যই আপুনি আনপিন নকৰালৈকে ইয়াক দেখা পোৱা অৱস্থাত ৰাখে। আনপিন কৰিবলৈ \'পিছলৈ যাওক\' আৰু \'অৱলোকন\'-ত স্পৰ্শ কৰি থাকক।"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"এই কাৰ্যই আপুনি আনপিন নকৰালৈকে ইয়াক দেখা পোৱা অৱস্থাত ৰাখে। আনপিন কৰিবলৈ পিছলৈ যাওক আৰু হ\'মত স্পৰ্শ কৰি সেঁচি ধৰক।"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ছেটিং"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ত <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ৰ <xliff:g id="SONG_NAME">%1$s</xliff:g> গীতটো প্লে’ হৈ আছে"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>ৰ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> চলি আছে"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"প্লে’ কৰক"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"পজ কৰক"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"পূৰ্বৱৰ্তী ট্ৰেক"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"আপোনাৰ ষ্টাইলাছ এটা চাৰ্জাৰৰ সৈতে সংযোগ কৰক"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"ষ্টাইলাছৰ বেটাৰী কম আছে"</string>
     <string name="video_camera" msgid="7654002575156149298">"ভিডিঅ’ কেমেৰা"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"এই প্ৰ’ফাইলৰ পৰা কল কৰিব নোৱাৰি"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"আপোনাৰ কৰ্মস্থানৰ নীতিয়ে আপোনাক কেৱল কৰ্মস্থানৰ প্ৰ’ফাইলৰ পৰা ফ’ন কল কৰিবলৈ দিয়ে"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"ব্যক্তিগত এপৰ পৰা বাৰ্তা পঠিয়াব নোৱাৰি"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"আপোনাৰ প্ৰতিষ্ঠানে আপোনাক কেৱল কাম সম্পৰ্কীয় এপ্‌সমূহৰ পৰা কল কৰিবলৈ অনুমতি দিয়ে"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"কৰ্মস্থানৰ প্ৰ’ফাইললৈ সলনি কৰক"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"বন্ধ কৰক"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"কাম সম্পৰ্কীয় এটা ফ’ন এপ্ ইনষ্টল কৰক"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"বাতিল কৰক"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"লক স্ক্ৰীন কাষ্টমাইজ কৰক"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"লক স্ক্ৰীন কাষ্টমাইজ কৰিবলৈ আনলক কৰক"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ৱাই-ফাই উপলব্ধ নহয়"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 9f3f175..047323f 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Paylaşın"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Ekran çəkilişi yadda saxlanıldı"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Baxmaq üçün toxunun"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekranın video çəkiminin silinməsi zamanı xəta baş verdi"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Ekran çəkimini yadda saxlayarkən xəta oldu"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Ekranın yazılması ilə bağlı xəta"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Geri"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Ana səhifə"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Üz doğrulandı"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Təsdiqləndi"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tamamlamaq üçün \"Təsdiq edin\" seçiminə toxunun"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Üzlə kilidi açılıb. \"Kilidi aç\" ikonasına basıb davam edin."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Üz ilə kiliddən çıxarılıb. Davam etmək üçün basın."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Üz tanınıb. Davam etmək üçün basın."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Üz tanınıb. \"Kiliddən çıxar\" ikonasına basıb davam edin."</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Bu cihazda sertifikat səlahiyyəti quraşdırıldı. Təhlükəsiz şəbəkə ötürülməsinə nəzarət edilə və ya dəyişdirilə bilər."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Admin cihazda şəbəkə ötürülməsinə nəzarət edən şəbəkə qeydlərini aktiv etdi."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Admininiz şəxsi profilinizdəki deyil, iş profilinizdəki trafikə nəzarət edən şəbəkə qeydiyyatını aktiv edib."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Bu cihaz <xliff:g id="VPN_APP">%1$s</xliff:g> ilə internetə qoşulub. VPN provayderi e-məktub və baxış datası daxil olmaqla şəbəkə fəaliyyətini görür."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Bu cihaz <xliff:g id="VPN_APP">%1$s</xliff:g> ilə internetə qoşulub. VPN provayderi sizin e-məktub və baxış datanız daxil olmaqla şəbəkə fəaliyyətinizi görür."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"Bu cihaz <xliff:g id="VPN_APP">%1$s</xliff:g> ilə internetə qoşulub. IT admini e-məktub və baxış datası daxil olmaqla şəbəkə fəaliyyətini görür."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Bu cihaz <xliff:g id="VPN_APP_0">%1$s</xliff:g> və <xliff:g id="VPN_APP_1">%2$s</xliff:g> vasitəsilə internetə qoşulub. E-məktublar və baxış datası daxil olmaqla, iş tətbiqlərindəki şəbəkə fəaliyyətiniz İT admininiz görünür."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"İş tətbiqləriniz <xliff:g id="VPN_APP">%1$s</xliff:g> vasitəsilə internetə qoşulub. E-məktublar və baxış datası daxil olmaqla, iş tətbiqlərindəki şəbəkə fəaliyyətiniz İT admininiz və VPN provayderinizə görünür."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktiv edin"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Səs və vibrasiya"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Ayarlar"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Təhlükəsiz səs səviyyəsinə azaldıldı"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Səs səviyyəsi tövsiyə ediləndən uzun müddət yüksək olub"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Səs təhlükəsiz səviyyəyə azaldıldı"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Qulaqlığın səsi tövsiyə ediləndən uzun müddət yüksək olub"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Bu həftə qulaqlığın səsi təhlükəsiz limiti keçib"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Dinləməyə davam edin"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Səsi azaldın"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Tətbiq bərkidilib"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Sancaq götürülənə qədər bu görünəcək. Sancağı götürmək üçün Geri və İcmal düymələrinə basıb saxlayın."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"\"Geri\" və \"Əsas ekran\" düymələrinin davamlı basılması ilə çıxarılana qədər tətbiq göz önündə qalır."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> tərəfindən <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%3$s</xliff:g> tətbiqindən oxudulur"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> işləyir"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Oxudun"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Durdurun"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Əvvəlki trek"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Dinamiklər &amp; Displeylər"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Təklif olunan Cihazlar"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Medianı başqa cihaza köçürmək üçün paylaşılan sessiyanı dayandırın"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Dayandırın"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Yayım necə işləyir"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Yayım"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Uyğun Bluetooth cihazları olan yaxınlığınızdakı insanlar yayımladığınız medianı dinləyə bilər"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Qələmi adapterə qoşun"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Qələm enerjisi azdır"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Bu profildən zəng etmək mümkün deyil"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"İş siyasətiniz yalnız iş profilindən telefon zəngləri etməyə imkan verir"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Şəxsi tətbiqdən zəng etmək olmur"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Təşkilat yalnız iş tətbiqindən zəng etməyə icazə verir"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"İş profilinə keçin"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Bağlayın"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"İş üçün telefon tətbiqi quraşdırın"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Ləğv edin"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Kilid ekranını fərdiləşdirin"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Kilid ekranını fərdiləşdirmək üçün kiliddən çıxarın"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi əlçatan deyil"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index e730ae84..5575274 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Deli"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Snimak ekrana je sačuvan"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite da biste pregledali"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Došlo je do problema pri brisanju snimka ekrana"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Greška pri čuvanju snimka ekrana"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Nazad"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Početna"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Lice je potvrđeno"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi da biste završili"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Otključano je licem. Pritisnite ikonu otključavanja za nastavak"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano je licem. Pritisnite da biste nastavili."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice je prepoznato. Pritisnite da biste nastavili."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu otključavanja za nastavak."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"onemogućite"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Zvuk i vibriranje"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Podešavanja"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Zvuk je smanjen na bezbednu jačinu"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Zvuk je bio glasan duže nego što se preporučuje"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Zvuk je smanjen na bezbednu jačinu"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Zvuk u slušalicama je bio glasan duže nego što se preporučuje"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Jačina zvuka u slušalicama je premašila bezbednosno ograničenje za ovu nedelju"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Nastavite da slušate"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Smanjite jačinu zvuka"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Aplikacija je zakačena"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Nazad i Pregled da biste ga otkačili."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Nazad i Početna da biste ga otkačili."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Podešavanja"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se pušta iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je pokrenuta"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Pusti"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pauziraj"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Prethodna pesma"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvučnici i ekrani"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predloženi uređaji"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Zaustavite deljenu sesiju da biste premestili medijski sadržaj na drugi uređaj"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Zaustavi"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako funkcioniše emitovanje"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Emitovanje"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ljudi u blizini sa kompatibilnim Bluetooth uređajima mogu da slušaju medijski sadržaj koji emitujete"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Povežite pisaljku sa punjačem"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Nizak nivo baterije pisaljke"</string>
     <string name="video_camera" msgid="7654002575156149298">"Video kamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Ne možete da upućujete pozive sa ovog profila"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Smernice za posao vam omogućavaju da telefonirate samo sa poslovnog profila"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Ne možete da upućujete pozive iz lične aplikacije"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Vaša organizacija dozvoljava pozivanje samo iz poslovnih aplikacija"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pređi na poslovni profil"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string>
+    <string name="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čani ekran"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Otključajte da biste prilagodili zaključani ekran"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"WiFi nije dostupan"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index ad0b675..1576fb5 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Абагуліць"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Запіс экрана захаваны"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Націсніце для прагляду"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Памылка выдалення запісу экрана"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Памылка захавання запісу экрана"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Памылка пачатку запісу экрана"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"На Галоўную старонку"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Твар распазнаны"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Пацверджана"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Націсніце \"Пацвердзіць\", каб завяршыць"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Твар распазнаны. Для працягу націсніце значок разблакіроўкі."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Разблакіравана распазнаваннем твару. Націсніце для працягу."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Твар распазнаны. Націсніце для працягу."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Твар распазнаны. Для працягу націсніце значок разблакіроўкі."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"адключыць"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Гук і вібрацыя"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Налады"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Гук паменшаны да бяспечнага ўзроўню"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Гучнасць была моцнай больш часу, чым рэкамендавана"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Гучнасць паніжана да больш бяспечнага ўзроўню"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Гучнасць у навушніках была вялікай больш часу, чым рэкамендавана"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Гучнасць у навушніках перавысіла ліміт бяспечнага праслухоўвання на гэтым тыдні"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Працягваць слухаць"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Паменшыць гучнасць"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Праграма замацавана"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Будзе паказвацца, пакуль не адмацуеце. Каб адмацаваць, краніце і ўтрымлівайце кнопкі \"Назад\" і \"Агляд\"."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Будзе паказвацца, пакуль не адмацуеце. Каб адмацаваць, націсніце і ўтрымлівайце кнопкі \"Назад\" і \"Галоўны экран\"."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Налады"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"У праграме \"<xliff:g id="APP_LABEL">%3$s</xliff:g>\" прайграецца кампазіцыя \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\", выканаўца – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> з <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> працуе"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Прайграць"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Прыпыніць"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Папярэдні трэк"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Дынамікі і дысплэі"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Прылады, якія падтрымліваюцца"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Каб перамясціць медыяфайлы на іншую прыладу, спыніце абагулены сеанс"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Спыніць"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Як адбываецца трансляцыя"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Трансляцыя"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Людзі паблізу, у якіх ёсць прылады з Bluetooth, змогуць праслухваць мультымедыйнае змесціва, якое вы трансліруеце"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Падключыце пяро да зараднай прылады"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Нізкі ўзровень зараду пяра"</string>
     <string name="video_camera" msgid="7654002575156149298">"Відэакамера"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Не ўдалося зрабіць выклік з гэтага профілю"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Згодна з палітыкай вашай арганізацыі, рабіць тэлефонныя выклікі дазволена толькі з працоўнага профілю"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Нельга рабіць выклік з асабістай праграмы"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Ваша арганізацыя дазваляе рабіць выклікі толькі з працоўных праграм"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Пераключыцца на працоўны профіль"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрыць"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Усталяваць праграму для тэлефона"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Скасаваць"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Наладзіць экран блакіроўкі"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Разблакіруйце, каб наладзіць экран блакіроўкі"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Сетка Wi-Fi недаступная"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 542f5c4..ec85234 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Споделяне"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Записът е запазен"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Докоснете за преглед"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"При изтриването на записа на екрана възникна грешка"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Грешка при запазването на записа на екрана"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"При стартирането на записа на екрана възникна грешка"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Начало"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лицето е удостоверено"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потвърдено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Докоснете „Потвърждаване“ за завършване"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Отключено с лице. Натиснете иконата за отключване, за да продължите."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Отключено с лице. Натиснете, за да продължите."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицето бе разпознато. Натиснете, за да продължите."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицето бе разпознато. Продължете чрез иконата за отключване."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"деактивиране"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Звук и вибриране"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Настройки"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Силата на звука е намалена до по-безопасно ниво"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Нивото на силата на звука е било високо по-дълго, отколкото е препоръчително"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Силата на звука е намалена до по-безопасно ниво"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Нивото на силата на звука на слушалките е било високо по-дълго, отколкото е препоръчително"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Нивото на силата на звука на слушалките е надвишило безопасния лимит за тази седмица"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Продължете да слушате"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Намаляване на силата на звука"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Приложението е фиксирано"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Екранът ще се показва, докато не го освободите с докосване и задържане на бутона за връщане назад и този за общ преглед."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Екранът ще се показва, докато не го освободите с докосване и задържане на бутона за връщане назад и „Начало“."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Настройки"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> на <xliff:g id="ARTIST_NAME">%2$s</xliff:g> се възпроизвежда от <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> от <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> се изпълнява"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Пускане"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Пауза"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Предишен запис"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Високоговорители и екрани"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Предложени устройства"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Спиране на споделената ви сесия с цел преместване на мултимедията на друго устройство"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Спиране"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Как работи предаването"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Предаване"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Хората в близост със съвместими устройства с Bluetooth могат да слушат мултимедията, която предавате"</string>
@@ -1054,7 +1057,7 @@
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Свързано"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Установена е временна връзка"</string>
     <string name="mobile_data_poor_connection" msgid="819617772268371434">"Слаба връзка"</string>
-    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Връзката за мобилни данни няма да е автоматична"</string>
+    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Връзката за мобилни данни няма да е автом."</string>
     <string name="mobile_data_no_connection" msgid="1713872434869947377">"Няма връзка"</string>
     <string name="non_carrier_network_unavailable" msgid="770049357024492372">"Няма други налични мрежи"</string>
     <string name="all_network_unavailable" msgid="4112774339909373349">"Няма налични мрежи"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Свържете писалката към зарядно устройство"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Батерията на писалката е изтощена"</string>
     <string name="video_camera" msgid="7654002575156149298">"Видеокамера"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Не може да се извърши обаждане от този потребителски профил"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Служебните правила ви дават възможност да извършвате телефонни обаждания само от служебния потребителски профил"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Не можете да извършвате обаждания от лично приложение"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Организацията ви разрешава да извършвате обаждания само от служебни приложения"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Превключване към служебния потребителски профил"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затваряне"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Инсталиране на служебно приложение за телефон"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Отказ"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Персонализ. на заключения екран"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Отключете, за да персонализирате заключения екран"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi не е налице"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 33225b1..3335c3d 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"শেয়ার করুন"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"স্ক্রিন রেকর্ডিং সেভ করা হয়েছে"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"দেখতে ট্যাপ করুন"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"স্ক্রিন রেকডিং মুছে ফেলার সময় সমস্যা হয়েছে"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"স্ক্রিন রেকর্ডিং সেভ করার সময় কোনও সমস্যা হয়েছে"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"স্ক্রিন রেকর্ডিং শুরু করার সময় সমস্যা হয়েছে"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"ফিরুন"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"হোম"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ফেস যাচাই করা হয়েছে"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"কনফার্ম করা হয়েছে"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"সম্পূর্ণ করতে \'কনফার্ম করুন\' বোতামে ট্যাপ করুন"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ফেসের সাহায্যে আনলক করা হয়েছে। চালিয়ে যাওয়ার জন্য আনলক আইকনে প্রেস করুন।"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ফেসের সাহায্যে আনলক করা হয়েছে। চালিয়ে যেতে প্রেস করুন।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ফেস শনাক্ত করা হয়েছে। চালিয়ে যেতে প্রেস করুন।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ফেস শনাক্ত করা হয়েছে। চালিয়ে যেতে আনলক আইকন প্রেস করুন।"</string>
@@ -414,7 +415,7 @@
     <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"শুরু করুন"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"আপনার আইটি অ্যাডমিন ব্লক করেছেন"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"ডিভাইস নীতির কারণে স্ক্রিন ক্যাপচার করার প্রসেস বন্ধ করা আছে"</string>
-    <string name="clear_all_notifications_text" msgid="348312370303046130">"সবকিছু সাফ করুন"</string>
+    <string name="clear_all_notifications_text" msgid="348312370303046130">"সব মুছে দিন"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"পরিচালনা করুন"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"ইতিহাস"</string>
     <string name="notification_section_header_incoming" msgid="850925217908095197">"নতুন"</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"এই ডিভাইসে একটি সার্টিফিকেট কর্তৃপক্ষ ইনস্টল করা আছে। আপনার নিরাপদ নেটওয়ার্ক ট্রাফিকে নজর রাখা হতে পারে বা তাতে পরিবর্তন করা হতে পারে।"</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"আপনার প্রশাসক নেটওয়ার্ক লগিং চালু করেছেন, যা আপনার ডিভাইসের ট্রাফিকের উপরে নজর রাখে।"</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"আপনার অ্যাডমিন নেটওয়ার্ক লগ করা চালু করেছেন যা আপনার অফিস প্রোফাইলে ট্রাফিক মনিটর করে তবে ব্যক্তিগত প্রোফাইলে করে না।"</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"<xliff:g id="VPN_APP">%1$s</xliff:g>-এর মাধ্যমে এই ডিভাইসটি ইন্টারনেটের সাথে কানেক্ট করা আছে। ইমেল ও ব্রাউজ করা ডেটা সহ আপনার নেটওয়ার্ক অ্যাক্টিভিটি VPN প্রদানকারী দেখতে পারবেন।"</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"এই ডিভাইসটিকে <xliff:g id="VPN_APP">%1$s</xliff:g>-এর মাধ্যমে ইন্টারনেটের সাথে কানেক্ট করা আছে। ইমেল ও ব্রাউজিং ডেটা সহ আপনার নেটওয়ার্ক অ্যাক্টিভিটি VPN প্রদানকারী দেখতে পারবেন।"</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"<xliff:g id="VPN_APP">%1$s</xliff:g>-এর মাধ্যমে এই ডিভাইসটি ইন্টারনেটের সাথে কানেক্ট করা আছে। ইমেল ও ব্রাউজ করা ডেটা সহ আপনার নেটওয়ার্ক অ্যাক্টিভিটি আইটি অ্যাডমিন দেখতে পারবেন।"</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> ও <xliff:g id="VPN_APP_1">%2$s</xliff:g>-এর মাধ্যমে এই ডিভাইস ইন্টারনেটের সাথে কানেক্ট করা আছে। ইমেল ও ব্রাউজ করা ডেটা সহ নেটওয়ার্ক অ্যাক্টিভিটি আপনার আইটি অ্যাডমিন দেখতে পারবেন।"</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"<xliff:g id="VPN_APP">%1$s</xliff:g>-এর মাধ্যমে আপনার অফিসের অ্যাপ ইন্টারনেটের সাথে কানেক্ট করা আছে। ইমেল ও ব্রাউজ করা ডেটা সহ অফিসের অ্যাপে করা নেটওয়ার্ক অ্যাক্টিভিটি আপনার আইটি অ্যাডমিন ও ভিপিএন প্রদানকারী দেখতে পারবেন।"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"বন্ধ হবে"</string>
     <string name="sound_settings" msgid="8874581353127418308">"সাউন্ড ও ভাইব্রেশন"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"সেটিংস"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"নিরাপদ ভলিউমে কমানো হয়েছে"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"যতক্ষণ সাজেস্ট করা হয়েছে তার থেকে বেশি সময় ভলিউম হাই ছিল"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ভলিউম কমিয়ে আরও নিরাপদ মাত্রায় নামানো হয়েছে"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"সাজেস্ট করা সময়ের চেয়ে অতিরিক্ত সময় ধরে হেডফোনের ভলিউম বেশি করা আছে"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"এই সপ্তাহে হেডফোনের ভলিউম নিরাপদ মাত্রা ছাড়িয়ে গেছে"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"শুনতে থাকুন"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"ভলিউম কমান"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"অ্যাপ পিন করা হয়েছে"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"এটি আপনি আনপিন না করা পর্যন্ত এটিকে প্রদর্শিত করবে৷ আনপিন করতে ফিরুন এবং ওভারভিউ স্পর্শ করে ধরে থাকুন।"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"এর ফলে আপনি এটি আনপিন না করা পর্যন্ত এটি দেখানো হতে থাকবে। আনপিন করতে \"ফিরে যান\" এবং \"হোম\" বোতামদুটি ট্যাপ করে ধরে রাখুন।"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"সেটিংস"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>-এর <xliff:g id="SONG_NAME">%1$s</xliff:g> গানটি <xliff:g id="APP_LABEL">%3$s</xliff:g> অ্যাপে চলছে"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>টির মধ্যে <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>টি"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> চলছে"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"চালান"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"পজ করুন"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"আগের ট্র্যাক"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"স্পিকার &amp; ডিসপ্লে"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"সাজেস্ট করা ডিভাইস"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"অন্য ডিভাইসে মিডিয়া সরাতে আপনার শেয়ার করা সেশন বন্ধ করুন"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"বন্ধ করুন"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ব্রডকাস্ট কীভাবে কাজ করে"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"সম্প্রচার করুন"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"আশপাশে লোকজন যাদের মানানসই ব্লুটুথ ডিভাইস আছে, তারা আপনার ব্রডকাস্ট করা মিডিয়া শুনতে পারবেন"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"কোনও চার্জারের সাথে আপনার স্টাইলাস কানেক্ট করুন"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"স্টাইলাস ব্যাটারিতে চার্জ কম আছে"</string>
     <string name="video_camera" msgid="7654002575156149298">"ভিডিও ক্যামেরা"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"এই প্রোফাইল থেকে কল করা যাচ্ছে না"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"কাজ সংক্রান্ত নীতি, আপনাকে শুধুমাত্র অফিস প্রোফাইল থেকে কল করার অনুমতি দেয়"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"ব্যক্তিগত অ্যাপ থেকে কল করা যাবে না"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"আপনার সংস্থা শুধু অফিসের অ্যাপ থেকেই আপনাকে কল করার অনুমতি দেয়"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"অফিস প্রোফাইলে পাল্টে নিন"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"বন্ধ করুন"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"একটি অফিসের ফোন অ্যাপ ইনস্টল করুন"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"বাতিল করুন"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"লক স্ক্রিন কাস্টমাইজ করুন"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"লক স্ক্রিন কাস্টমাইজ করতে আনলক করুন"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ওয়াই-ফাই উপলভ্য নয়"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index ed9f44f..4d6d78c 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Dijeli"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Snimak ekrana je sačuvan"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite da vidite"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Greška prilikom brisanja snimka ekrana"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Greška prilikom pohranjivanja snimka ekrana"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Greška pri pokretanju snimanja ekrana"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Nazad"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Dugme za početnu stranicu"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Lice je provjereno"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi da završite"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Otključano licem. Pritisnite ikonu za otklj. da nastavite."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano licem. Pritisnite da nastavite."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice prepoznato. Pritisnite da nastavite."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu za otklj. da nastavite."</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"CA certifikat je instaliran na ovom uređaju. Vaš saobraćaj preko sigurne mreže može se pratiti."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Vaš administrator je uključio zapisivanje na mreži, čime se prati saobraćaj na vašem uređaju."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administrator je uključio zapisivanje na mreži, čime se nadzire saobraćaj na vašem radnom profilu, ali ne i na ličnom profilu."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Uređaj je povezan s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša aktivnost na mreži, uključujući e-poruke i podatke o pregledanju, je vidljiva vašem IT administratoru."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Uređaj je povezan s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša mrežna aktivnost, uključujući e-poštu i podatke o pregledanju, je vidljiva vašem pružaocu VPN usluga."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"Uređaj je povezan s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša aktivnost na mreži, uključujući e-poruke i podatke o pregledanju, je vidljiva vašem IT administratoru."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Uređaj je povezan s internetom putem aplikacija <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Vaša mrežna aktivnost, uključujući e-poštu i podatke o pregledanju, je vidljiva vašem IT administratoru."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vaše poslovne aplikacije su povezane s internetom putem aplikacije <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša mrežna aktivnost u poslovnim aplikacijama, uključujući e-poštu i podatke o pregledanju, je vidljiva IT administratoru i pružaocu VPN usluga."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"onemogući"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Zvuk i vibracija"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Postavke"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Stišano je na sigurniju jačinu zvuka"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Jačina zvuka je bila glasna duže nego što se preporučuje"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Zvuk je smanjen na sigurniju jačinu"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Jačina zvuka slušalica je bila visoka duže od preporučenog"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Jačina zvuka slušalica je premašila sigurno ograničenje za ovu sedmicu"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Nastavite slušati"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Smanji jačinu zvuka"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Aplikacija je zakačena"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Ekran ostaje prikazan ovako dok ga ne otkačite. Da ga otkačite, dodirnite i držite dugme Nazad."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Na ovaj način ekran ostaje prikazan dok ga ne otkačite. Da otkačite ekran, dodirnite i držite dugme Nazad i Početna."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Pjesma <xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se reproducira pomoću aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je pokrenuta"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Reproduciranje"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pauziranje"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Prethodna numera"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvučnici i ekrani"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predloženi uređaji"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Zaustavite dijeljenu sesiju da premjestite medij na drugi uređaj"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Zaustavi"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako funkcionira emitiranje"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Emitirajte"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osobe u vašoj blizini s kompatibilnim Bluetooth uređajima mogu slušati medijske sadržaje koje emitirate"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Priključite pisaljku na punjač"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Baterija pisaljke je slaba"</string>
     <string name="video_camera" msgid="7654002575156149298">"Video kamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Nije moguće pozvati s ovog profila"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Radna pravila vam dozvoljavaju upućivanje telefonskih poziva samo s radnog profila"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Nije moguće pozvati iz lične aplikacije"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Vaša organizacija vam dozvoljava da upućujete pozive samo iz poslovnih aplikacija"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pređite na radni profil"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string>
+    <string name="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="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"WiFi mreža nije dostupna"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 66be1c2..a998436 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Comparteix"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"S\'ha desat la gravació de pantalla"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Toca per veure-la"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"S\'ha produït un error en suprimir la gravació de la pantalla"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"S\'ha produït un error en desar la gravació de la pantalla"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"S\'ha produït un error en iniciar la gravació de pantalla"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Enrere"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Inici"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Cara autenticada"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmat"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirma per completar"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"S\'ha desbloquejat amb la cara. Prem la icona per continuar."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"S\'ha desbloquejat amb la cara. Prem per continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"S\'ha reconegut la cara. Prem per continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"S\'ha reconegut la cara. Prem la icona per continuar."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"desactivar"</string>
     <string name="sound_settings" msgid="8874581353127418308">"So i vibració"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Configuració"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"El volum s\'ha abaixat a un nivell més segur"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"El volum ha estat elevat durant més temps del recomanat"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"El volum s\'ha abaixat a un nivell més segur"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"El volum dels auriculars ha estat elevat durant més temps del recomanat"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"El volum dels auriculars ha superat el límit de seguretat d\'aquesta setmana"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Continua escoltant"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Abaixa el volum"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"L\'aplicació està fixada"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Aquest element es continuarà mostrant fins que deixis de fixar-lo. Per fer-ho, toca i mantén premudes els botons Enrere i Aplicacions recents."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Aquest element es continuarà mostrant fins que deixis de fixar-lo. Per fer-ho, mantén premuts els botons Enrere i Inici."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Configuració"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) s\'està reproduint des de l\'aplicació <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> s\'està executant"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Reprodueix"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Posa en pausa"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Pista anterior"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Altaveus i pantalles"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositius suggerits"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Atura la sessió compartida per moure contingut multimèdia a un altre dispositiu"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Atura"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Com funciona l\'emissió"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Emet"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les persones properes amb dispositius Bluetooth compatibles poden escoltar el contingut multimèdia que emets"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connecta el llapis òptic a un carregador"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Bateria del llapis òptic baixa"</string>
     <string name="video_camera" msgid="7654002575156149298">"Càmera de vídeo"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"No es pot trucar des d\'aquest perfil"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"La teva política de treball et permet fer trucades només des del perfil de treball"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"No pots trucar des d\'una aplicació personal"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"La teva organització només et permet fer trucades des d\'aplicacions de treball"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Canvia al perfil de treball"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tanca"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instal·la una aplicació de treball per a telèfons"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Cancel·la"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalitza pantalla de bloqueig"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Desbloqueja per personalitzar la pantalla de bloqueig"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"No hi ha cap Wi‑Fi disponible"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 17a9566..4530fb7 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Sdílet"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Nahrávka obrazovky se uložila"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Klepnutím nahrávku zobrazíte"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Při mazání záznamu obrazovky došlo k chybě"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Při ukládání záznamu obrazovky došlo k chybě"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Při spouštění nahrávání obrazovky došlo k chybě"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Zpět"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Domů"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Obličej byl ověřen"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrzeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ověření dokončíte klepnutím na Potvrdit"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Odemknuto obličejem. Klepněte na ikonu odemknutí."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odemknuto obličejem. Pokračujte stisknutím."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Obličej rozpoznán. Pokračujte stisknutím."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Obličej rozpoznán. Klepněte na ikonu odemknutí."</string>
@@ -270,7 +271,7 @@
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Převrácení barev"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Korekce barev"</string>
     <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Velikost písma"</string>
-    <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Správa uživatelů"</string>
+    <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Spravovat uživatele"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Hotovo"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zavřít"</string>
     <string name="quick_settings_connected" msgid="3873605509184830379">"Připojeno"</string>
@@ -390,7 +391,7 @@
     <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Přidáním nového uživatele ukončíte režim hosta a smažete všechny aplikace a data z aktuální relace hosta."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Bylo dosaženo limitu uživatelů"</string>
     <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Lze vytvořit jen jednoho uživatele.}few{Přidat můžete maximálně # uživatele.}many{Přidat můžete maximálně # uživatele.}other{Přidat můžete maximálně # uživatelů.}}"</string>
-    <string name="user_remove_user_title" msgid="9124124694835811874">"Odstranit uživatele?"</string>
+    <string name="user_remove_user_title" msgid="9124124694835811874">"Odebrat uživatele?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Veškeré aplikace a data tohoto uživatele budou smazána."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Odstranit"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Začít nahrávat nebo odesílat s aplikací <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktivovat"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Zvuk a vibrace"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Nastavení"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Ztišeno na bezpečnější hlasitost"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Hlasitost byla vysoká déle, než je doporučeno"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Hlasitost byla snížena na bezpečnou úroveň"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Hlasitost sluchátek byla vysoká déle, než je doporučeno"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Hlasitost sluchátek překročila bezpečný limit pro tento týden"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Poslouchat dál"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Snížit hlasitost"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Aplikace je připnutá"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Obsah bude připnut v zobrazení, dokud jej neuvolníte. Uvolníte jej stisknutím a podržením tlačítek Zpět a Přehled."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Obsah bude připnut v zobrazení, dokud ho neuvolníte. Uvolníte ho podržením tlačítek Zpět a Plocha."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavení"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Skladba <xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> hrajte z aplikace <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> z <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> je spuštěna"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Přehrát"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pozastavit"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Předchozí skladba"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Reproduktory a displeje"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Navrhovaná zařízení"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Ukončí sdílenou relaci a bude možné přesunout médium do jiného zařízení"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Zastavit"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jak vysílání funguje"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Vysílání"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Lidé ve vašem okolí s kompatibilními zařízeními Bluetooth mohou poslouchat média, která vysíláte"</string>
@@ -1094,7 +1097,7 @@
     <string name="clipboard_image_preview" msgid="2156475174343538128">"Náhled obrázku"</string>
     <string name="clipboard_edit" msgid="4500155216174011640">"upravit"</string>
     <string name="add" msgid="81036585205287996">"Přidat"</string>
-    <string name="manage_users" msgid="1823875311934643849">"Správa uživatelů"</string>
+    <string name="manage_users" msgid="1823875311934643849">"Spravovat uživatele"</string>
     <string name="drag_split_not_supported" msgid="7173481676120546121">"Toto oznámení nepodporuje přetažení na rozdělenou obrazovku"</string>
     <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Síť Wi‑Fi není k dispozici"</string>
     <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"Prioritní režim"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Připojte dotykové pero k nabíječce"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Slabá baterie dotykového pera"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Z tohoto profilu nelze volat"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Vaše pracovní zásady vám umožňují telefonovat pouze z pracovního profilu"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Z osobní aplikace volat nelze"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Vaše organizace dovoluje volat jen z pracovních aplikací"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Přepnout na pracovní profil"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zavřít"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Nainstalovat pracovní telefonní aplikaci"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Zrušit"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Přizpůsobit zámek obrazovky"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Pokud chcete upravit obrazovku uzamčení, odemkněte zařízení"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Síť Wi-Fi není dostupná"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 93705f52..38eda88 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Del"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Skærmoptagelsen er gemt"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Tryk for at se"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Der opstod en fejl ved sletning af skærmoptagelsen"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Skærmoptagelsen kunne ikke gemmes"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Skærmoptagelsen kunne ikke startes"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Tilbage"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Hjem"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansigtet er godkendt"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekræftet"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tryk på Bekræft for at udføre"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Låst op vha. ansigt. Tryk på oplåsningsikonet for at fortsætte."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Låst op ved hjælp af ansigt. Tryk for at fortsætte."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansigt genkendt. Tryk for at fortsætte."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansigt genkendt. Tryk på oplåsningsikonet for at fortsætte."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktiver"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Lyd og vibration"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Indstillinger"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Der blev skruet ned til en mere sikker lydstyrke"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Lydstyrken har været for høj i længere tid end anbefalet"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Lydstyrken blev sænket til et mere sikkert niveau"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Høretelefonernes lydstyrke har været høj i længere tid end anbefalet"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Høretelefonernes lydstyrke har overskredet sikkerhedsgrænsen for denne uge"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Fortsæt med at lytte"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Skru ned for lyden"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Appen er fastgjort"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Dette fastholder skærmen i visningen, indtil du frigør den. Tryk på Tilbage og Overblik, og hold fingeren nede for at frigøre skærmen."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Dette fastholder skærmen i visningen, indtil du frigør den. Hold Tilbage og Startskærm nede for at frigøre skærmen."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Indstillinger"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> af <xliff:g id="ARTIST_NAME">%2$s</xliff:g> afspilles via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> af <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> kører"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Afspil"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Sæt på pause"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Afspil forrige"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Højttalere og skærme"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Foreslåede enheder"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Stop din delte session for at flytte medier til en anden enhed"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Stop"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Sådan fungerer udsendelser"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Udsendelse"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personer i nærheden, som har kompatible Bluetooth-enheder, kan lytte til det medie, du udsender"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Slut din styluspen til en oplader"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Lavt batteriniveau på styluspen"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Du kan ikke ringe fra denne profil"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Din arbejdspolitik tillader kun, at du kan foretage telefonopkald fra arbejdsprofilen"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Du kan ikke foretage opkald via en personlig app"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Din organisation tillader kun, at du foretager opkald via arbejdsapps"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skift til arbejdsprofil"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Luk"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installer en arbejdstelefonapp"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Annuller"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Tilpas låseskærm"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Lås op for at tilpasse låseskærmen"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi er ikke tilgængeligt"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index ce655a3..b6b896f 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Teilen"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Bildschirmaufzeichnung gespeichert"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Zum Ansehen tippen"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Fehler beim Löschen der Bildschirmaufzeichnung"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Fehler beim Speichern der Bildschirmaufzeichnung"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Fehler beim Start der Bildschirmaufzeichnung"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Zurück"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Startbildschirm"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Gesicht authentifiziert"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bestätigt"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Zum Abschließen auf \"Bestätigen\" tippen"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Per Gesichtserkennung entsperrt. Tippe auf das Symbol „Entsperren“, um fortzufahren."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Gerät mit dem Gesicht entsperrt. Tippe, um fortzufahren."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gesicht erkannt. Tippe, um fortzufahren."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gesicht erkannt. Tippe zum Fortfahren auf das Symbol „Entsperren“."</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Auf dem Gerät ist das Zertifikat einer Zertifizierungsstelle installiert. Eventuell wird dein sicherer Netzwerkverkehr überwacht oder bearbeitet."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Dein Administrator hat die Netzwerkprotokollierung aktiviert. Damit wird der Netzwerkverkehr auf deinem Gerät überwacht."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Dein Administrator hat die Netzwerkprotokollierung aktiviert. Damit werden die Zugriffe in deinem Arbeitsprofil erfasst, jedoch nicht in deinem privaten Profil."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Dieses Gerät ist über die <xliff:g id="VPN_APP">%1$s</xliff:g> mit dem Internet verbunden. Deine Netzwerkaktivitäten, einschließlich E-Mails und Browserdaten, sind für den VPN-Anbieter sichtbar."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Dieses Gerät geht über <xliff:g id="VPN_APP">%1$s</xliff:g> ins Internet. Der VPN-Anbieter hat Zugriff auf Daten zu deinen Netzwerkaktivitäten, einschließlich E-Mails und Browserdaten."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"Dieses Gerät ist über die <xliff:g id="VPN_APP">%1$s</xliff:g> mit dem Internet verbunden. Deine Netzwerkaktivitäten, einschließlich E-Mails und Browserdaten, sind für deinen IT-Administrator sichtbar."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Dieses Gerät ist über <xliff:g id="VPN_APP_0">%1$s</xliff:g> und <xliff:g id="VPN_APP_1">%2$s</xliff:g> mit dem Internet verbunden. Deine Netzwerkaktivitäten, einschließlich E-Mails und Browserdaten, sind für deinen IT-Administrator sichtbar."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Deine geschäftlichen Apps sind über <xliff:g id="VPN_APP">%1$s</xliff:g> mit dem Internet verbunden. Deine Netzwerkaktivitäten in geschäftlichen Apps, einschließlich E-Mails und Browserdaten, sind für deinen IT-Administrator und deinen VPN-Anbieter sichtbar."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktivieren"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Ton &amp; Vibration"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Einstellungen"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Lautstärke zur Sicherheit verringert"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Die Lautstärke war länger als empfohlen hoch eingestellt"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Auf sicherere Lautstärke gesenkt"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Die Kopfhörerlautstärke war länger als empfohlen hoch eingestellt"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Die Kopfhörerlautstärke hat für diese Woche das Sicherheitslimit überschritten"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Weiterhören"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Leiser stellen"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"App ist auf dem Bildschirm fixiert"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Die App bleibt so lange auf dem Bildschirm fixiert, bis du die Fixierung aufhebst. Berühre und halte dazu \"Zurück\" und \"Übersicht\"."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Die App bleibt so lange auf dem Bildschirm fixiert, bis du die Fixierung aufhebst. Berühre und halte dazu \"Zurück\" und \"Startbildschirm\"."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Einstellungen"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> von <xliff:g id="ARTIST_NAME">%2$s</xliff:g> wird gerade über <xliff:g id="APP_LABEL">%3$s</xliff:g> wiedergegeben"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> von <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> wird ausgeführt"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Wiedergeben"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pausieren"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Vorheriger Titel"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Lautsprecher &amp; Displays"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Vorgeschlagene Geräte"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Beende die Freigabesitzung zur Übertragung von Medien auf das andere Gerät"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Beenden"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Funktionsweise von Nachrichten an alle"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Nachricht an alle"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personen, die in der Nähe sind und kompatible Bluetooth-Geräten haben, können sich die Medien anhören, die du per Nachricht an alle sendest"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Schließe deinen Eingabestift an ein Ladegerät an"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Stylus-Akkustand niedrig"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Keine Anrufe über dieses Profil möglich"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Gemäß den Arbeitsrichtlinien darfst du nur über dein Arbeitsprofil telefonieren"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Telefonieren über private App nicht möglich"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Deine Organisation lässt das Telefonieren nur über geschäftliche Apps zu"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Zum Arbeitsprofil wechseln"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Schließen"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Geschäftliche Smartphone-App installieren"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Abbrechen"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Sperrbildschirm personalisieren"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Zum Anpassen des Sperrbildschirms entsperren"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Kein WLAN verfügbar"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 3560cf7..073e9f4 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Κοινοποίηση"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Η εγγραφή οθόνης αποθηκεύτηκε"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Πατήστε για προβολή"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Παρουσιάστηκε σφάλμα κατά τη διαγραφή της εγγραφής οθόνης"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Σφάλμα κατά την αποθήκευση της εγγραφής οθόνης"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Σφάλμα κατά την έναρξη της εγγραφής οθόνης"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Πίσω"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Αρχική οθόνη"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Έγινε έλεγχος ταυτότητας προσώπου"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Επιβεβαιώθηκε"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Πατήστε Επιβεβαίωση για ολοκλήρωση"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ξεκλείδωμα με πρόσωπο. Πατήστε το εικονίδιο ξεκλειδώματος."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ξεκλείδωμα με αναγνώριση προσώπου. Πατήστε για συνέχεια."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Το πρόσωπο αναγνωρίστηκε. Πατήστε για συνέχεια."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Το πρόσωπο αναγνωρ. Πατήστε το εικον. ξεκλειδ. για συνέχεια."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"απενεργοποίηση"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Ήχος και δόνηση"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Ρυθμίσεις"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Μειώθηκε σε πιο ασφαλή ένταση ήχου"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Η ένταση ήχου ήταν σε υψηλό επίπεδο για μεγαλύτερο διάστημα από αυτό που συνιστάται"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Η ένταση ήχου μειώθηκε σε πιο ασφαλές επίπεδο"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Η ένταση ήχου των ακουστικών ήταν σε υψηλό επίπεδο για μεγαλύτερο διάστημα από αυτό που συνιστάται"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Η ένταση ήχου των ακουστικών ξεπέρασε το ασφαλές όριο για αυτήν την εβδομάδα"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Συνέχιση ακρόασης"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Μείωση έντασης ήχου"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Η εφαρμογή είναι καρφιτσωμένη."</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Με αυτόν τον τρόπο παραμένει σε προβολή μέχρι να το ξεκαρφιτσώσετε. Αγγίξτε παρατεταμένα τα στοιχεία \"Επιστροφή\" και \"Επισκόπηση\" για ξεκαρφίτσωμα."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Με αυτόν τον τρόπο, παραμένει σε προβολή μέχρι να το ξεκαρφιτσώσετε. Αγγίξτε παρατεταμένα τα στοιχεία \"Πίσω\" και \"Αρχική οθόνη\" για ξεκαρφίτσωμα."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Ρυθμίσεις"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Γίνεται αναπαραγωγή του <xliff:g id="SONG_NAME">%1$s</xliff:g> από <xliff:g id="ARTIST_NAME">%2$s</xliff:g> στην εφαρμογή <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> από <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> εκτελείται"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Αναπαραγωγή"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Παύση"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Προηγούμενο κομμάτι"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Ηχεία και οθόνες"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Προτεινόμενες συσκευές"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Διακόψτε την κοινόχρηστη περίοδο λειτουργίας για να μεταφέρετε μέσα σε άλλη συσκευή"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Διακοπή"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Πώς λειτουργεί η μετάδοση"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Μετάδοση"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Οι άνθρωποι με συμβατές συσκευές Bluetooth που βρίσκονται κοντά σας μπορούν να ακούσουν το μέσο που μεταδίδετε."</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Συνδέστε τη γραφίδα σε έναν φορτιστή"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Χαμηλή στάθμη μπαταρίας γραφίδας"</string>
     <string name="video_camera" msgid="7654002575156149298">"Βιντεοκάμερα"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Δεν είναι δυνατή η κλήση από αυτό το προφίλ"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Η πολιτική εργασίας σάς επιτρέπει να πραγματοποιείτε τηλεφωνικές κλήσεις μόνο από το προφίλ εργασίας σας."</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Δεν είναι δυνατές οι κλήσεις από μια προσωπική εφαρμογή"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Ο οργανισμός σας επιτρέπει την πραγματοποίηση κλήσεων μόνο από εφαρμογές εργασιών"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Εναλλαγή σε προφίλ εργασίας"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Κλείσιμο"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Εγκαταστήστε μια εφαρμογή εργασιών για τηλεφωνικές κλήσεις"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Ακύρωση"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Προσαρμογή οθόνης κλειδώματος"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Ξεκλειδώστε για προσαρμογή της οθόνης κλειδώματος"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Δεν υπάρχει διαθέσιμο δίκτυο Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 11d22f7..61c15e2 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Screen recording saved"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Back"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Unlocked by face. Press the unlock icon to continue."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"disable"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Sound and vibration"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Settings"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Lowered to safer volume"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"The volume has been high for longer than recommended"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume lowered to safer level"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Headphone volume has been high for longer than recommended"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Headphone volume has exceeded the safe limit for this week"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Keep listening"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Lower volume"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"App is pinned"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"This keeps it in view until you unpin. Touch &amp; hold Back and Overview to unpin."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"This keeps it in view until you unpin. Touch &amp; hold Back and Home to unpin."</string>
@@ -811,7 +815,7 @@
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"your operator"</string>
     <string name="auto_data_switch_disable_title" msgid="5146527155665190652">"Switch back to <xliff:g id="CARRIER">%s</xliff:g>?"</string>
     <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Mobile data won\'t automatically switch based on availability"</string>
-    <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"No thanks"</string>
+    <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"No, thanks"</string>
     <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Yes, switch"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"Because an app is obscuring a permission request, Settings can’t verify your response."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"Allow <xliff:g id="APP_0">%1$s</xliff:g> to show <xliff:g id="APP_2">%2$s</xliff:g> slices?"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Play"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pause"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Previous track"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connect your stylus to a charger"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Stylus battery low"</string>
     <string name="video_camera" msgid="7654002575156149298">"Video camera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Can\'t call from this profile"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Your work policy allows you to make phone calls only from the work profile"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Can\'t call from a personal app"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Your organisation only allows you to make calls from work apps"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Switch to work profile"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Install a work phone app"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Cancel"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Customise lock screen"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Unlock to customise lock screen"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi not available"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 41c7bc5..d442f6a 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Screen recording saved"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Back"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Unlocked by face. Press the unlock icon to continue."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognized. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognized. Press the unlock icon to continue."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"disable"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Sound and vibration"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Settings"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Lowered to safer volume"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"The volume has been high for longer than recommended"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume lowered to safer level"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Headphone volume has been high for longer than recommended"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Headphone volume has exceeded the safe limit for this week"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Keep listening"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Lower volume"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"App is pinned"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"This keeps it in view until you unpin. Touch and hold Back and Overview to unpin."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"This keeps it in view until you unpin. Touch and hold Back and Home to unpin."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Play"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pause"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Previous track"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connect your stylus to a charger"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Stylus battery low"</string>
     <string name="video_camera" msgid="7654002575156149298">"Video camera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Can\'t call from this profile"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Your work policy allows you to make phone calls only from the work profile"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Can\'t call from a personal app"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Your organization only allows you to make calls from work apps"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Switch to work profile"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Install a work phone app"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Cancel"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Customize lock screen"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Unlock to customize lock screen"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi not available"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 11d22f7..61c15e2 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Screen recording saved"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Back"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Unlocked by face. Press the unlock icon to continue."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"disable"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Sound and vibration"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Settings"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Lowered to safer volume"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"The volume has been high for longer than recommended"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume lowered to safer level"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Headphone volume has been high for longer than recommended"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Headphone volume has exceeded the safe limit for this week"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Keep listening"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Lower volume"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"App is pinned"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"This keeps it in view until you unpin. Touch &amp; hold Back and Overview to unpin."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"This keeps it in view until you unpin. Touch &amp; hold Back and Home to unpin."</string>
@@ -811,7 +815,7 @@
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"your operator"</string>
     <string name="auto_data_switch_disable_title" msgid="5146527155665190652">"Switch back to <xliff:g id="CARRIER">%s</xliff:g>?"</string>
     <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Mobile data won\'t automatically switch based on availability"</string>
-    <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"No thanks"</string>
+    <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"No, thanks"</string>
     <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Yes, switch"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"Because an app is obscuring a permission request, Settings can’t verify your response."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"Allow <xliff:g id="APP_0">%1$s</xliff:g> to show <xliff:g id="APP_2">%2$s</xliff:g> slices?"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Play"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pause"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Previous track"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connect your stylus to a charger"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Stylus battery low"</string>
     <string name="video_camera" msgid="7654002575156149298">"Video camera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Can\'t call from this profile"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Your work policy allows you to make phone calls only from the work profile"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Can\'t call from a personal app"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Your organisation only allows you to make calls from work apps"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Switch to work profile"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Install a work phone app"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Cancel"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Customise lock screen"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Unlock to customise lock screen"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi not available"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 11d22f7..61c15e2 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Share"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Screen recording saved"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error deleting screen recording"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Back"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Face authenticated"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmed"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tap Confirm to complete"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Unlocked by face. Press the unlock icon to continue."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"disable"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Sound and vibration"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Settings"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Lowered to safer volume"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"The volume has been high for longer than recommended"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume lowered to safer level"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Headphone volume has been high for longer than recommended"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Headphone volume has exceeded the safe limit for this week"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Keep listening"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Lower volume"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"App is pinned"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"This keeps it in view until you unpin. Touch &amp; hold Back and Overview to unpin."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"This keeps it in view until you unpin. Touch &amp; hold Back and Home to unpin."</string>
@@ -811,7 +815,7 @@
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"your operator"</string>
     <string name="auto_data_switch_disable_title" msgid="5146527155665190652">"Switch back to <xliff:g id="CARRIER">%s</xliff:g>?"</string>
     <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Mobile data won\'t automatically switch based on availability"</string>
-    <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"No thanks"</string>
+    <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"No, thanks"</string>
     <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Yes, switch"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"Because an app is obscuring a permission request, Settings can’t verify your response."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"Allow <xliff:g id="APP_0">%1$s</xliff:g> to show <xliff:g id="APP_2">%2$s</xliff:g> slices?"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Play"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pause"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Previous track"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connect your stylus to a charger"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Stylus battery low"</string>
     <string name="video_camera" msgid="7654002575156149298">"Video camera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Can\'t call from this profile"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Your work policy allows you to make phone calls only from the work profile"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Can\'t call from a personal app"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Your organisation only allows you to make calls from work apps"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Switch to work profile"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Install a work phone app"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Cancel"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Customise lock screen"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Unlock to customise lock screen"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi not available"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index de44510..cbc9538 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎Share‎‏‎‎‏‎"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎Screen recording saved‎‏‎‎‏‎"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎Tap to view‎‏‎‎‏‎"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‎‎Error deleting screen recording‎‏‎‎‏‎"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎Error saving screen recording‎‏‎‎‏‎"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎Error starting screen recording‎‏‎‎‏‎"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎Back‎‏‎‎‏‎"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎Home‎‏‎‎‏‎"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎Face authenticated‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‏‎‎Confirmed‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‎Tap Confirm to complete‎‏‎‎‏‎"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎‏‎‎‏‏‏‎Unlocked by face. Press the unlock icon to continue.‎‏‎‎‏‎"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎Unlocked by face. Press to continue.‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‎‎‎Face recognized. Press to continue.‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎Face recognized. Press the unlock icon to continue.‎‏‎‎‏‎"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎disable‎‏‎‎‏‎"</string>
     <string name="sound_settings" msgid="8874581353127418308">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‎‎‎Sound &amp; vibration‎‏‎‎‏‎"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‏‎‎Settings‎‏‎‎‏‎"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎‎‎Lowered to safer volume‎‏‎‎‏‎"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‏‏‎‎‏‏‏‏‎‎‎The volume has been high for longer than recommended‎‏‎‎‏‎"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‎‎‏‏‎‏‎‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‎Volume lowered to safer level‎‏‎‎‏‎"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎Headphone volume has been high for longer than recommended‎‏‎‎‏‎"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‎‏‏‏‎‎‎Headphone volume has exceeded the safe limit for this week‎‏‎‎‏‎"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‎‏‏‎‏‎‏‏‏‎‎‏‏‎‎‎‎‎‎‎‎Keep listening‎‏‎‎‏‎"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‏‏‎‎‎‎‎‏‏‎Lower volume‎‏‎‎‏‎"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‎‎‎‏‎‎‏‏‎‎‏‎App is pinned‎‏‎‎‏‎"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‏‎‏‏‎‎‎‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‎‎‎‏‏‎‎‎‏‏‏‏‏‎This keeps it in view until you unpin. Touch &amp; hold Back and Overview to unpin.‎‏‎‎‏‎"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎This keeps it in view until you unpin. Touch &amp; hold Back and Home to unpin.‎‏‎‎‏‎"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎Settings‎‏‎‎‏‎"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="SONG_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ by ‎‏‎‎‏‏‎<xliff:g id="ARTIST_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ is playing from ‎‏‎‎‏‏‎<xliff:g id="APP_LABEL">%3$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‎‎‎‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎<xliff:g id="TOTAL_TIME">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is running‎‏‎‎‏‎"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎Play‎‏‎‎‏‎"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎Pause‎‏‎‎‏‎"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‎‏‎‎Previous track‎‏‎‎‏‎"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‎Connect your stylus to a charger‎‏‎‎‏‎"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‎Stylus battery low‎‏‎‎‏‎"</string>
     <string name="video_camera" msgid="7654002575156149298">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎Video camera‎‏‎‎‏‎"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‎‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‎‏‎‏‏‎Can\'t call from this profile‎‏‎‎‏‎"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎Your work policy allows you to make phone calls only from the work profile‎‏‎‎‏‎"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎Can\'t call from a personal app‎‏‎‎‏‎"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‎‏‎‎Your organization only allows you to make calls from work apps‎‏‎‎‏‎"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎Switch to work profile‎‏‎‎‏‎"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‎‎‏‎‏‏‏‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‎Close‎‏‎‎‏‎"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‏‎‎‏‏‎‏‎‏‎‎Install a work phone app‎‏‎‎‏‎"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‏‎Cancel‎‏‎‎‏‎"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‏‏‏‏‏‎Customize lock screen‎‏‎‎‏‎"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‏‏‏‏‎‏‏‎Unlock to customize lock screen‎‏‎‎‏‎"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‎‎‎Wi-Fi not available‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index af03e27..4855959 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Se guardó la grabación de pantalla"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Presiona para ver"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"No se pudo borrar la grabación de pantalla"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Se produjo un error al guardar la grabación de pantalla"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Error al iniciar la grabación de pantalla"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Atrás"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Página principal"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Se autenticó el rostro"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmado"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Presiona Confirmar para completar"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueo con rostro. Presiona ícono desbl. para continuar."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueo con rostro. Presiona para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rostro reconocido. Presiona para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rostro reconocido. Presiona el desbloqueo para continuar."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"inhabilitar"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Sonido y vibración"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Configuración"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Se bajó el volumen a un nivel seguro"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"El volumen se mantuvo elevado por más tiempo del recomendado"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Se bajó el volumen a un nivel seguro"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"El volumen de los auriculares se mantuvo elevado por más tiempo del recomendado"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Se excedió el límite seguro de volumen de los auriculares para esta semana"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Seguir escuchando"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Bajar volumen"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"La app está fijada"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Esta función mantiene la pantalla visible hasta que dejes de fijarla. Para ello, mantén presionados los botones Atrás y Recientes."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Esta función mantiene la pantalla visible hasta que dejes de fijarla. Para ello, mantén presionados los botones de inicio y Atrás."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Se está reproduciendo <xliff:g id="SONG_NAME">%1$s</xliff:g>, de <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Reproducir"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pausar"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Pista anterior"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Bocinas y pantallas"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Detiene la sesión de uso compartido para transferir contenido multimedia a otro dispositivo"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Detener"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cómo funciona la transmisión"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmisión"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Las personas cercanas con dispositivos Bluetooth compatibles pueden escuchar el contenido multimedia que transmites"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conecta tu pluma stylus a un cargador"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"La pluma stylus tiene poca batería"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videocámara"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"No se puede llamar desde este perfil"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Tu política del trabajo te permite hacer llamadas telefónicas solo desde el perfil de trabajo"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"No puedes realizar llamadas desde una app personal"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Tu organización solo te permite realizar llamadas desde apps de trabajo"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Cambiar al perfil de trabajo"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Cerrar"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instala una app de Teléfono de trabajo"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Cancelar"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizar pantalla de bloqueo"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Desbloquea para personalizar la pantalla de bloqueo"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi no disponible"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 76ca5f3..23a2d13 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Grabación de pantalla guardada"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Toca para verla"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"No se ha podido eliminar la grabación de la pantalla"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"No se ha podido guardar la grabación de pantalla"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"No se ha podido empezar a grabar la pantalla"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Atrás"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Inicio"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Cara autenticada"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirmar para completar la acción"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueado con la cara. Toca el icono de desbloquear para continuar."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado con la cara. Pulsa para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Cara reconocida. Pulsa para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Cara reconocida. Pulsa el icono de desbloquear para continuar."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"desactivar"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Sonido y vibración"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Ajustes"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Se ha bajado el volumen a un nivel más seguro"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"El volumen ha sido elevado durante más tiempo del recomendado"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volumen bajado a un nivel más seguro"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"El volumen de los auriculares ha estado alto durante más tiempo del recomendado"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"El volumen de los auriculares ha superado el límite de seguridad de esta semana"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Seguir escuchando"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Bajar volumen"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Aplicación fijada"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"La aplicación se mantendrá visible hasta que dejes de fijarla. Para dejar de fijarla, mantén pulsados los botones Atrás y Aplicaciones recientes."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"La aplicación se mantendrá visible hasta que dejes de fijarla. Para dejar de fijarla, mantén pulsados los botones Atrás e Inicio."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Ajustes"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Se está reproduciendo <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Reproducir"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pausar"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Canción anterior"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Altavoces y pantallas"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Sugerencias de dispositivos"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Detén tu sesión compartida para transferir el contenido multimedia a otro dispositivo"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Detener"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cómo funciona la emisión"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Emisión"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Las personas cercanas con dispositivos Bluetooth compatibles pueden escuchar el contenido multimedia que emites"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conecta tu lápiz óptico a un cargador"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Batería del lápiz óptico baja"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videocámara"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"No se puede llamar desde este perfil"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Tu política del trabajo solo te permite hacer llamadas telefónicas desde el perfil de trabajo"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"No puedes llamar desde una aplicación personal"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Tu organización solo te permite hacer llamadas desde aplicaciones de trabajo"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Cambiar al perfil de trabajo"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Cerrar"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalar una aplicación de llamadas de trabajo"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Cancelar"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizar pantalla de bloqueo"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Desbloquea para personalizar la pantalla de bloqueo"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Red Wi-Fi no disponible"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 8f8290b..2328b7b 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -103,7 +103,7 @@
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Salvestamise ajal on Androidil juurdepääs kõigele, mis on teie ekraanikuval nähtaval või mida teie seadmes esitatakse. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Rakenduse salvestamise ajal on Androidil juurdepääs kõigele, mis on selles rakenduses nähtaval või mida selles esitatakse. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Alusta salvestamist"</string>
-    <string name="screenrecord_audio_label" msgid="6183558856175159629">"Heli salvestamine"</string>
+    <string name="screenrecord_audio_label" msgid="6183558856175159629">"Salvesta heli"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Seadme heli"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Seadmest pärinev heli, nt muusika, kõned ja helinad"</string>
     <string name="screenrecord_mic_label" msgid="2111264835791332350">"Mikrofon"</string>
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Jaga"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Ekraanisalvestis on salvestatud"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Puudutage kuvamiseks"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Viga ekraanikuva salvestise kustutamisel"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Viga ekraanisalvestise salvestamisel"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Viga ekraanikuva salvestamise alustamisel"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Tagasi"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Kodu"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Nägu on autenditud"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Kinnitatud"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Lõpuleviimiseks puudutage nuppu Kinnita"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Avati näoga. Jätkamiseks vajutage avamise ikooni."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Avati näoga. Vajutage jätkamiseks."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Nägu tuvastati. Vajutage jätkamiseks."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Nägu tuvastati. Jätkamiseks vajutage avamise ikooni."</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Sertifikaadi volitus on sellesse seadmesse installitud. Teie turvalist võrguliiklust võidakse jälgida ja muuta."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Teie administraator lülitas sisse võrgu logimise funktsiooni, mis jälgib teie seadmes liiklust."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Teie administraator on sisse lülitanud võrgu logimise funktsiooni, mis jälgib liiklust teie võrguprofiilil, kuid mitte teie isiklikul profiilil."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"See seade on Internetiga ühendatud rakenduse <xliff:g id="VPN_APP">%1$s</xliff:g> kaudu. Teie võrgutegevus, sealhulgas meilid ja sirvimisandmed, on nähtav teie VPN-teenuse pakkujale."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"See seade on ühendatud internetiga rakenduse <xliff:g id="VPN_APP">%1$s</xliff:g> kaudu. Teie võrgutegevused, sealhulgas meilid ja sirvimisandmed, on nähtavad teie VPN-teenuse pakkujale."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"See seade on Internetiga ühendatud rakenduse <xliff:g id="VPN_APP">%1$s</xliff:g> kaudu. Teie võrgutegevus, sealhulgas meilid ja sirvimisandmed, on nähtav teie IT-administraatorile."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"See seade on ühendatud internetiga rakenduste <xliff:g id="VPN_APP_0">%1$s</xliff:g> ja <xliff:g id="VPN_APP_1">%2$s</xliff:g> kaudu. Teie võrgutegevused (sealhulgas meilid ja sirvimisandmed) on nähtavad teie IT-administraatorile."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Teie töörakendused on ühendatud internetiga rakenduse <xliff:g id="VPN_APP">%1$s</xliff:g> kaudu. Teie töörakenduste võrgutegevused (sealhulgas meilid ja sirvimisandmed) on nähtavad teie IT-administraatorile ning VPN-i teenusepakkujale."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"keela"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Heli ja vibreerimine"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Seaded"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Ohutuma helitugevuse huvides vähendatud"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Heli on olnud vali soovitatavast ajast kauem"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Helitugevust vähendati ohutumale tasemele"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Kõrvaklappide helitugevus on olnud suur soovitatavast ajast kauem"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Kõrvaklappide helitugevus on ületanud selle nädala ohutuspiirangu"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Jätkake kuulamist"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Vähenda helitugevust"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Rakendus on kinnitatud"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"See hoitakse kuval, kuni selle vabastate. Vabastamiseks puudutage pikalt nuppe Tagasi ja Ülevaade."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"See hoitakse kuval, kuni selle vabastate. Vabastamiseks puudutage pikalt nuppe Tagasi ja Avakuva."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Seaded"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> esitajalt <xliff:g id="ARTIST_NAME">%2$s</xliff:g> esitatakse rakenduses <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> töötab"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Esita"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Peata"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Eelmine lugu"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Ühendage elektronpliiats laadijaga"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Elektronpliiatsi akutase on madal"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokaamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Sellelt profiililt ei saa helistada"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Teie töökoha eeskirjad lubavad teil helistada ainult tööprofiililt"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Isiklikust rakendusest ei saa helistada"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Teie organisatsioon lubab helistada ainult töörakendustest"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Lülitu tööprofiilile"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sule"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"• Installige töö telefonirakendus"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Tühista"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Kohanda lukustuskuva"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Lukustuskuva kohandamiseks avage"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"WiFi pole saadaval"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 7b4e12d..269df8a 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -96,25 +96,19 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioak pantaila-argazkia hauteman du."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioak eta irekitako beste aplikazio batzuek pantaila-argazkia hauteman dute."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Gehitu oharrean"</string>
-    <!-- no translation found for screenrecord_title (4257171601439507792) -->
-    <skip />
+    <string name="screenrecord_title" msgid="4257171601439507792">"Pantaila-grabagailua"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pantaila-grabaketa prozesatzen"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pantailaren grabaketa-saioaren jakinarazpen jarraitua"</string>
-    <!-- no translation found for screenrecord_permission_dialog_title (303380743267672953) -->
-    <skip />
-    <!-- no translation found for screenrecord_permission_dialog_warning_entire_screen (4152602778470789965) -->
-    <skip />
-    <!-- no translation found for screenrecord_permission_dialog_warning_single_app (6818309727772146138) -->
-    <skip />
-    <!-- no translation found for screenrecord_permission_dialog_continue (5811122652514424967) -->
-    <skip />
+    <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Grabatzen hasi nahi duzu?"</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Grabatzen duzunean, pantailan ikusgai dagoen edo gailuan erreproduzitzen ari den guztia atzi dezake Android-ek. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Aplikazio bat grabatzen duzunean, aplikazio horretan ikusgai dagoen edo bertan erreproduzitzen ari den guztia atzi dezake Android-ek. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
+    <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Hasi grabatzen"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Grabatu audioa"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Gailuaren audioa"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Gailuko soinuak; adibidez, musika, deiak eta tonuak"</string>
     <string name="screenrecord_mic_label" msgid="2111264835791332350">"Mikrofonoa"</string>
     <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Gailuaren audioa eta mikrofonoa"</string>
-    <!-- no translation found for screenrecord_continue (4055347133700593164) -->
-    <skip />
+    <string name="screenrecord_continue" msgid="4055347133700593164">"Hasi"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Pantaila grabatzen"</string>
     <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Pantaila eta audioa grabatzen"</string>
     <string name="screenrecord_taps_label" msgid="1595690528298857649">"Erakutsi pantaila-ukitzeak"</string>
@@ -122,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Partekatu"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Gorde da pantailaren grabaketa"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Sakatu ikusteko"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Errore bat gertatu da pantailaren grabaketa ezabatzean"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Errore bat gertatu da pantaila-grabaketa gordetzean"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Errore bat gertatu da pantaila grabatzen hastean"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Atzera"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Hasiera"</string>
@@ -148,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Autentifikatu da aurpegia"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Berretsita"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Amaitzeko, sakatu \"Berretsi\""</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Aurpegiaren bidez desblokeatu da. Aurrera egiteko, sakatu desblokeatzeko ikonoa."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Aurpegiaren bidez desblokeatu da. Sakatu aurrera egiteko."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ezagutu da aurpegia. Sakatu aurrera egiteko."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ezagutu da aurpegia. Aurrera egiteko, sakatu desblokeatzeko ikonoa."</string>
@@ -400,42 +395,24 @@
     <string name="user_remove_user_message" msgid="6702834122128031833">"Erabiltzailearen aplikazio eta datu guztiak ezabatuko dira."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Kendu"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aplikazioarekin grabatzen edo igortzen hasi nahi duzu?"</string>
-    <!-- no translation found for media_projection_dialog_warning (1303664408388363598) -->
-    <skip />
-    <!-- no translation found for media_projection_sys_service_dialog_title (3751133258891897878) -->
-    <skip />
-    <!-- no translation found for media_projection_sys_service_dialog_warning (2443872865267330320) -->
-    <skip />
-    <!-- no translation found for screen_share_permission_dialog_option_entire_screen (3131200488455089620) -->
-    <skip />
-    <!-- no translation found for screen_share_permission_dialog_option_single_app (4350961814397220929) -->
-    <skip />
-    <!-- no translation found for screen_share_permission_app_selector_title (1404878013670347899) -->
-    <skip />
-    <!-- no translation found for media_projection_entry_app_permission_dialog_title (9155535851866407199) -->
-    <skip />
-    <!-- no translation found for media_projection_entry_app_permission_dialog_warning_entire_screen (8736391633234144237) -->
-    <skip />
-    <!-- no translation found for media_projection_entry_app_permission_dialog_warning_single_app (5211695779082563959) -->
-    <skip />
-    <!-- no translation found for media_projection_entry_app_permission_dialog_continue (295463518195075840) -->
-    <skip />
-    <!-- no translation found for media_projection_entry_cast_permission_dialog_title (8860150223172993547) -->
-    <skip />
-    <!-- no translation found for media_projection_entry_cast_permission_dialog_warning_entire_screen (1986212276016817231) -->
-    <skip />
-    <!-- no translation found for media_projection_entry_cast_permission_dialog_warning_single_app (9900961380294292) -->
-    <skip />
-    <!-- no translation found for media_projection_entry_cast_permission_dialog_continue (7209890669948870042) -->
-    <skip />
-    <!-- no translation found for media_projection_entry_generic_permission_dialog_title (4519802931547483628) -->
-    <skip />
-    <!-- no translation found for media_projection_entry_generic_permission_dialog_warning_entire_screen (5407906851409410209) -->
-    <skip />
-    <!-- no translation found for media_projection_entry_generic_permission_dialog_warning_single_app (3454859977888159495) -->
-    <skip />
-    <!-- no translation found for media_projection_entry_generic_permission_dialog_continue (8640381403048097116) -->
-    <skip />
+    <string name="media_projection_dialog_warning" msgid="1303664408388363598">"Zerbait grabatzen edo igortzen duzunean, pantailan ikusgai dagoen edo gailuak erreproduzitzen duen informazio guztia atzi dezake <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aplikazioak. Pasahitzak, ordainketen xehetasunak, argazkiak, mezuak eta erreproduzitzen dituzun audioak sartzen dira informazio horretan."</string>
+    <string name="media_projection_sys_service_dialog_title" msgid="3751133258891897878">"Grabatzen edo igortzen hasi nahi duzu?"</string>
+    <string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"Zerbait grabatzen edo igortzen duzunean, pantailan ikusgai dagoen edo gailuak erreproduzitzen duen informazio guztia erabili ahalko du funtzio hori eskaintzen duen zerbitzuak. Pasahitzak, ordainketen xehetasunak, argazkiak, mezuak eta erreproduzitzen dituzun audioak sartzen dira informazio horretan."</string>
+    <string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"Pantaila osoa"</string>
+    <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Aplikazio bakar bat"</string>
+    <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Partekatu edo grabatu aplikazio bat"</string>
+    <string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aplikazioarekin grabatzen edo igortzen hasi nahi duzu?"</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Edukia partekatzen, grabatzen edo igortzen ari zarenean, pantailan ikusgai dagoen edo gailuan erreproduzitzen ari den guztia atzi dezake <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aplikazioak. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Aplikazio bat partekatzen, grabatzen edo igortzen ari zarenean, aplikazio horretan ikusgai dagoen edo bertan erreproduzitzen ari den guztia atzi dezake <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aplikazioak. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
+    <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Hasi"</string>
+    <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Igortzen hasi nahi duzu?"</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Edukia igortzen ari zarenean, pantailan ikusgai dagoen edo gailuan erreproduzitzen ari den guztia atzi dezake Android-ek. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Aplikazio bat igortzen ari zarenean, aplikazio horretan ikusgai dagoen edo bertan erreproduzitzen ari den guztia atzi dezake Android-ek. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
+    <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Hasi igortzen"</string>
+    <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Partekatzen hasi nahi duzu?"</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Edukia partekatzen, grabatzen edo igortzen ari zarenean, pantailan ikusgai dagoen edo gailuan erreproduzitzen ari den guztia atzi dezake Android-ek. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Aplikazio bat partekatzen, grabatzen edo igortzen ari zarenean, aplikazio horretan ikusgai dagoen edo bertan erreproduzitzen ari den guztia atzi dezake Android-ek. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
+    <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Hasi"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"IKT saileko administratzaileak blokeatu du"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Pantaila-kapturak egiteko aukera desgaituta dago, gailu-gidalerroei jarraikiz"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Garbitu guztiak"</string>
@@ -484,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Autoritate ziurtagiri-emaile bat dago instalatuta gailuan. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administratzaileak sarearen erregistroak aktibatu ditu; horrela, zure gailuko trafikoa gainbegira dezake."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administratzaileak sarearen erregistroak aktibatu ditu; horrela, zure laneko profileko trafikoa gainbegira dezake, baina ez zure profil pertsonalekoa."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Gailua <xliff:g id="VPN_APP">%1$s</xliff:g> bidez dago konektatuta Internetera. IKT saileko administratzaileak sareko jarduerak (mezu elektronikoak eta arakatze-datuak barne) ikusi ahalko ditu."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Gailua <xliff:g id="VPN_APP">%1$s</xliff:g> bidez dago konektatuta Internetera. VPN hornitzaileak sareko jarduerak (mezu elektronikoak eta arakatze-datuak barne) ikusi ahalko ditu."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"Gailua <xliff:g id="VPN_APP">%1$s</xliff:g> bidez dago konektatuta Internetera. IKT saileko administratzaileak laneko aplikazioen bidez egiten dituzun sareko jarduerak (mezu elektronikoak eta arakatze-datuak barne) ikusi ahalko ditu."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Gailua <xliff:g id="VPN_APP_0">%1$s</xliff:g> eta <xliff:g id="VPN_APP_1">%2$s</xliff:g> bidez dago konektatuta Internetera. IKT saileko administratzaileak laneko aplikazioen bidez egiten dituzun sareko jarduerak (mezu elektronikoak eta arakatze-datuak barne) ikusi ahalko ditu."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Laneko aplikazioak <xliff:g id="VPN_APP">%1$s</xliff:g> bidez daude konektatuta Internetera. IKT saileko administratzaileak eta VPNaren hornitzaileak laneko aplikazioen bidez egiten dituzun sareko jarduerak (mezu elektronikoak eta arakatze-datuak barne) ikusi ahalko dituzte."</string>
@@ -503,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"desgaitu"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Audioa eta dardara"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Ezarpenak"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Bolumena jaitsi da entzumena babesteko"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Gomendatutakoa baino denbora gehiagoan eduki da bolumena ozen"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Bolumena maila seguruago batera jaitsi da"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Entzungailuen bolumena gomendatutako denboran baino gehiagoan eduki da ozen"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Entzungailuen bolumenak aste honetarako muga segurua gainditu du"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Jarraitu entzuten"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Jaitsi bolumena"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Aplikazioa ainguratuta dago"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Horrela, ikusgai egongo da aingura kendu arte. Aingura kentzeko, eduki sakatuta \"Atzera\" eta \"Ikuspegi orokorra\" botoiak."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Horrela, ikusgai egongo da aingura kendu arte. Aingura kentzeko, eduki sakatuta Atzera eta Hasiera botoiak."</string>
@@ -964,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Ezarpenak"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) ari da erreproduzitzen <xliff:g id="APP_LABEL">%3$s</xliff:g> bidez"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> abian da"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Erreproduzitu"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pausatu"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Aurrekoa"</string>
@@ -1163,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Konektatu arkatza kargagailu batera"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Arkatzak bateria gutxi du"</string>
     <string name="video_camera" msgid="7654002575156149298">"Bideokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Ezin duzu deitu profil honetatik"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Deiak laneko profiletik soilik egiteko baimena ematen dizute laneko gidalerroek"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Ezin duzu deitu aplikazio pertsonaletatik"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Laneko aplikazioetatik soilik deitzeko baimena ematen du zure erakundeak"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Aldatu laneko profilera"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Itxi"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalatu telefonoetarako aplikazio bat (lanerako)"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Utzi"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Pertsonalizatu pantaila blokeatua"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Desblokeatu eta pertsonalizatu pantaila blokeatua"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi-konexioa ez dago erabilgarri"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index b5c8f1f..1e0189c 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"هم‌رسانی"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"قطعه ضبط‌شده از صفحه‌نمایش ذخیره شد"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"برای مشاهده ضربه بزنید"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"خطا در حذف فایل ضبط صفحه‌نمایش"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"خطا در ذخیره‌سازی ضبط صفحه‌نمایش"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"خطا هنگام شروع ضبط صفحه‌نمایش"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"برگشت"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"صفحهٔ اصلی"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"چهره اصالت‌سنجی شد"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تأیید شد"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"برای تکمیل، روی تأیید ضربه بزنید"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"قفلْ با چهره باز شد. برای ادامه، نماد قفل‌گشایی را فشار دهید."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"قفلْ با چهره باز شد. برای ادامه، فشار دهید."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"چهره شناسایی شد. برای ادامه، فشار دهید."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"چهره شناسایی شد. برای ادامه، نماد قفل‌گشایی را فشار دهید."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"غیرفعال کردن"</string>
     <string name="sound_settings" msgid="8874581353127418308">"صدا و لرزش"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"تنظیمات"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"به میزان صدای ایمن‌تر کاهش یافت"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"صدا برای مدتی طولانی‌تر از حد توصیه‌شده بلند بوده است"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"صدا به سطح ایمن‌تر کاهش یافت"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"صدای هدفون برای مدتی طولانی‌تر از حد توصیه‌شده بلند بوده است"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"صدای هدفون از حد ایمن برای این هفته فراتر رفته است"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"ادامه گوش کردن"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"کم کردن صدا"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"برنامه سنجاق شده است"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"تا زمانی که سنجاق را برندارید، در نما نگه‌داشته می‌شود. برای برداشتن سنجاق، «برگشت» و «نمای کلی» را لمس کنید و نگه‌دارید."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"تا برداشتن سنجاق، در نما نگه‌داشته می‌شود. برای برداشتن سنجاق، «برگشت» و «صفحه اصلی» را لمس کنید و نگه‌دارید."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"تنظیمات"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> از <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ازطریق <xliff:g id="APP_LABEL">%3$s</xliff:g> پخش می‌شود"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> از <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> در حال اجرا است"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"پخش"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"توقف موقت"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"آهنگ قبلی"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"بلندگوها و نمایشگرها"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"دستگاه‌های پیشنهادی"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"جلسه مشترک برای انتقال رسانه به دستگاهی دیگر متوقف می‌شود"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"توقف"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"همه‌فرتستی چطور کار می‌کند"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"همه‌فرستی"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"‏افرادی که در اطرافتان دستگاه‌های Bluetooth سازگار دارند می‌توانند به رسانه‌ای که همه‌فرستی می‌کنید گوش کنند"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"قلم را به شارژر وصل کنید"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"باتری قلم ضعیف است"</string>
     <string name="video_camera" msgid="7654002575156149298">"دوربین ویدیویی"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"نمی‌توانید از این نمایه تماس بگیرید"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"خط‌مشی کاری شما فقط به برقراری تماس ازطریق نمایه کاری اجازه می‌دهد"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"نمی‌توانید ازطریق برنامه‌های شخصی تماس بگیرید"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"سازمانتان به شما اجازه می‌دهد فقط ازطریق برنامه‌های کاری تماس بگیرید"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"رفتن به نمایه کاری"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"بستن"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"نصب برنامه کاری در تلفن"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"لغو"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"سفارشی‌سازی صفحه قفل"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"برای سفارشی‌سازی صفحه قفل، قفل را باز کنید"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"‏Wi-Fi دردسترس نیست"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index d8315cd..2878c66ce 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Jaa"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Näyttötallenne tallennettu"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Napauta näyttääksesi"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Virhe poistettaessa näyttötallennetta"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Virhe näyttötallenteen tallentamisessa"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Virhe näytön tallennuksen aloituksessa"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Takaisin"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Aloitus"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Kasvot tunnistettu"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Vahvistettu"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Valitse lopuksi Vahvista"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Avattu kasvojen avulla. Jatka lukituksen avauskuvakkeella."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Avattu kasvojen avulla. Jatka painamalla."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Kasvot tunnistettu. Jatka painamalla."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Kasvot tunnistettu. Jatka lukituksen avauskuvakkeella."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"poista käytöstä"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Ääni ja värinä"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Asetukset"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Äänenvoimakkuutta vähennetty turvallisemmalle tasolle"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Äänenvoimakkuus on ollut suuri yli suositellun ajan"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Äänenvoimakkuus laskettu turvalliselle tasolle"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Äänenvoimakkuus on ollut suuri yli suositellun ajan"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Kuulokkeiden äänenvoimakkuus on ylittänyt tämän viikon turvarajan"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Jatka kuuntelua"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Vähennä äänenvoimakkuutta"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Sovellus on kiinnitetty"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Pysyy näkyvissä, kunnes irrotat sen. Irrota painamalla pitkään Edellinen ja Viimeisimmät."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Pysyy näkyvissä, kunnes irrotat sen. Irrota painamalla pitkään Edellinen ja Aloitusnäyttö."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Asetukset"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> soittaa nyt tätä: <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>)"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> on käynnissä"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Toista"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Keskeytä"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Edellinen kappale"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Kaiuttimet ja näytöt"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Ehdotetut laitteet"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Lopeta jaettu istunto, jotta voit siirtyä mediaan toisella laitteella"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Lopeta"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Miten lähetys toimii"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Lähetys"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Lähistöllä olevat ihmiset, joilla on yhteensopiva Bluetooth-laite, voivat kuunnella lähettämääsi mediaa"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Yhdistä näyttökynä laturiin"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Näyttökynän akku vähissä"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Tästä profiilista ei voi soittaa"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Työkäytäntö sallii sinun soittaa puheluita vain työprofiilista"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Et voi soittaa henkilökohtaisella sovelluksella"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Organisaatio sallii soittamisen vain työsovelluksilla"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Vaihda työprofiiliin"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sulje"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Asenna työpuhelinsovellus"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Peruuta"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Customize lukitusnäyttöä"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Avaa lukitus muokataksesi lukitusnäyttöä"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi-yhteys ei ole käytettävissä"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index b40bec0..0e7a0bd 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -122,7 +122,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Partager"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Enregistrement sauvegardé"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Touchez pour afficher"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Une erreur s\'est produite lors de la suppression de l\'enregistrement d\'écran"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Erreur d\'enregistrement de l\'écran"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Une erreur s\'est produite lors du démarrage de l\'enregistrement d\'écran"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Précédent"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Domicile"</string>
@@ -148,7 +148,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Visage authentifié"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmé"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Touchez Confirmer pour terminer"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Déverr. par reconn. faciale. App. sur l\'icône pour continuer."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Déverr. par reconnaissance faciale. Appuyez pour continuer."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Visage reconnu. Appuyez pour continuer."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Visage reconnu. Appuyez sur Déverrouiller pour continuer."</string>
@@ -171,34 +172,20 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Si vous entrez un schéma incorrect à la prochaine tentative suivante, votre profil professionnel et ses données seront supprimés."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Si vous entrez un NIP incorrect à la prochaine tentative, votre profil professionnel et ses données seront supprimés."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Si vous entrez un mot de passe incorrect à la prochaine tentative suivante, votre profil professionnel et ses données seront supprimés."</string>
-    <!-- no translation found for biometric_re_enroll_dialog_confirm (3049858021857801836) -->
-    <skip />
-    <!-- no translation found for biometric_re_enroll_dialog_cancel (93760939407091417) -->
-    <skip />
-    <!-- no translation found for biometric_re_enroll_notification_content (8685925877186288180) -->
-    <skip />
-    <!-- no translation found for fingerprint_re_enroll_notification_title (4539432429683916604) -->
-    <skip />
-    <!-- no translation found for fingerprint_re_enroll_notification_name (630798657797645704) -->
-    <skip />
-    <!-- no translation found for fingerprint_re_enroll_dialog_title (3526033128113925780) -->
-    <skip />
-    <!-- no translation found for fingerprint_re_enroll_dialog_content (4866561176695984879) -->
-    <skip />
-    <!-- no translation found for fingerprint_re_enroll_dialog_content_singular (3083663339787381218) -->
-    <skip />
-    <!-- no translation found for fingerprint_reenroll_failure_dialog_content (4733768492747300666) -->
-    <skip />
-    <!-- no translation found for face_re_enroll_notification_title (1850838867718410520) -->
-    <skip />
-    <!-- no translation found for face_re_enroll_notification_name (7384545252206120659) -->
-    <skip />
-    <!-- no translation found for face_re_enroll_dialog_title (6392173708176069994) -->
-    <skip />
-    <!-- no translation found for face_re_enroll_dialog_content (7353502359464038511) -->
-    <skip />
-    <!-- no translation found for face_reenroll_failure_dialog_content (7073947334397236935) -->
-    <skip />
+    <string name="biometric_re_enroll_dialog_confirm" msgid="3049858021857801836">"Configuration"</string>
+    <string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"Plus tard"</string>
+    <string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"Cela est requis pour améliorer la sécurité et la performance"</string>
+    <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"Configurer le Déverrouillage par empreinte digitale à nouveau"</string>
+    <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"Déverrouillage par empreinte digitale"</string>
+    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Configurer le Déverrouillage par empreinte digitale"</string>
+    <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"Pour configurer le Déverrouillage par empreinte digitale à nouveau, les images et les modèles actuels de votre empreinte digitale devront être supprimés.\n\nAprès cela, vous devrez configurer le Déverrouillage par empreinte digitale à nouveau pour utiliser votre empreinte digitale afin de déverrouiller votre téléphone."</string>
+    <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"Pour configurer le Déverrouillage par empreinte digitale à nouveau, les images et les modèles actuels de votre empreinte digitale devront être supprimés.\n\nAprès cela, vous devrez configurer le Déverrouillage par empreinte digitale à nouveau pour utiliser votre empreinte digitale afin de déverrouiller votre téléphone."</string>
+    <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Impossible de configurer le Déverrouillage par empreinte digitale. Accédez au menu Paramètres pour réessayer."</string>
+    <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Configurer le déverrouillage par reconnaissance faciale à nouveau"</string>
+    <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"Déverrouillage par reconnaissance faciale"</string>
+    <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Configurer le Déverrouillage par reconnaissance faciale"</string>
+    <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"Pour configurer le Déverrouillage par reconnaissance faciale à nouveau, votre modèle facial devra être supprimé.\n\nVous devrez configurer cette fonctionnalité à nouveau pour utiliser votre visage afin de déverrouiller votre téléphone."</string>
+    <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"Impossible de configurer le Déverrouillage par reconnaissance faciale. Accédez au menu Paramètres pour réessayer."</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Touchez le capteur d\'empreintes digitales"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Visage non reconnu. Utilisez plutôt l\'empreinte digitale."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -517,8 +504,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"désactiver"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Son et vibration"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Paramètres"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Réduction du volume à un niveau moins dangereux"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Le niveau du volume est resté élevé au-delà de la durée recommandée"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume réduit à un niveau plus sécuritaire"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Le niveau du volume des écouteurs est resté élevé au-delà de la durée recommandée"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Le niveau du volume des écouteurs a dépassé la limite de sécurité pour cette semaine"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Poursuivre l\'écoute"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Diminuer le volume"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"L\'application est épinglée"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur « Retour » et « Aperçu »."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur les touches Retour et Accueil."</string>
@@ -940,10 +930,9 @@
     <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"supprimer des favoris"</string>
     <string name="accessibility_control_move" msgid="8980344493796647792">"Déplacer l\'élément à la position <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"Commandes"</string>
-    <!-- no translation found for controls_favorite_subtitle (5818709315630850796) -->
-    <skip />
+    <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Choisissez les commandes de l\'appareil auxquelles vous souhaitez accéder rapidement"</string>
     <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Faites glisser les commandes pour les réorganiser"</string>
-    <string name="controls_favorite_removed" msgid="5276978408529217272">"Toutes les commandes ont été supprimées"</string>
+    <string name="controls_favorite_removed" msgid="5276978408529217272">"Toutes les commandes ont été retirées"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Modifications non enregistrées"</string>
     <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Afficher autres applications"</string>
     <string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Réorganiser"</string>
@@ -979,6 +968,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> est en cours de lecteur à partir de <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> en cours d\'exécution"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Faire jouer"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Interrompre"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Chanson précédente"</string>
@@ -1024,10 +1014,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Haut-parleurs et écrans"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Appareils suggérés"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Arrêtez votre session partagée pour déplacer des contenus multimédias vers un autre appareil"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Arrêter"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Fonctionnement de la diffusion"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Diffusion"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les personnes à proximité disposant d\'appareils Bluetooth compatibles peuvent écouter le contenu multimédia que vous diffusez"</string>
@@ -1179,11 +1167,12 @@
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Charge restante de la pile : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connectez votre stylet à un chargeur"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Pile du stylet faible"</string>
-    <string name="video_camera" msgid="7654002575156149298">"Mode vidéo"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Impossible de passer un appel à partir de ce profil"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Votre politique de l\'entreprise vous autorise à passer des appels téléphoniques uniquement à partir de votre profil professionnel"</string>
+    <string name="video_camera" msgid="7654002575156149298">"Caméra"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Impossible d\'appeler à partir d\'une application personnelle"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Votre organisation vous autorise à passer des appels uniquement à partir d\'applications professionnelles"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Passer au profil professionnel"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fermer"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installer une application de téléphone professionnelle"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Annuler"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personn. l\'écran de verrouillage"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Déverrouiller pour personnaliser l\'écran de verrouillage"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi non accessible"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index d7e0a4f..21176b3 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -99,7 +99,7 @@
     <string name="screenrecord_title" msgid="4257171601439507792">"Enregistreur d\'écran"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Enregistrement de l\'écran…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement de l\'écran"</string>
-    <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Lancer l\'enregistrement ?"</string>
+    <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Commencer à enregistrer ?"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Lorsque vous enregistrez, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages, photos et contenus audio et vidéo."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Lorsque vous enregistrez une appli, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages et contenus audio et vidéo."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Lancer l\'enregistrement"</string>
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Partager"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Enregistrement sauvegardé"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Appuyez pour afficher"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Erreur lors de la suppression de l\'enregistrement de l\'écran"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Erreur lors de l\'enregistrement de l\'écran"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Erreur lors du démarrage de l\'enregistrement de l\'écran"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Retour"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Accueil"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Visage authentifié"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmé"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Appuyez sur \"Confirmer\" pour terminer"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Déverrouillage par visage. Appuyez sur l\'icône de déverrouillage pour continuer."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Déverrouillé par visage. Appuyez pour continuer."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Visage reconnu. Appuyez pour continuer."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Visage reconnu. Appuyez sur l\'icône de déverrouillage pour continuer."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"désactiver"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Son et vibreur"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Paramètres"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Volume réduit à un niveau plus sûr"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"La période pendant laquelle le volume est resté élevé est supérieure à celle recommandée"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume réduit à un niveau plus sûr"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Le volume du casque est élevé depuis plus longtemps que recommandé"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Le volume du casque a dépassé la limite de sécurité pour cette semaine"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Continuer d\'écouter"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Réduire le volume"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"L\'application est épinglée"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Elle restera visible jusqu\'à ce que vous la retiriez. Pour la retirer, appuyez de manière prolongée sur les boutons Retour et Récents."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Elle restera visible jusqu\'à ce que vous la retiriez. Pour la retirer, appuyez de manière prolongée sur les boutons Retour et Accueil."</string>
@@ -812,7 +816,7 @@
     <string name="auto_data_switch_disable_title" msgid="5146527155665190652">"Rebasculer sur <xliff:g id="CARRIER">%s</xliff:g> ?"</string>
     <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Il n\'y aura pas de basculement automatique entre les données mobile selon la disponibilité"</string>
     <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"Non, merci"</string>
-    <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Oui, revenir"</string>
+    <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Oui, rebasculer"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"L\'application Paramètres ne peut pas valider votre réponse, car une application masque la demande d\'autorisation."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"Autoriser <xliff:g id="APP_0">%1$s</xliff:g> à afficher des éléments de <xliff:g id="APP_2">%2$s</xliff:g> ?"</string>
     <string name="slice_permission_text_1" msgid="6675965177075443714">"- Accès aux informations de <xliff:g id="APP">%1$s</xliff:g>"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> est en cours de lecture depuis <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> sur <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> est en cours d\'exécution"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Lecture"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pause"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Titre précédent"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Enceintes et écrans"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Appareils suggérés"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Arrêter votre session partagée pour déplacer des contenus multimédias vers un autre appareil"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Arrêter"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Fonctionnement des annonces"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Annonce"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les personnes à proximité équipées d\'appareils Bluetooth compatibles peuvent écouter le contenu multimédia que vous diffusez"</string>
@@ -1064,7 +1067,7 @@
     <string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"Recherche de réseaux…"</string>
     <string name="wifi_failed_connect_message" msgid="4161863112079000071">"Échec de la connexion au réseau"</string>
     <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Connexion automatique au Wi-Fi désactivée pour le moment"</string>
-    <string name="see_all_networks" msgid="3773666844913168122">"Tout afficher"</string>
+    <string name="see_all_networks" msgid="3773666844913168122">"Tout voir"</string>
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Pour changer de réseau, déconnectez l\'Ethernet"</string>
     <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Pour améliorer l\'expérience sur l\'appareil, les applis et les services peuvent continuer de rechercher les réseaux Wi-Fi, même si le Wi-Fi est désactivé. Vous pouvez modifier cela dans les paramètres de recherche Wi-Fi. "<annotation id="link">"Modifier"</annotation></string>
     <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Désactiver le mode Avion"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connectez votre stylet à un chargeur"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"La batterie du stylet est faible"</string>
     <string name="video_camera" msgid="7654002575156149298">"Caméra"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Impossible d\'appeler depuis ce profil"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Votre règle professionnelle ne vous permet de passer des appels que depuis le profil professionnel"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Impossible d\'appeler depuis une appli personnelle"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Votre organisation ne vous autorise à passer des appels que depuis des applis professionnelles"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Passer au profil professionnel"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fermer"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installer une appli professionnelle pour téléphoner"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Annuler"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personnaliser écran verrouillage"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Déverrouiller pour personnaliser l\'écran de verrouillage"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi non disponible"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index b3b8a98..fc3d033 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Compartir"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Gravación da pantalla gardada"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Toca para ver o contido"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Produciuse un erro ao eliminar a gravación de pantalla"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Produciuse un erro ao gardar a gravación da pantalla"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Produciuse un erro ao iniciar a gravación da pantalla"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Volver"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Inicio"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Autenticouse a cara"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toca Confirmar para completar o proceso"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Usouse o desbloqueo facial. Preme a icona de desbloquear."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Usouse o desbloqueo facial. Preme para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Recoñeceuse a cara. Preme para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Recoñeceuse a cara. Preme a icona de desbloquear."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"desactiva"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Son e vibración"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Configuración"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"O volume baixouse a un nivel máis seguro"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"O volume estivo a un nivel alto durante máis tempo do recomendado"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"O volume baixouse ata un nivel máis seguro"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Usaches os auriculares cun volume alto durante máis tempo do recomendado"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"O volume dos auriculares superou o límite de seguranza desta semana"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Seguir escoitando"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Baixar volume"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"A aplicación está fixada"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"A pantalla manterase visible ata que deixes de fixala. Para facelo, mantén premido Atrás e Visión xeral."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"A pantalla manterase visible ata que deixes de fixala. Para facelo, mantén premido Atrás e Inicio."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Estase reproducindo <xliff:g id="SONG_NAME">%1$s</xliff:g>, de <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> estase executando"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Reproducir"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pór en pausa"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Pista anterior"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Altofalantes e pantallas"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos suxeridos"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Detén a sesión de uso compartido para mover contido multimedia a outro dispositivo"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Deter"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funcionan as difusións?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Difusión"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As persoas que estean preto de ti e que dispoñan de dispositivos Bluetooth compatibles poden escoitar o contido multimedia que difundas"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conecta o lapis óptico a un cargador"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"O lapis óptico ten pouca batería"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videocámara"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Non se pode chamar desde este perfil"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"A política do teu traballo só che permite facer chamadas de teléfono desde o perfil de traballo"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Non se pode chamar desde aplicacións persoais"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"A túa organización só che permite chamar desde aplicacións do traballo"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Cambiar ao perfil de traballo"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Pechar"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalar unha aplicación para teléfonos do traballo"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Cancelar"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizar pantalla de bloqueo"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Para personalizar a pantalla de bloqueo, primeiro desbloquea o dispositivo"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi non dispoñible"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index f3b2648..c5b3d2e4 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"શેર કરો"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"સ્ક્રીન રેકોર્ડિંગ સાચવ્યું"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"જોવા માટે ટૅપ કરો"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"સ્ક્રીન રેકોર્ડિંગ ડિલીટ કરવામાં ભૂલ આવી"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"સ્ક્રીન રેકોર્ડિંગ સાચવવામાં ભૂલ આવી"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"સ્ક્રીનને રેકૉર્ડ કરવાનું શરૂ કરવામાં ભૂલ"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"પાછળ"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"હોમ"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ચહેરાનું પ્રમાણીકરણ થયું"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"પુષ્ટિ કરી"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"પરીક્ષણ પૂર્ણ કરવા કન્ફર્મ કરોને ટૅપ કરો"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ચહેરા દ્વારા અનલૉક કર્યું. આગળ વધવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ચહેરા દ્વારા અનલૉક કર્યું. આગળ વધવા માટે દબાવો."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ચહેરો ઓળખ્યો. આગળ વધવા માટે દબાવો."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ચહેરો ઓળખ્યો. આગળ વધવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"બંધ કરો"</string>
     <string name="sound_settings" msgid="8874581353127418308">"સાઉન્ડ અને વાઇબ્રેશન"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"સેટિંગ"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"વૉલ્યૂમ ઘટાડીને સલામત વૉલ્યૂમ જેટલું કર્યું"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"સુઝાવ આપેલા સમય કરતાં વધુ સમય સુધી વૉલ્યૂમ વધારે રહ્યું છે"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"વૉલ્યૂમને વધુ સલામત લેવલ સુધી ઘટાડ્યું"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"હૅડફોનનું વૉલ્યૂમ સુઝાવ આપેલા સમય કરતાં વધારે સમય સુધી ઊંચા વૉલ્યૂમ પર રહ્યું છે"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"હૅડફોનનું વૉલ્યૂમ આ અઠવાડિયા માટેની સુરક્ષિત મર્યાદા કરતાં વધારે છે"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"સાંભળવાનું ચાલુ રાખો"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"વૉલ્યૂમ ઘટાડો"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"ઍપને પિન કરેલી છે"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"તમે જ્યાં સુધી અનપિન કરશો નહીં ત્યાં સુધી આ તેને વ્યૂમાં રાખે છે. અનપિન કરવા માટે પાછળ અને ઓવરવ્યૂને સ્પર્શ કરી રાખો."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"તમે જ્યાં સુધી અનપિન કરશો નહીં ત્યાં સુધી આ તેને વ્યૂમાં રાખે છે. અનપિન કરવા માટે પાછળ અને હોમને સ્પર્શ કરી રાખો."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"સેટિંગ"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> પર <xliff:g id="ARTIST_NAME">%2$s</xliff:g>નું <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચાલી રહ્યું છે"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>માંથી <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ચાલી રહી છે"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"ચલાવો"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"થોભાવો"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"પહેલાનો ટ્રૅક"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"સ્પીકર અને ડિસ્પ્લે"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"સૂચવેલા ડિવાઇસ"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"મીડિયાને બીજા ડિવાઇસ પર ખસેડવા માટે તમારું શેર કરેલું સત્ર રોકો"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"રોકો"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"બ્રોડકાસ્ટ પ્રક્રિયાની કામ કરવાની રીત"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"બ્રોડકાસ્ટ કરો"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"સુસંગત બ્લૂટૂથ ડિવાઇસ ધરાવતા નજીકના લોકો તમે જે મીડિયા બ્રોડકાસ્ટ કરી રહ્યાં છો તે સાંભળી શકે છે"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"તમારા સ્ટાઇલસને ચાર્જર સાથે કનેક્ટ કરો"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"સ્ટાઇલસની બૅટરીમાં ચાર્જ ઓછો છે"</string>
     <string name="video_camera" msgid="7654002575156149298">"વીડિયો કૅમેરા"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"આ પ્રોફાઇલ પરથી કૉલ કરી શકતા નથી"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"તમારી ઑફિસની પૉલિસી તમને માત્ર ઑફિસની પ્રોફાઇલ પરથી જ ફોન કૉલ કરવાની મંજૂરી આપે છે"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"કોઈ વ્યક્તિગત ઍપ પરથી કૉલ કરી શકાશે નહીં"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"તમારી સંસ્થા તમને માત્ર ઑફિસ માટેની ઍપ પરથી કૉલ કરવાની મંજૂરી આપે છે"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ઑફિસની પ્રોફાઇલ પર સ્વિચ કરો"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"બંધ કરો"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ઑફિસ માટેની કોઈ ફોન ઍપ ઇન્સ્ટૉલ કરો"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"રદ કરો"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"લૉક સ્ક્રીન કસ્ટમાઇઝ કરો"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"લૉક સ્ક્રીનને કસ્ટમાઇઝ કરવા માટે અનલૉક કરો"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"વાઇ-ફાઇ ઉપલબ્ધ નથી"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index a74716e..fb4de70 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -111,12 +111,12 @@
     <string name="screenrecord_continue" msgid="4055347133700593164">"शुरू करें"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"स्क्रीन को रिकॉर्ड किया जा रहा है"</string>
     <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"स्क्रीन और ऑडियो, दोनों रिकॉर्ड हो रहे हैं"</string>
-    <string name="screenrecord_taps_label" msgid="1595690528298857649">"स्क्रीन को कहां छुआ गया, ये दिखाएं"</string>
+    <string name="screenrecord_taps_label" msgid="1595690528298857649">"स्क्रीन को कहां-कहां छुआ गया, यह दिखाएं"</string>
     <string name="screenrecord_stop_label" msgid="72699670052087989">"रोकें"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"शेयर करें"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"स्क्रीन रिकॉर्डिंग सेव की गई"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"देखने के लिए टैप करें"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रीन रिकॉर्डिंग मिटाने में गड़बड़ी हुई"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"स्क्रीन रिकॉर्डिंग सेव करते समय गड़बड़ी हुई"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन को रिकॉर्ड करने में गड़बड़ी आ रही है"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"वापस जाएं"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"होम"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"चेहरे की पुष्टि हो गई"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"पुष्टि हो गई"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"\'पुष्टि करें\' पर टैप करके पूरा करें"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"चेहरे से अनलॉक किया. जारी रखने के लिए, अनलॉक आइकॉन को दबाएं."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहरे से अनलॉक किया गया. जारी रखने के लिए टैप करें."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरे की पहचान हो गई. जारी रखने के लिए टैप करें."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरे की पहचान हो गई. जारी रखने के लिए अनलॉक आइकॉन को टैप करें."</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"इस डिवाइस पर एक प्रमाणपत्र अनुमति इंस्टॉल की है. आपके सुरक्षित नेटवर्क ट्रैफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"आपके व्यवस्थापक ने नेटवर्क लॉगिंग चालू किया है, जो आपके डिवाइस पर ट्रैफ़िक की निगरानी करता है."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"आपके एडमिन ने नेटवर्क लॉगिंग की सुविधा चालू कर दी है. इससे आपकी वर्क प्रोफ़ाइल पर आने वाले ट्रैफ़िक की निगरानी की जाती है. हालांकि, इससे आपकी निजी प्रोफ़ाइल की निगरानी नहीं की जाती."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"इस डिवाइस को <xliff:g id="VPN_APP">%1$s</xliff:g> के ज़रिए इंटरनेट से कनेक्ट किया गया है. नेटवर्क पर की गई गतिविधि से जुड़ी जानकारी, वीपीएन सेवा देने वाली कंपनी को दिखती है. इस जानकारी में ईमेल और ब्राउज़िंग डेटा शामिल हैं."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"इस डिवाइस को <xliff:g id="VPN_APP">%1$s</xliff:g> के ज़रिए इंटरनेट से कनेक्ट किया गया है. नेटवर्क पर की जाने वाली आपकी गतिविधि, वीपीएन सेवा देने वाली कंपनी को दिखती है. इस जानकारी में ईमेल और ब्राउज़िंग डेटा शामिल हैं."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"इस डिवाइस को <xliff:g id="VPN_APP">%1$s</xliff:g> के ज़रिए इंटरनेट से कनेक्ट किया गया है. नेटवर्क पर की गई गतिविधि से जुड़ी जानकारी, आपके आईटी एडमिन को दिखती है. इस जानकारी में ईमेल और ब्राउज़िंग डेटा शामिल हैं."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"इस डिवाइस को <xliff:g id="VPN_APP_0">%1$s</xliff:g> और <xliff:g id="VPN_APP_1">%2$s</xliff:g> के ज़रिए इंटरनेट से कनेक्ट किया गया है. नेटवर्क पर की गई गतिविधि से जुड़ी जानकारी, आपके आईटी एडमिन को दिखती है. इस जानकारी में, ईमेल और ब्राउज़िंग डेटा शामिल है."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"ऑफ़िस के काम से जुड़े ऐप्लिकेशन, <xliff:g id="VPN_APP">%1$s</xliff:g> के ज़रिए इंटरनेट से कनेक्ट किए गए हैं. ऑफ़िस के काम से जुड़े ऐप्लिकेशन में, नेटवर्क पर की गई गतिविधि से जुड़ी जानकारी आपके आईटी एडमिन और वीपीएन सेवा देने वाले को दिखती है. इस जानकारी में, ईमेल और ब्राउज़िंग डेटा शामिल है."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"बंद करें"</string>
     <string name="sound_settings" msgid="8874581353127418308">"आवाज़ और वाइब्रेशन"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"सेटिंग"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"बेहतर ऑडियो के लिए वॉल्यूम का लेवल कम किया गया"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"सुझाए गए समय से ज़्यादा देर तक वॉल्यूम का लेवल ज़्यादा रहा है"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"आवाज़ को कम करके, सुरक्षित लेवल पर सेट कर दिया गया है"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"हेडफ़ोन की आवाज़ सुझाए गए समय के बाद भी ज़्यादा रही"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"इस हफ़्ते के लिए हेडफ़ोन की आवाज़, सुझाई गई सीमा से ज़्यादा हो गई है"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"सुनना जारी रखें"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"आवाज़ कम करें"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"ऐप्लिकेशन पिन किया गया है"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"इससे वह तब तक दिखता रहता है, जब तक कि आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, \'वापस जाएं\' और \'खास जानकारी\' को दबाकर रखें."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"इससे वह तब तक दिखाई देती है जब तक आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, होम और वापस जाएं वाले बटन को दबाकर रखें."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> पर, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> का <xliff:g id="SONG_NAME">%1$s</xliff:g> चल रहा है"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> में से <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> चालू है"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"चलाएं"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"रोकें"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"पिछला ट्रैक"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"अपने स्टाइलस को चार्ज करें"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"स्टाइलस की बैटरी कम है"</string>
     <string name="video_camera" msgid="7654002575156149298">"वीडियो कैमरा"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"यह प्रोफ़ाइल होने पर कॉल नहीं की जा सकती"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"ऑफ़िस की नीति के तहत, वर्क प्रोफ़ाइल होने पर ही फ़ोन कॉल किए जा सकते हैं"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"निजी ऐप्लिकेशन से कॉल नहीं की जा सकती"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"आपके संगठन ने, सिर्फ़ वर्क ऐप्लिकेशन से कॉल करने की अनुमति दी है"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"वर्क प्रोफ़ाइल पर स्विच करें"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"बंद करें"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"वर्क प्रोफ़ाइल वाला फ़ोन ऐप्लिकेशन इंस्टॉल करें"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"रद्द करें"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"लॉक स्क्रीन को कस्टमाइज़ करें"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"लॉक स्क्रीन को पसंद के मुताबिक बनाने के लिए अनलॉक करें"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"वाई-फ़ाई उपलब्ध नहीं है"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 0f7960b..9cb3fe8 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -53,7 +53,7 @@
     <string name="usb_debugging_allow" msgid="1722643858015321328">"Dopusti"</string>
     <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Otklanjanje pogrešaka putem USB-a nije dopušteno"</string>
     <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"Korisnik koji je trenutačno prijavljen na ovaj uređaj ne može uključiti otklanjanje pogrešaka putem USB-a. Da biste upotrebljavali tu značajku, prijeđite na korisnika s administratorskim pravima."</string>
-    <string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Želite li promijeniti jezik sustava u <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
+    <string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"Želite li jezik sustava promijeniti na <xliff:g id="LANGUAGE">%1$s</xliff:g>?"</string>
     <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Drugi uređaj zatražio je promjenu jezika sustava"</string>
     <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Promijeni jezik"</string>
     <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Zadrži trenutačni jezik"</string>
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Dijeli"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Snimanje zaslona spremljeno"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Dodirnite za prikaz"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Pogreška prilikom brisanja snimanja zaslona"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Pogreška prilikom spremanja snimke zaslona"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Pogreška prilikom pokretanja snimanja zaslona"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Natrag"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Početna"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Lice je autentificirano"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrđeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Dodirnite Potvrdi za dovršetak"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Otključano pomoću lica. Pritisnite ikonu otključavanja da biste nastavili."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano pomoću lica. Pritisnite da biste nastavili."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice je prepoznato. Pritisnite da biste nastavili."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice je prepoznato. Pritisnite ikonu otključavanja da biste nastavili."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"onemogući"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Zvuk i vibracija"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Postavke"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Stišano na sigurniju glasnoću"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Zvuk je bio glasan duže nego što se preporučuje"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Glasnoća je stišana na sigurniju razinu"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Pojačana je glasnoća u slušalicama dulje nego što se preporučuje"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Glasnoća slušalica premašila je sigurno ograničenje za ovaj tjedan"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Nastavite slušati"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Stišaj"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Aplikacija je prikvačena"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Zaslon će tako ostati u prvom planu dok ga ne otkvačite. Dodirnite i zadržite Natrag i Pregled da biste ga otkvačili."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Zaslon će tako ostati u prvom planu dok ga ne otkvačite. Dodirnite gumbe Natrag i Početna i zadržite pritisak da biste ga otkvačili."</string>
@@ -919,7 +923,7 @@
     <string name="controls_dialog_message" msgid="342066938390663844">"Preporuka s kanala <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="controls_tile_locked" msgid="731547768182831938">"Uređaj je zaključan"</string>
     <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Prikazati uređaje i omogućiti upravljanje njima na zaključanom zaslonu?"</string>
-    <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Na zaključan zaslon možete dodati kontrole za svoje vanjske uređaje.\n\nAplikacija vašeg uređaja može vam dopustiti upravljanje nekim uređajima bez otključavanja telefona ili tableta.\n\nPromjene uvijek možete unijeti u Postavkama."</string>
+    <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Na zaključani zaslon možete dodati kontrole za svoje vanjske uređaje.\n\nAplikacija vašeg uređaja može vam dopustiti upravljanje nekim uređajima bez otključavanja telefona ili tableta.\n\nPromjene uvijek možete unijeti u Postavkama."</string>
     <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Upravljati uređajima na zaključanom zaslonu?"</string>
     <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Nekim uređajima možete upravljati bez otključavanja telefona ili tableta. Aplikacija vašeg uređaja odlučuje kojim se uređajima može upravljati na taj način."</string>
     <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ne, hvala"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> reproducira se putem aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je pokrenuta"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Reproduciraj"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pauziraj"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Prethodni zapis"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvučnici i zasloni"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predloženi uređaji"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Zaustavite dijeljenu sesiju da biste premjestili medij na drugi uređaj"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Zaustavi"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako emitiranje funkcionira"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Emitiranje"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osobe u blizini s kompatibilnim Bluetooth uređajima mogu slušati medije koje emitirate"</string>
@@ -1054,7 +1057,7 @@
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Povezano"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Privremeno povezano"</string>
     <string name="mobile_data_poor_connection" msgid="819617772268371434">"Slaba veza"</string>
-    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Mobilna veza neće se automatski uspostaviti"</string>
+    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Mobilni podaci neće se automatski prenositi"</string>
     <string name="mobile_data_no_connection" msgid="1713872434869947377">"Niste povezani"</string>
     <string name="non_carrier_network_unavailable" msgid="770049357024492372">"Nije dostupna nijedna druga mreža"</string>
     <string name="all_network_unavailable" msgid="4112774339909373349">"Nema dostupnih mreža"</string>
@@ -1141,12 +1144,13 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Priključite pisaljku na punjač"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Slaba baterija pisaljke"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Nije moguće uspostavljati pozive s ovog profila"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Vaša pravila za poslovne uređaje omogućuju vam upućivanje poziva samo s poslovnog profila"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Ne možete upućivati pozive iz osobne aplikacije"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Vaša organizacija dopušta upućivanje poziva samo iz poslovnih aplikacija"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Prijeđite na poslovni profil"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instaliraj poslovnu aplikaciju telefona"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Odustani"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Prilagodi zaključavanje zaslona"</string>
-    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Otključajte da biste prilagodili zaključan zaslon"</string>
+    <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Otključajte da biste prilagodili zaključani zaslon"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi nije dostupan"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera je blokirana"</string>
     <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Blokirani su kamera i mikrofon"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index c48f88a..36e4cd2 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Megosztás"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Képernyőfelvétel elmentve"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Koppintson a megtekintéshez"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Hiba történt a képernyőről készült felvétel törlésekor"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Hiba történt a képernyőrögzítés mentése során"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Hiba a képernyőrögzítés indításakor"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Vissza"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Főoldal"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Arc hitelesítve"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Megerősítve"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Koppintson a Megerősítés lehetőségre"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Arccal feloldva. A folytatáshoz nyomja meg a feloldás ikont."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Zárolás arccal feloldva. Koppintson a folytatáshoz."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Arc felismerve. Koppintson a folytatáshoz."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Arc felismerve. A folytatáshoz koppintson a Feloldásra."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"letiltás"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Hang és rezgés"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Beállítások"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Hangerő csökkentve a biztonság érdekében"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"A hangerő az ajánlottnál hosszabb ideig volt nagy"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Hangerő biztonságos szintre csökkentve"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"A fejhallgató hangereje az ajánlottnál hosszabb ideig volt nagy"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"A fejhallgató hangereje túllépte a biztonságos határt a hétre vonatkozóan"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Hangerő megtartása"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Hangerő csökkentése"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Az alkalmazás ki van tűzve"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Megjelenítve tartja addig, amíg Ön fel nem oldja a rögzítést. A feloldáshoz tartsa lenyomva a Vissza és az Áttekintés lehetőséget."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Megjelenítve tartja addig, amíg Ön fel nem oldja a rögzítést. A feloldáshoz tartsa lenyomva a Vissza és a Kezdőképernyő elemet."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Beállítások"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> <xliff:g id="SONG_NAME">%1$s</xliff:g> című száma hallható itt: <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>/<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> jelenleg fut"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Lejátszás"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Szünet"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Előző szám"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Hangfalak és kijelzők"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Javasolt eszközök"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Állítsa le a megosztott munkamenetet, ha át szeretné helyezni a médiát egy másik eszközre"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Leállítás"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"A közvetítés működése"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Közvetítés"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"A közelben tartózkodó, kompatibilis Bluetooth-eszközzel rendelkező személyek meghallgathatják az Ön közvetített médiatartalmait"</string>
@@ -1064,7 +1067,7 @@
     <string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"Hálózatok keresése…"</string>
     <string name="wifi_failed_connect_message" msgid="4161863112079000071">"Nem sikerült hálózathoz csatlakozni."</string>
     <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"A Wi-Fi-re történő csatlakozás jelenleg nem automatikus"</string>
-    <string name="see_all_networks" msgid="3773666844913168122">"Megtekintés"</string>
+    <string name="see_all_networks" msgid="3773666844913168122">"Összes megtekintése"</string>
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Hálózatváltáshoz válassza le az ethernetet"</string>
     <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Az eszközhasználati élmény javítása érdekében az alkalmazások és a szolgáltatások továbbra is bármikor kereshetnek Wi-Fi-hálózatokat, még akkor is, ha a Wi-Fi ki van kapcsolva. A funkciót a Wi-Fi-keresési beállításoknál módosíthatja. "<annotation id="link">"Módosítás"</annotation></string>
     <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Repülős üzemmód kikapcsolása"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Tegye töltőre az érintőceruzát"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Az érintőceruza töltöttsége alacsony"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Nem lehet hívást kezdeményezni ebből a profilból"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"A munkahelyi házirend csak munkaprofilból kezdeményezett telefonhívásokat engedélyez"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Személyes alkalmazásokból nem lehet hívást indítani"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Szervezete csak munkahelyi alkalmazásokból engedélyezi a hívásindítást"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Váltás munkaprofilra"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Bezárás"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Munkahelyi telefonalkalmazás telepítése"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Mégse"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Lezárási képernyő testreszabása"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Oldja fel a zárolást a lezárási képernyő testreszabásához"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Nem áll rendelkezésre Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 712dc16..57b3033 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Կիսվել"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Էկրանի տեսագրությունը պահվեց"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Հպեք՝ դիտելու համար"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Չհաջողվեց ջնջել տեսագրությունը"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Չհաջողվեց պահել էկրանի տեսագրությունը"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Չհաջողվեց սկսել տեսագրումը"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Հետ"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Տուն"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Դեմքը ճանաչվեց"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Հաստատվեց"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ավարտելու համար հպեք «Հաստատել»"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ապակողպվել է դեմքով։ Սեղմեք ապակողպման պատկերակը։"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ապակողպվել է դեմքով։ Սեղմեք շարունակելու համար։"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Դեմքը ճանաչվեց։ Սեղմեք շարունակելու համար։"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Դեմքը ճանաչվեց։ Սեղմեք ապակողպման պատկերակը։"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"անջատել"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Ձայն և թրթռոց"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Կարգավորումներ"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Ձայնն իջեցվեց անվտանգ մակարդակի"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Ձայնը բարձր է եղել առաջարկված ժամանակահատվածից ավելի երկար"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Ձայնն իջեցվեց անվտանգ մակարդակի"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Ձայնը բարձր է եղել առաջարկված ժամանակահատվածից ավելի երկար"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Ականջակալների ձայնի ուժգնությունը այս շաբաթ գերազանցել է անվտանգ մակարդակի շեմը"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Շարունակել լսել"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Ցածրացնել ձայնը"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Հավելվածն ամրացված է"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Էկրանը կմնա տեսադաշտում, մինչև այն ապամրացնեք: Ապամրացնելու համար հպեք և պահեք Հետ և Համատեսք կոճակները:"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Էկրանը կցուցադրվի այնքան ժամանակ, մինչև չեղարկեք ամրացումը: Չեղարկելու համար հպեք և պահեք «Հետ» և «Գլխավոր էկրան» կոճակները"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Կարգավորումներ"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Այժմ նվագարկվում է <xliff:g id="SONG_NAME">%1$s</xliff:g> երգը <xliff:g id="ARTIST_NAME">%2$s</xliff:g>-ի կատարմամբ <xliff:g id="APP_LABEL">%3$s</xliff:g> հավելվածից"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>՝ <xliff:g id="TOTAL_TIME">%2$s</xliff:g>-ից"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածն աշխատում է"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Նվագարկել"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Դադարեցնել"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Նախորդ կատարումը"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Բարձրախոսներ և էկրաններ"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Առաջարկվող սարքեր"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Կանգնեցրեք ընդհանուր աշխատաշրջանը՝ մուլտիմեդիա բովանդակությունն այլ սարք տեղափոխելու համար"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Կանգնեցնել"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Ինչպես է աշխատում հեռարձակումը"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Հեռարձակում"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ձեր մոտակայքում գտնվող՝ համատեղելի Bluetooth սարքերով մարդիկ կարող են լսել մեդիա ֆայլերը, որոնք դուք հեռարձակում եք։"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Ձեր ստիլուսը միացրեք լիցքավորիչի"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Ստիլուսի մարտկոցի լիցքի ցածր մակարդակ"</string>
     <string name="video_camera" msgid="7654002575156149298">"Տեսախցիկ"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Հնարավոր չէ զանգել այս պրոֆիլից"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Ձեր աշխատանքային կանոնների համաձայն՝ դուք կարող եք զանգեր կատարել աշխատանքային պրոֆիլից"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Հնարավոր չէ զանգել անձնական հավելվածից"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Ձեր կազմակերպությունը թույլատրում է ձեզ զանգեր կատարել միայն աշխատանքային հավելվածներից"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Անցնել աշխատանքային պրոֆիլ"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Փակել"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Տեղադրել հեռախոսի աշխատանքային հավելված"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Չեղարկել"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Անհատականացնել կողպէկրանը"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Ապակողպեք սարքը՝ կողպէկրանը կարգավորելու համար"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi ցանց հասանելի չէ"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index a0641fb..4ece767 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Bagikan"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Perekaman layar disimpan"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Ketuk untuk melihat"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error saat menghapus rekaman layar"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Terjadi error saat menyimpan rekaman layar"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Terjadi error saat memulai perekaman layar"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Kembali"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Utama"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Wajah diautentikasi"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Dikonfirmasi"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ketuk Konfirmasi untuk menyelesaikan"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Kunci dibuka dengan wajah. Tekan ikon buka kunci untuk melanjutkan."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Kunci dibuka dengan wajah. Tekan untuk melanjutkan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Wajah dikenali. Tekan untuk melanjutkan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Wajah dikenali. Tekan ikon buka kunci untuk melanjutkan."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"nonaktifkan"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Suara &amp; getaran"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Setelan"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Diturunkan ke volume yang lebih aman"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Volume tinggi selama lebih lama dari yang direkomendasikan"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume diturunkan ke level yang lebih aman"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Volume headphone tinggi selama lebih lama dari yang direkomendasikan"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Volume headphone telah melampaui batas aman untuk minggu ini"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Terus dengarkan"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Turunkan volume"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Aplikasi disematkan"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Ini akan terus ditampilkan sampai Anda melepas sematan. Sentuh lama tombol Kembali dan Ringkasan untuk melepas sematan."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Ini akan terus ditampilkan sampai Anda melepas sematan. Sentuh lama tombol Kembali dan Beranda untuk melepas sematan."</string>
@@ -907,7 +911,7 @@
     <string name="controls_favorite_removed" msgid="5276978408529217272">"Semua kontrol dihapus"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Perubahan tidak disimpan"</string>
     <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Lihat aplikasi lainnya"</string>
-    <string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Atur ulang"</string>
+    <string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Tata ulang"</string>
     <string name="controls_favorite_add_controls" msgid="1221420435546694004">"Tambahkan kontrol"</string>
     <string name="controls_favorite_back_to_editing" msgid="184125114090062713">"Kembali mengedit"</string>
     <string name="controls_favorite_load_error" msgid="5126216176144877419">"Kontrol tidak dapat dimuat. Periksa aplikasi <xliff:g id="APP">%s</xliff:g> untuk memastikan setelan aplikasi tidak berubah."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Setelan"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> sedang diputar dari <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> dari <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang berjalan"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Putar"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Jeda"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Lagu sebelumnya"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speaker &amp; Layar"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Perangkat yang Disarankan"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Menghentikan sesi berbagi Anda untuk memindahkan media ke perangkat lain"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Berhenti"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cara kerja siaran"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Siaran"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Orang di dekat Anda dengan perangkat Bluetooth yang kompatibel dapat mendengarkan media yang sedang Anda siarkan"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Hubungkan stilus ke pengisi daya"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Baterai stilus lemah"</string>
     <string name="video_camera" msgid="7654002575156149298">"Kamera video"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Tidak dapat melakukan panggilan dari profil ini"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Kebijakan kantor mengizinkan Anda melakukan panggilan telepon hanya dari profil kerja"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Tidak dapat menelepon dari aplikasi pribadi"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Organisasi Anda hanya mengizinkan menelepon dari aplikasi kerja"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Beralih ke profil kerja"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tutup"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instal aplikasi telepon kerja"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Batalkan"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Sesuaikan layar kunci"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Buka kunci untuk menyesuaikan layar kunci"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi tidak tersedia"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index fbd34f7..29494ff 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Deila"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Skjáupptaka vistuð"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Ýttu til að skoða"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Villa við að eyða skjáupptöku"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Villa við að vista skjáupptöku"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Villa við að hefja upptöku skjás"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Til baka"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Heim"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Andlit staðfest"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Staðfest"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ýttu á „Staðfesta“ til að ljúka"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Opnað með andliti. Ýttu á táknið taka úr lás til að halda áfram."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Opnað með andliti. Ýttu til að halda áfram."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Andlitið var greint. Ýttu til að halda áfram."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Andlitið var greint. Ýttu á opnunartáknið til að halda áfr."</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"CA-vottorð er uppsett á þessu tæki. Eftirlit kann að vera haft með öruggri netnotkun þinni eða henni kann að vera breytt."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Kerfisstjóri hefur kveikt á eftirliti netkerfa, sem fylgist með netumferð á tækinu þínu."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Stjórnandinn kveikti á eftirliti netkerfa sem fylgist með netumferð á vinnusniðinu þínu en ekki á eigin sniði."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Þetta tæki er nettengt í gegnum <xliff:g id="VPN_APP">%1$s</xliff:g>. VPN-þjónustuaðilinn getur séð netvirkni þína í vinnuforritum, þar á meðal tölvupóst og vefskoðunargögn."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Þetta tæki er nettengt í gegnum <xliff:g id="VPN_APP">%1$s</xliff:g>. VPN-þjónustuaðilinn getur séð netvirkni þína, þar á meðal tölvupóst og vefskoðunargögn."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"Þetta tæki er nettengt í gegnum <xliff:g id="VPN_APP">%1$s</xliff:g>. Kerfisstjórinn þinn getur séð netvirkni þína í vinnuforritum, þar á meðal tölvupóst og vefskoðunargögn."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Þetta tæki er nettengt í gegnum <xliff:g id="VPN_APP_0">%1$s</xliff:g> og <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Kerfisstjórinn þinn getur séð netvirkni þína í vinnuforritum, þar á meðal tölvupósta og vefskoðunargögn."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vinnuforritin þín eru nettengd í gegnum <xliff:g id="VPN_APP">%1$s</xliff:g>. Kerfisstjórinn þinn og VPN-þjónustuaðilinn geta séð netvirkni þína í vinnuforritum, þar á meðal tölvupósta og vefskoðunargögn."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"slökkva"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Hljóð og titringur"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Stillingar"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Lækkað í öruggari hljóðstyrk"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Hljóðstyrkurinn hefur verið hár í lengri tíma en mælt er með"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Hljóð lækkað í öruggari hljóðstyrk"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Hljóðstyrkur í heyrnartólum hefur verið hár í lengri tíma en mælt er með"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Hljóðstyrkur í heyrnartólum hefur náð öryggismörkum fyrir þessa viku"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Halda áfram að hlusta"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Lækka hljóð"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Forrit er fest"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Þetta heldur þessu opnu þangað til þú losar það. Haltu fingri á „Til baka“ og „Yfirlit“ til að losa."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Þetta heldur þessu opnu þangað til það er losað. Haltu inni bakkhnappinum og heimahnappinum til að losa."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Stillingar"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> með <xliff:g id="ARTIST_NAME">%2$s</xliff:g> er í spilun á <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> af <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> er í gangi"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Spila"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Gera hlé"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Fyrra lag"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Hátalarar og skjáir"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Tillögur að tækjum"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Stöðvaðu sameiginlega lotu til að flytja efni yfir í annað tæki"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Stöðva"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Svona virkar útsending"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Útsending"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Fólk nálægt þér með samhæf Bluetooth-tæki getur hlustað á efnið sem þú sendir út"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Tengdu pennann við hleðslutæki"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Rafhlaða pennans er að tæmast"</string>
     <string name="video_camera" msgid="7654002575156149298">"Kvikmyndatökuvél"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Ekki er hægt að hringja úr þessu sniði"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Vinnureglur gera þér aðeins kleift að hringja símtöl úr vinnusniði"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Ekki er hægt að hringja úr forriti til einkanota"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Fyrirtækið heimilar þér aðeins að hringja úr vinnuforritum"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skipta yfir í vinnusnið"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Loka"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Setja upp símaforrit fyrir vinnu"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Hætta við"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Sérsníða lásskjá"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Taktu úr lás til að sérsníða lásskjá"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi er ekki til staðar"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 4b0f89f..f9b329e 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Condividi"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Registrazione schermo salvata"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Tocca per visualizzare"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Errore durante l\'eliminazione della registrazione dello schermo"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Errore durante il salvataggio della registrazione dello schermo"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Errore durante l\'avvio della registrazione dello schermo"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Indietro"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Volto autenticato"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confermato"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tocca Conferma per completare"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Sbloccato con il volto. Premi l\'icona Sblocca e continua."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Sbloccato con il volto. Premi per continuare."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Volto riconosciuto. Premi per continuare."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Volto riconosciuto. Premi l\'icona Sblocca e continua."</string>
@@ -306,7 +307,7 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC non attiva"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC attiva"</string>
-    <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Registrazione dello schermo"</string>
+    <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Registrazione schermo"</string>
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Inizia"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Interrompi"</string>
     <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Modalità a una mano"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"disattiva"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Suoni e vibrazione"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Impostazioni"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Audio abbassato a un volume più sicuro"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Il volume è alto da più tempo di quanto consigliato"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume abbassato a un livello più sicuro"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Il volume delle cuffie è rimasto alto per un periodo superiore a quello consigliato"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Il volume delle cuffie ha superato il limite di sicurezza per questa settimana"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Continua ad ascoltare"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Abbassa il volume"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"L\'app è bloccata sullo schermo"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"La schermata rimane visibile finché non viene sganciata. Per sganciarla, tieni premuto Indietro e Panoramica."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"La schermata rimane visibile finché non viene disattivato il blocco su schermo. Per disattivarlo, tocca e tieni premuto Indietro e Home."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Impostazioni"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> di <xliff:g id="ARTIST_NAME">%2$s</xliff:g> è in riproduzione da <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> di <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> è in esecuzione"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Riproduci"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Metti in pausa"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Traccia precedente"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speaker e display"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivi consigliati"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Interrompi la sessione condivisa per spostare i contenuti multimediali su un altro dispositivo"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Interrompi"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Come funziona la trasmissione"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Annuncio"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Le persone vicine a te che hanno dispositivi Bluetooth compatibili possono ascoltare i contenuti multimediali che stai trasmettendo"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connetti lo stilo a un caricabatterie"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Batteria stilo in esaurimento"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videocamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Impossibile chiamare da questo profilo"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Le norme di lavoro ti consentono di fare telefonate soltanto dal profilo di lavoro"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Impossibile fare chiamate da un\'app personale"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"La tua organizzazione consente di fare chiamate solo dalle app di lavoro"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Passa al profilo di lavoro"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Chiudi"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installa un\'app di lavoro per smartphone"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Annulla"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizza schermata di blocco"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Sblocca per personalizzare la schermata di blocco"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi non disponibile"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index be78678..6cf8ffa 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -100,7 +100,7 @@
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"מתבצע עיבוד של הקלטת מסך"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"התראה מתמשכת לסשן הקלטת מסך"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"להתחיל את ההקלטה?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"‏בזמן ההקלטה, תהיה ל-Android גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"‏בזמן ההקלטה, תהיה ל-Android גישה לכל מה שמופיע במסך שלך או מנוגן במכשיר שלך. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"‏בזמן הקלטה של אפליקציה, תהיה ל-Android גישה לכל מה שגלוי באפליקציה או מופעל מהאפליקציה. כדאי להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"התחלת ההקלטה"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"הקלטת אודיו"</string>
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"שיתוף"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"הקלטת המסך נשמרה"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"יש להקיש כדי להציג"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"שגיאה במחיקת הקלטת המסך"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"שגיאה בשמירה של הקלטת המסך"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"שגיאה בהפעלה של הקלטת המסך"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"חזרה"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"בית"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"זיהוי הפנים בוצע"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"יש אישור"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"יש להקיש על \'אישור\' לסיום התהליך"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"הנעילה בוטלה בזיהוי פנים. להמשך, לוחצים על סמל ביטול הנעילה."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"הנעילה בוטלה באמצעות זיהוי הפנים. יש ללחוץ כדי להמשיך."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"הפנים זוהו. יש ללחוץ כדי להמשיך."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"הפנים זוהו. להמשך יש ללחוץ על סמל ביטול הנעילה."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"השבתה"</string>
     <string name="sound_settings" msgid="8874581353127418308">"צליל ורטט"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"הגדרות"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"עוצמת הקול הוחלשה לרמה בטוחה יותר"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"עוצמת הקול הייתה גבוהה במשך יותר זמן מהמומלץ"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"עוצמת הקול הוחלשה לרמה בטוחה יותר"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"עוצמת הקול של האוזניות הייתה גבוהה במשך יותר זמן מהמומלץ"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"עוצמת הקול של האוזניות חרגה ממגבלת הבטיחות לשבוע הזה"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"המשך ההאזנה"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"החלשה של עוצמת הקול"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"האפליקציה מוצמדת"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"נשאר בתצוגה עד לביטול ההצמדה. יש ללחוץ לחיצה ארוכה על הלחצנים \'הקודם\' ו\'סקירה\' כדי לבטל את ההצמדה."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"נשאר בתצוגה עד לביטול ההצמדה. יש ללחוץ לחיצה ארוכה על הלחצנים \'הקודם\' ו\'דף הבית\' כדי לבטל את ההצמדה."</string>
@@ -903,7 +907,7 @@
     <string name="accessibility_control_move" msgid="8980344493796647792">"העברה למיקום <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"פקדים"</string>
     <string name="controls_favorite_subtitle" msgid="5818709315630850796">"יש לבחור פקדי מכשירים כדי לקבל גישה מהירה"</string>
-    <string name="controls_favorite_rearrange" msgid="5616952398043063519">"יש ללחוץ לחיצה ארוכה ולגרור כדי לארגן מחדש את הפקדים"</string>
+    <string name="controls_favorite_rearrange" msgid="5616952398043063519">"כדי לארגן מחדש את הפקדים, צריך ללחוץ לחיצה ארוכה ולגרור"</string>
     <string name="controls_favorite_removed" msgid="5276978408529217272">"כל הפקדים הוסרו"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"השינויים לא נשמרו"</string>
     <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"הצגת אפליקציות אחרות"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"הגדרות"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> של <xliff:g id="ARTIST_NAME">%2$s</xliff:g> מופעל מ-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> מתוך <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"אפליקציית <xliff:g id="APP_NAME">%1$s</xliff:g> פועלת"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"הפעלה"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"השהיה"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"הטראק הקודם"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"כדאי לחבר את הסטיילוס למטען"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"הסוללה של הסטיילוס חלשה"</string>
     <string name="video_camera" msgid="7654002575156149298">"מצלמת וידאו"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"אי אפשר להתקשר מהפרופיל הזה"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"המדיניות של מקום העבודה מאפשרת לך לבצע שיחות טלפון רק מפרופיל העבודה"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"אי אפשר לבצע שיחות מהאפליקציה לשימוש אישי"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"בארגון שלך מאפשרים לבצע שיחות רק מאפליקציות לעבודה"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"מעבר לפרופיל עבודה"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"סגירה"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"התקנה של אפליקציה לעבודה בטלפון"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"ביטול"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"התאמה אישית של מסך הנעילה"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"כדי להתאים אישית את מסך הנעילה, יש לבטל את הנעילה"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"‏ה-Wi-Fi לא זמין"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index ef32e64..a515e49 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -100,8 +100,8 @@
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"画面の録画を処理しています"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"画面の録画セッション中の通知"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"録画を開始しますか?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"録画中は、画面に表示される内容やデバイスで再生される内容に Android がアクセスできるため、パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"アプリの録画中は、そのアプリで表示または再生される内容に Android がアクセスできるため、パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"録画中は、表示や再生される内容に Android がアクセスできます。パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"アプリの録画中は、そのアプリで表示または再生される内容に Android がアクセスできます。パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"録画を開始"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"録音"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"デバイスの音声"</string>
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"共有"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"画面の録画を保存しました"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"タップすると表示されます"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"画面の録画の削除中にエラーが発生しました"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"画面の録画の保存中にエラーが発生しました"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"画面の録画中にエラーが発生しました"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"戻る"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"ホーム"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"顔を認証しました"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"確認しました"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"完了するには [確認] をタップしてください"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"顔でロック解除しました。アイコンを押すと続行します。"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"顔でロック解除しました。押して続行してください。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"顔を認識しました。押して続行してください。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"顔を認識しました。ロック解除アイコンを押して続行します。"</string>
@@ -394,9 +395,9 @@
     <string name="user_remove_user_message" msgid="6702834122128031833">"このユーザーのアプリとデータがすべて削除されます。"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"削除"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> で録画やキャストを開始しますか?"</string>
-    <string name="media_projection_dialog_warning" msgid="1303664408388363598">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> は、録画中またはキャスト中に画面に表示される情報や、デバイスで再生される情報のすべてにアクセスできるようになります。これには、パスワード、お支払いの詳細、写真、メッセージ、再生される音声などが含まれます。"</string>
+    <string name="media_projection_dialog_warning" msgid="1303664408388363598">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> は、録画中またはキャスト中に画面上に表示または再生される情報のすべてにアクセスできるようになります。これには、パスワード、お支払いの詳細、写真、メッセージ、音声などが含まれます。"</string>
     <string name="media_projection_sys_service_dialog_title" msgid="3751133258891897878">"録画やキャストを開始しますか?"</string>
-    <string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"この機能を提供するサービスは、録画中またはキャスト中に画面上に表示される情報や、デバイスで再生される情報のすべてにアクセスできるようになります。これには、パスワード、お支払いの詳細、写真、メッセージ、再生される音声などが含まれます。"</string>
+    <string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"この機能を提供するサービスは、録画中またはキャスト中に画面上に表示または再生される情報のすべてにアクセスできるようになります。これには、パスワード、お支払いの詳細、写真、メッセージ、音声などが含まれます。"</string>
     <string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"画面全体"</string>
     <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"1 つのアプリ"</string>
     <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"アプリの共有または録画"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"無効にする"</string>
     <string name="sound_settings" msgid="8874581353127418308">"音とバイブレーション"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"設定"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"安全な音量まで下げました"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"おすすめの時間よりも長く大音量になっていました"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"音量を安全なレベルまで下げました"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"おすすめの時間よりも長い時間にわたってヘッドフォンの音量が大きく設定されています"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ヘッドフォンの音量が今週一週間の安全基準とされる音量、時間を超えています"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"引き続き聴く"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"音量を下げる"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"アプリは固定されています"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"固定を解除するまで画面が常に表示されるようになります。[戻る] と [最近] を同時に押し続けると固定が解除されます。"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"固定を解除するまで画面が常に表示されるようになります。[戻る] と [ホーム] を同時に押し続けると固定が解除されます。"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>(アーティスト名: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>)が <xliff:g id="APP_LABEL">%3$s</xliff:g> で再生中"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> を実行しています"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"再生"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"一時停止"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"前のトラック"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"スピーカーとディスプレイ"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"デバイスの候補"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"メディアを他のデバイスに移動する共有中のセッションを停止します。"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"停止"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ブロードキャストの仕組み"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ブロードキャスト"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Bluetooth 対応デバイスを持っている付近のユーザーは、あなたがブロードキャストしているメディアを聴けます"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"タッチペンを充電器に接続してください"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"タッチペンのバッテリー残量が少なくなっています"</string>
     <string name="video_camera" msgid="7654002575156149298">"ビデオカメラ"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"このプロファイルからは通話を発信できません"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"仕事用ポリシーでは、通話の発信を仕事用プロファイルからのみに制限できます"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"個人用アプリからの通話はできません"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"組織では、仕事用アプリからの通話のみ許可されています"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"仕事用プロファイルに切り替える"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"閉じる"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"仕事用電話アプリをインストール"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"キャンセル"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ロック画面のカスタマイズ"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ロック画面をカスタマイズするにはロックを解除してください"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi は利用できません"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index f809045e..d37dfaf 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"გაზიარება"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"ეკრანის ჩაწერა შეინახა"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"შეეხეთ სანახავად"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"ეკრანის ჩანაწერის წაშლისას წარმოიშვა შეცდომა"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"ეკრანის ჩანაწერის შენახვისას შეცდომა მოხდა"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"ეკრანის ჩაწერის დაწყებისას წარმოიქმნა შეცდომა"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"უკან"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"საწყისი"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"სახის ამოცნობილია"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"დადასტურებული"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"დასასრულებლად შეეხეთ „დადასტურებას“"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"განიბლოკა სახით. გასაგრძელებლად დააჭირეთ განბლოკვის ხატულას."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"განიბლოკა სახით. დააჭირეთ გასაგრძელებლად."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ამოცნობილია სახით. დააჭირეთ გასაგრძელებლად."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ამოცნობილია სახით. გასაგრძელებლად დააჭირეთ განბლოკვის ხატულას."</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ამ მოწყობილობაზე დაინსტალირებულია სერტიფიცირების ორგანო. თქვენი ქსელის დაცული ტრაფიკი შეიძლება შეიცვალოს, ან მასზე მონიტორინგი განხორციელდეს."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"თქვენმა ადმინისტრატორმა ჩართო ქსელის ჟურნალირება, რომელიც თქვენი მოწყობილობის ტრაფიკის მონიტორინგს ახორციელებს."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"თქვენმა ადმინისტრატორმა ქსელის ჟურნალირება ჩართო, რომელიც ახორციელებს თქვენი სამსახურის პროფილის, მაგრამ არა პირადი პროფილის, ტრაფიკის მონიტორინგს."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"ეს მოწყობილობა დაკავშირებულია ინტერნეტთან <xliff:g id="VPN_APP">%1$s</xliff:g> აპით თქვენი ქსელის აქტივობა, მათ შორის, ელფოსტები და დათვალიერების მონაცემები, ხილულია VPN პროვაიდერისთვის."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"ეს მოწყობილობა დაკავშირებულია ინტერნეტთან <xliff:g id="VPN_APP">%1$s</xliff:g>. აპით თქვენი ქსელის აქტივობა, მათ შორის, ელფოსტა და დათვალიერების მონაცემები, ხილულია VPN პროვაიდერისთვის."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"ეს მოწყობილობა დაკავშირებულია ინტერნეტთან <xliff:g id="VPN_APP">%1$s</xliff:g> აპით თქვენი ქსელის აქტივობა, მათ შორის, ელფოსტები და დათვალიერების მონაცემები, ხილულია თქვენი IT ადმინისტრატორისთვის."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ეს მოწყობილობა დაკავშირებულია ინტერნეტთან <xliff:g id="VPN_APP_0">%1$s</xliff:g> და <xliff:g id="VPN_APP_1">%2$s</xliff:g> აპებით. თქვენი ქსელის აქტივობა, მათ შორის, ელფოსტები და დათვალიერების მონაცემები, ხილულია თქვენი IT ადმინისტრატორისთვის."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"თქვენი სამსახურის აპები დაკავშირებულია ინტერნეტთან <xliff:g id="VPN_APP">%1$s</xliff:g> აპით. თქვენი ქსელის აქტივობა სამსახურის აპებში, მათ შორის, ელფოსტები და დათვალიერების მონაცემები, ხილულია IT ადმინისტრატორისა და VPN პროვაიდერისთვის."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"გამორთვა"</string>
     <string name="sound_settings" msgid="8874581353127418308">"ხმა და ვიბრაცია"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"პარამეტრები"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"ხმა დაკლებულია უსაფრთხო დონემდე"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"ხმა მაღალია რეკომენდებულზე მეტი ხნის განავლობაში"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ხმა დაწეულია უსაფრთხო დონემდე"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ხმა მაღალი იყო რეკომენდებულზე მეტი ხნის განმავლობაში"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ყურსასმენების ხმამ ამ კვირაში უსაფრთხოების ლიმიტს გადააჭარბა"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"მოსმენის გაგრძელება"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"ხმის დაწევა"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"აპი ჩამაგრებულია"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"ამით ის დარჩება ხედში ჩამაგრების მოხსნამდე. ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ „უკან და მიმოხილვა“-ს."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"ამით ის დარჩება ხედში ჩამაგრების მოხსნამდე. ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ „უკან მთავარ გვერდზე“-ს."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"პარამეტრები"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, უკრავს <xliff:g id="APP_LABEL">%3$s</xliff:g>-დან"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>-დან <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> გაშვებულია"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"დაკვრა"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"პაუზა"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"წინა ჩანაწერი"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"დააკავშირეთ თქვენი სტილუსი დამტენს"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"სტილუსის ბატარეა დაცლის პირასაა"</string>
     <string name="video_camera" msgid="7654002575156149298">"ვიდეოკამერა"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"ამ პროფილიდან დარეკვა ვერ ხერხდება"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"თქვენი სამსახურის წესები საშუალებას გაძლევთ, სატელეფონო ზარები განახორციელოთ მხოლოდ სამსახურის პროფილიდან"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"პირადი აპიდან დარეკვა შეუძლებელია"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"თქვენი ორგანიზაცია ნებას გრთავთ, რომ დარეკოთ მხოლოდ სამსახურის აპებიდან"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"სამსახურის პროფილზე გადართვა"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"დახურვა"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"სამსახურის ტელეფონის აპის ინსტალაცია"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"გაუქმება"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ჩაკეთილი ეკრანის მორგება"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ჩაკეტილი ეკრანის მოსარგებად გაბლოკეთ"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi მიუწვდომელია"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index c335f4d..64ceefd 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Бөлісу"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Экран жазбасы сақталды."</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Көру үшін түртіңіз."</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Экран бейне жазбасын жою кезінде қате кетті"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Экран жазбасын сақтау кезінде қате шықты."</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Экрандағы бейнені жазу кезінде қате шықты."</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Артқа"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Үй"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Бет танылды."</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Расталды"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Аяқтау үшін \"Растау\" түймесін түртіңіз."</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Бет үлгісі арқылы ашылды. Жалғастыру үшін құлыпты ашу белгішесін басыңыз."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Бетпен ашылды. Жалғастыру үшін басыңыз."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Бет танылды. Жалғастыру үшін басыңыз."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Бет танылды. Жалғастыру үшін құлыпты ашу белгішесін басыңыз."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"өшіру"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Дыбыс және діріл"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Параметрлер"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Қауіпсіз дыбыс деңгейіне төмендетілді"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Дыбыстың жоғары деңгейі ұсынылғаннан уақыттан ұзағырақ болды."</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Дыбыс деңгейі қауіпсіз шекке дейін түсірілді"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Құлақаспаптың жоғары дыбыс деңгейі ұсынылған уақыттан ұзақ қосылып тұрды."</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Құлақаспаптың дыбыс деңгейі осы аптадағы қауіпсіз шектен асып кетті."</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Тыңдай беру"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Дыбыс деңгейін азайту"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Қолданба бекітілді"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Өзіңіз босатқаша ашық тұрады. Босату үшін \"Артқа\" және \"Шолу\" түймелерін басып тұрыңыз."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Өзіңіз босатқаша ашық тұрады. Босату үшін \"Артқа\" және \"Негізгі бет\" түймелерін басып тұрыңыз"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Параметрлер"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> қолданбасында <xliff:g id="ARTIST_NAME">%2$s</xliff:g> орындайтын \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" әні ойнатылуда."</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>/<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> қосулы тұр"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Ойнату"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Кідірту"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Алдыңғы трек"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Динамиктер мен дисплейлер"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Ұсынылған құрылғылар"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Мультимедиа файлын басқа құрылғыға жылжыту үшін ортақ сеансты тоқтатыңыз."</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Тоқтату"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Тарату қалай жүзеге асады"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Тарату"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Үйлесімді Bluetooth құрылғылары бар маңайдағы адамдар сіз таратып жатқан медиамазмұнды тыңдай алады."</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Стилусты зарядтағышқа жалғаңыз."</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Стилус батареясының заряды аз"</string>
     <string name="video_camera" msgid="7654002575156149298">"Бейнекамера"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Бұл профильден қоңырау шалу мүмкін емес"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Жұмыс саясатыңызға сәйкес тек жұмыс профилінен қоңырау шалуға болады."</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Жеке қолданбадан қоңырау шалу мүмкін емес"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Ұйымыңыз тек жұмыс қолданбаларынан қоңырау шалуға рұқсат етеді."</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Жұмыс профиліне ауысу"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Жабу"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Жұмысқа арналған телефон қолданбасын орнату"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Бас тарту"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Құлып экранын бейімдеу"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Құлып экранын бейімдеу үшін құлыпты ашыңыз"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi қолжетімсіз."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 2919737..43de595 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"ចែករំលែក"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"បានរក្សាទុក​ការថតវីដេអូអេក្រង់"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"ចុចដើម្បីមើល"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"មានបញ្ហា​ក្នុងការ​លុបការថត​សកម្មភាព​អេក្រង់"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"មានបញ្ហាក្នុងការរក្សាទុក​ការថតវីដេអូអេក្រង់"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"មានបញ្ហា​ក្នុងការ​ចាប់ផ្ដើម​ថត​អេក្រង់"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"ថយក្រោយ"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"គេហ​ទំព័រ"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"បានផ្ទៀងផ្ទាត់​មុខ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"បានបញ្ជាក់"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ចុច \"បញ្ជាក់\" ដើម្បីបញ្ចប់"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"បានដោះសោ​ដោយប្រើមុខ។ សូមចុចរូបដោះសោ ដើម្បីបន្ត។"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"បានដោះសោដោយប្រើមុខ។ សូមចុច ដើម្បីបន្ត។"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"បានស្គាល់មុខ។ សូមចុច ដើម្បីបន្ត។"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"បានស្គាល់មុខ។ សូមចុចរូបដោះសោ ដើម្បីបន្ត។"</string>
@@ -169,14 +170,14 @@
     <string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"កុំទាន់"</string>
     <string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"តម្រូវឱ្យ​កែលម្អ​សុវត្ថិភាព និងប្រតិបត្តិការ"</string>
     <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"រៀបចំការដោះសោដោយប្រើស្នាមម្រាមដៃម្ដងទៀត"</string>
-    <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"ការដោះសោ​ដោយប្រើ​ស្នាមម្រាមដៃ"</string>
-    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"រៀបចំការដោះសោ​ដោយប្រើ​ស្នាមម្រាមដៃ"</string>
+    <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"ការដោះសោ​ដោយស្កេន​ស្នាមម្រាមដៃ"</string>
+    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"រៀបចំការដោះសោ​ដោយស្កេន​ស្នាមម្រាមដៃ"</string>
     <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"ដើម្បីរៀបចំការដោះសោដោយប្រើស្នាមម្រាមដៃម្ដងទៀត គំរូ និងរូបភាពស្នាមម្រាមដៃបច្ចុប្បន្នរបស់អ្នកនឹងត្រូវបានលុប។\n\nបន្ទាប់ពីលុបគំរូនិងរូបភាពស្នាមម្រាមដៃទាំងនោះ អ្នកនឹងត្រូវរៀបចំការដោះសោដោយប្រើស្នាមម្រាមដៃម្ដងទៀត ដើម្បីដោះសោទូរសព្ទរបស់អ្នក ឬផ្ទៀងផ្ទាត់ថាជាអ្នក។"</string>
     <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"ដើម្បីរៀបចំការដោះសោដោយប្រើស្នាមម្រាមដៃម្ដងទៀត គំរូ និងរូបភាពស្នាមម្រាមដៃបច្ចុប្បន្នរបស់អ្នកនឹងត្រូវបានលុប។\n\nបន្ទាប់ពីលុបគំរូនិងរូបភាពស្នាមម្រាមដៃទាំងនោះ អ្នកនឹងត្រូវរៀបចំការដោះសោដោយប្រើស្នាមម្រាមដៃម្ដងទៀត ដើម្បីដោះសោទូរសព្ទរបស់អ្នក ឬផ្ទៀងផ្ទាត់ថាជាអ្នក។"</string>
     <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"មិនអាចរៀបចំការដោះសោដោយប្រើស្នាមម្រាមដៃបានទេ។ សូមចូលទៅកាន់​ការកំណត់​ ដើម្បីព្យាយាមម្ដងទៀត។"</string>
     <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"រៀបចំ​ការដោះសោតាមទម្រង់មុខ​ម្ដងទៀត"</string>
-    <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"ដោះ​សោ​តាម​​ទម្រង់​មុខ"</string>
-    <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"រៀបចំ​ការដោះសោ​តាមទម្រង់មុខ"</string>
+    <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"ការដោះ​សោ​ដោយស្កេន​មុខ"</string>
+    <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"រៀបចំ​ការដោះសោ​ដោយស្កេនមុខ"</string>
     <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"ដើម្បីរៀបចំ​ដោះសោតាមទម្រង់មុខ​ម្ដងទៀត គំរូមុខបច្ចុប្បន្ន​របស់អ្នក​នឹងត្រូវបានលុប។\n\nអ្នកនឹងត្រូវ​រៀបចំមុខងារនេះ​ម្ដងទៀត ដើម្បីប្រើមុខរបស់អ្នក​សម្រាប់ដោះសោទូរសព្ទរបស់អ្នក។"</string>
     <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"មិនអាច​រៀបចំ​ការដោះសោតាមទម្រង់មុខបានទេ។ សូមចូលទៅកាន់​ការកំណត់​ ដើម្បីព្យាយាមម្ដងទៀត។"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"ប៉ះ​ឧបករណ៍​ចាប់ស្នាម​ម្រាមដៃ"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"បិទ"</string>
     <string name="sound_settings" msgid="8874581353127418308">"សំឡេង និងការញ័រ"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ការកំណត់"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"បានបន្ថយទៅកម្រិតសំឡេង​ដែលកាន់តែមានសុវត្ថិភាព"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"កម្រិតសំឡេងខ្ពស់​ក្នុងរយៈពេលយូរជាងកម្រិត​ដែលបានណែនាំ"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"បានបន្ថយកម្រិតសំឡេងមកកម្រិតដែលកាន់តែមានសុវត្ថិភាព"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"កម្រិតសំឡេងកាសមានកម្រិតខ្ពស់យូរជាងរយៈពេលដែលបានណែនាំ"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"កម្រិតសំឡេងកាសបានលើសដែនកំណត់សុវត្ថិភាពសម្រាប់សប្ដាហ៍នេះ"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"បន្តស្ដាប់"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"បន្ថយ​កម្រិតសំឡេង"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"កម្មវិធី​ត្រូវបានខ្ទាស់"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"វា​នឹង​នៅតែ​បង្ហាញ រហូត​ទាល់​តែ​អ្នក​ដក​ការដៅ។ សូម​សង្កត់​ប៊ូតុង​ថយ​ក្រោយ និង​ប៊ូតុង​ទិដ្ឋភាពរួម​ឲ្យ​ជាប់ ដើម្បី​ដក​ការ​ដៅ។"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"វា​នឹង​នៅតែ​បង្ហាញ រហូត​ទាល់​តែ​អ្នក​ដក​ការដៅ។ សូម​ចុចប៊ូតុង​ថយក្រោយ និងប៊ូតុង​ទំព័រដើម​ឱ្យ​ជាប់ ដើម្បី​ដក​ការ​ដៅ។"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ការកំណត់"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ច្រៀងដោយ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> កំពុងចាក់ពី <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> នៃ <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុង​ដំណើរការ"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"ចាក់"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"ផ្អាក"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"ចម្រៀងមុន"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ភ្ជាប់ប៊ិករបស់អ្នកជាមួយឆ្នាំងសាក"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"ថ្មប៊ិកនៅសល់តិច"</string>
     <string name="video_camera" msgid="7654002575156149298">"កាមេរ៉ា​វីដេអូ"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"មិនអាចហៅទូរសព្ទពីកម្រងព័ត៌មាននេះបានទេ"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"គោលការណ៍ការងាររបស់អ្នកអនុញ្ញាតឱ្យអ្នកធ្វើការហៅទូរសព្ទបានតែពីកម្រងព័ត៌មានការងារប៉ុណ្ណោះ"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"មិនអាច​ហៅទូរសព្ទ​ពីកម្មវិធី​ផ្ទាល់ខ្លួន​បានទេ"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"ស្ថាប័ន​របស់អ្នក​អនុញ្ញាត​ឱ្យអ្នកធ្វើការហៅទូរសព្ទ​ពីកម្មវិធីការងារ​តែប៉ុណ្ណោះ"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ប្ដូរ​ទៅ​កម្រង​ព័ត៌មាន​ការងារ"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"បិទ"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ដំឡើងកម្មវិធីទូរសព្ទសម្រាប់ការងារ"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"បោះបង់"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ប្ដូរអេក្រង់ចាក់សោ​តាមបំណង"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ដោះសោ ដើម្បីប្ដូរអេក្រង់ចាក់សោតាមបំណង"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"មិនមាន Wi-Fi ទេ"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 07ba9b8..2ea1500 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -98,7 +98,7 @@
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ಟಿಪ್ಪಣಿಗೆ ಸೇರಿಸಿ"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡರ್"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿದೆ"</string>
-    <string name="screenrecord_channel_description" msgid="4147077128486138351">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೆಶನ್‌ಗಾಗಿ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಅಧಿಸೂಚನೆ"</string>
+    <string name="screenrecord_channel_description" msgid="4147077128486138351">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೆಶನ್‌ಗಾಗಿ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ನೋಟಿಫಿಕೇಶನ್"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭಿಸಬೇಕೇ?"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"ನೀವು ರೆಕಾರ್ಡಿಂಗ್ ಮಾಡುತ್ತಿರುವಾಗ, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಕಾಣಿಸುವ ಅಥವಾ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಮಾಡುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ Android ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಹಾಗೂ ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ರೆಕಾರ್ಡಿಂಗ್ ಮಾಡುತ್ತಿರುವಾಗ, ಆ ಆ್ಯಪ್‌ನಲ್ಲಿ ತೋರಿಸುವ ಅಥವಾ ಪ್ಲೇ ಮಾಡುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ Android ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಹಾಗೂ ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string>
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"ಹಂಚಿಕೊಳ್ಳಿ"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಉಳಿಸಲಾಗಿದೆ"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅಳಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೇವ್‌ ಮಾಡುವಾಗ ದೋಷ ಎದುರಾಗಿದೆ"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"ಹಿಂದೆ"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"ಮುಖಪುಟ"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ಪೂರ್ಣಗೊಳಿಸಲು ದೃಢೀಕರಿಸಿ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಒತ್ತಿ."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಒತ್ತಿ."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
@@ -230,7 +231,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"ಸೆನ್ಸರ್‌ಗಳು ಆಫ್ ಆಗಿವೆ"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೆರವುಗೊಳಿಸು."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{ಇನ್ನೂ # ಅಧಿಸೂಚನೆ ಒಳಗಿದೆ.}one{ಇನ್ನೂ # ಅಧಿಸೂಚನೆಗಳು ಒಳಗಿವೆ.}other{ಇನ್ನೂ # ಅಧಿಸೂಚನೆಗಳು ಒಳಗಿವೆ.}}"</string>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{ಇನ್ನೂ # ನೋಟಿಫಿಕೇಶನ್ ಒಳಗಿದೆ.}one{ಇನ್ನೂ # ನೋಟಿಫಿಕೇಶನ್‌ಗಳು ಒಳಗಿವೆ.}other{ಇನ್ನೂ # ನೋಟಿಫಿಕೇಶನ್‌ಗಳು ಒಳಗಿವೆ.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ಪರದೆಯನ್ನು ಲ್ಯಾಂಡ್‌ಸ್ಕೇಪ್ ಓರಿಯಂಟೇಶನ್‍ನಲ್ಲಿ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ಪರದೆಯನ್ನು ಪೋರ್ಟ್ರೇಟ್ ಓರಿಯಂಟೇಶನ್‍ನಲ್ಲಿ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ."</string>
     <string name="dessert_case" msgid="9104973640704357717">"ಡೆಸರ್ಟ್ ಕೇಸ್"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="sound_settings" msgid="8874581353127418308">"ಧ್ವನಿ &amp; ವೈಬ್ರೇಷನ್"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"ಸುರಕ್ಷಿತ ವಾಲ್ಯೂಮ್‌ಗೆ ಕಡಿಮೆ ಮಾಡಲಾಗಿದೆ"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"ಶಿಫಾರಸು ಮಾಡಿದ ಸಮಯಕ್ಕಿಂತ ಹೆಚ್ಚು ಸಮಯ ವಾಲ್ಯೂಮ್ ಹೆಚ್ಚಾಗಿರುತ್ತದೆ"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ವಾಲ್ಯೂಮ್ ಅನ್ನು ಸುರಕ್ಷಿತ ಮಟ್ಟಕ್ಕೆ ತಗ್ಗಿಸಲಾಗಿದೆ"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ಹೆಡ್‌ಫೋನ್‌ನ ವಾಲ್ಯೂಮ್‌ ಶಿಫಾರಸು ಮಾಡಿದ್ದಕ್ಕಿಂತಲೂ ಹೆಚ್ಚಿನ ಸಮಯದವರೆಗೆ ಅಧಿಕವಾಗಿದೆ"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ಹೆಡ್‌ಫೋನ್‌ನ ವಾಲ್ಯೂಮ್ ಈ ವಾರದ‌ ಮಟ್ಟಿಗೆ ಸುರಕ್ಷಿತ ಮಿತಿಯನ್ನು ಮೀರಿದೆ"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"ಆಲಿಸುತ್ತಿರಿ"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"ವಾಲ್ಯೂಮ್ ತಗ್ಗಿಸಿ"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"ಆ್ಯಪ್ ಅನ್ನು ಪಿನ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"ನೀವು ಅನ್‌ಪಿನ್ ಮಾಡುವವರೆಗೆ ಅದನ್ನು ವೀಕ್ಷಣೆಯಲ್ಲಿಡುತ್ತದೆ. ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ ಹಾಗೂ ಅನ್‌ಪಿನ್ ಮಾಡಲು ಅವಲೋಕಿಸಿ."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"ನೀವು ಅನ್‌ಪಿನ್ ಮಾಡುವವರೆಗೆ ಅದನ್ನು ವೀಕ್ಷಣೆಯಲ್ಲಿಡುತ್ತದೆ. ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ ಹಾಗೂ ಅನ್‌ಪಿನ್ ಮಾಡಲು ಮುಖಪುಟಕ್ಕೆ ಹಿಂತಿರುಗಿ."</string>
@@ -501,7 +505,7 @@
     <string name="stream_ring" msgid="7550670036738697526">"ರಿಂಗ್"</string>
     <string name="stream_music" msgid="2188224742361847580">"ಮಾಧ್ಯಮ"</string>
     <string name="stream_alarm" msgid="16058075093011694">"ಅಲಾರಮ್"</string>
-    <string name="stream_notification" msgid="7930294049046243939">"ಅಧಿಸೂಚನೆ"</string>
+    <string name="stream_notification" msgid="7930294049046243939">"ನೋಟಿಫಿಕೇಶನ್"</string>
     <string name="stream_bluetooth_sco" msgid="6234562365528664331">"ಬ್ಲೂಟೂತ್‌"</string>
     <string name="stream_dtmf" msgid="7322536356554673067">"ಡ್ಯುಯಲ್‌ ಬಹು ಟೋನ್ ಆವರ್ತನೆ"</string>
     <string name="stream_accessibility" msgid="3873610336741987152">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ"</string>
@@ -553,9 +557,9 @@
     <string name="enable_bluetooth_title" msgid="866883307336662596">"ಬ್ಲೂಟೂತ್ ಆನ್ ಮಾಡಬೇಕೆ?"</string>
     <string name="enable_bluetooth_message" msgid="6740938333772779717">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್ ಅನ್ನು ಟ್ಯಾಬ್ಲೆಟ್‌ಗೆ ಸಂಪರ್ಕಿಸಲು, ನೀವು ಮೊದಲು ಬ್ಲೂಟೂತ್ ಆನ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ."</string>
     <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"ಆನ್‌ ಮಾಡಿ"</string>
-    <string name="tuner_full_importance_settings" msgid="1388025816553459059">"ಪವರ್ ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳು"</string>
+    <string name="tuner_full_importance_settings" msgid="1388025816553459059">"ಪವರ್ ನೋಟಿಫಿಕೇಶನ್ ನಿಯಂತ್ರಣಗಳು"</string>
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ಆನ್ ಆಗಿದೆ - ಮುಖ-ಆಧಾರಿತ"</string>
-    <string name="power_notification_controls_description" msgid="1334963837572708952">"ಪವರ್ ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳ ಮೂಲಕ, ನೀವು ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಅಧಿಸೂಚನೆಗಳನ್ನು 0 ರಿಂದ 5 ರವರೆಗಿನ ಹಂತಗಳ ಪ್ರಾಮುಖ್ಯತೆಯನ್ನು ಹೊಂದಿಸಬಹುದು. \n\n"<b>"ಹಂತ 5"</b>" \n- ಮೇಲಿನ ಅಧಿಸೂಚನೆ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ಅನುಮತಿಸಿ \n- ಯಾವಾಗಲು ಇಣುಕು ನೋಟ \n\n"<b>"ಹಂತ 4"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಯಾವಾಗಲು ಇಣುಕು ನೋಟ\n\n"<b>"ಹಂತ 3"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n\n"<b>"ಹಂತ 2"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n- ಶಬ್ದ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಎಂದಿಗೂ ಮಾಡಬೇಡಿ \n\n"<b>"ಹಂತ 1"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n- ಶಬ್ದ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಎಂದಿಗೂ ಮಾಡಬೇಡಿ \n- ಸ್ಥಿತಿ ಪಟ್ಟಿ ಮತ್ತು ಲಾಕ್ ಪರದೆಯಿಂದ ಮರೆಮಾಡಿ \n- ಕೆಳಗಿನ ಅಧಿಸೂಚನೆ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ \n\n"<b>"ಹಂತ 0"</b>" \n- ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ನಿರ್ಬಂಧಿಸಿ"</string>
+    <string name="power_notification_controls_description" msgid="1334963837572708952">"ಪವರ್ ನೋಟಿಫಿಕೇಶನ್ ನಿಯಂತ್ರಣಗಳ ಮೂಲಕ, ನೀವು ಆ್ಯಪ್‍ಗಳ ನೋಟಿಫಿಕೇಶನ್‍ಗಳನ್ನು 0 ರಿಂದ 5 ರವರೆಗಿನ ಹಂತಗಳ ಪ್ರಾಮುಖ್ಯತೆಯನ್ನು ಹೊಂದಿಸಬಹುದು. \n\n"<b>"ಹಂತ 5"</b>" \n- ಮೇಲಿನ ನೋಟಿಫಿಕೇಶನ್ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ಅನುಮತಿಸಿ \n- ಯಾವಾಗಲು ಇಣುಕು ನೋಟ \n\n"<b>"ಹಂತ 4"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಯಾವಾಗಲು ಇಣುಕು ನೋಟ\n\n"<b>"ಹಂತ 3"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n\n"<b>"ಹಂತ 2"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n- ಶಬ್ದ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಎಂದಿಗೂ ಮಾಡಬೇಡಿ \n\n"<b>"ಹಂತ 1"</b>" \n- ಪೂರ್ಣ ಪರದೆ ಅಡಚಣೆಯನ್ನು ತಡೆಯಿರಿ \n- ಎಂದಿಗೂ ಇಣುಕು ನೋಟ ಬೇಡ \n- ಶಬ್ದ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಎಂದಿಗೂ ಮಾಡಬೇಡಿ \n- ಸ್ಥಿತಿ ಪಟ್ಟಿ ಮತ್ತು ಲಾಕ್ ಪರದೆಯಿಂದ ಮರೆಮಾಡಿ \n- ಕೆಳಗಿನ ನೋಟಿಫಿಕೇಶನ್ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸಿ \n\n"<b>"ಹಂತ 0"</b>" \n- ಆ್ಯಪ್‍ನಿಂದ ಎಲ್ಲಾ ನೋಟಿಫಿಕೇಶನ್‍ಗಳನ್ನು ನಿರ್ಬಂಧಿಸಿ"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"ಪೂರ್ಣಗೊಂಡಿದೆ"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"ಅನ್ವಯಿಸಿ"</string>
     <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ಅಧಿಸೂಚನೆಗಳನ್ನು ಆಫ್ ಮಾಡಿ"</string>
@@ -588,15 +592,15 @@
     <string name="feedback_promoted" msgid="2125562787759780807">"ಈ ಅಧಿಸೂಚನೆಯು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿಮ್ಮ ಶೇಡ್‌ನಲ್ಲಿ &lt;b&gt;ಉನ್ನತ ಸ್ಥಾನವನ್ನು ಹೊಂದಿದೆ&lt;/b&gt;."</string>
     <string name="feedback_demoted" msgid="951884763467110604">"ಈ ಅಧಿಸೂಚನೆಯು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿಮ್ಮ ಶೇಡ್‌ನಲ್ಲಿ &lt;b&gt;ಕಡಿಮೆ ಸ್ಥಾನವನ್ನು ಹೊಂದಿದೆ&lt;/b&gt;."</string>
     <string name="feedback_prompt" msgid="3656728972307896379">"ನಿಮ್ಮ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಡೆವಲಪರ್‌ಗೆ ತಿಳಿಸಿ. ಇದು ಸರಿಯಾಗಿತ್ತೇ?"</string>
-    <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳನ್ನು ತೆರೆಯಲಾಗಿದೆ"</string>
-    <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳನ್ನು ಮುಚ್ಚಲಾಗಿದೆ"</string>
+    <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ನೋಟಿಫಿಕೇಶನ್ ನಿಯಂತ್ರಣಗಳನ್ನು ತೆರೆಯಲಾಗಿದೆ"</string>
+    <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ನೋಟಿಫಿಕೇಶನ್ ನಿಯಂತ್ರಣಗಳನ್ನು ಮುಚ್ಚಲಾಗಿದೆ"</string>
     <string name="notification_more_settings" msgid="4936228656989201793">"ಹೆಚ್ಚಿನ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="notification_app_settings" msgid="8963648463858039377">"ಕಸ್ಟಮೈಜ್‌ ಮಾಡಿ"</string>
     <string name="notification_conversation_bubble" msgid="2242180995373949022">"ಬಬಲ್ ತೋರಿಸಿ"</string>
     <string name="notification_conversation_unbubble" msgid="6908427185031099868">"ಬಬಲ್ಸ್‌ ಅನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
     <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
-    <string name="notification_menu_gear_description" msgid="6429668976593634862">"ಅಧಿಸೂಚನೆ ನಿಯಂತ್ರಣಗಳು"</string>
-    <string name="notification_menu_snooze_description" msgid="4740133348901973244">"ಅಧಿಸೂಚನೆ ಸ್ನೂಜ್ ಆಯ್ಕೆಗಳು"</string>
+    <string name="notification_menu_gear_description" msgid="6429668976593634862">"ನೋಟಿಫಿಕೇಶನ್ ನಿಯಂತ್ರಣಗಳು"</string>
+    <string name="notification_menu_snooze_description" msgid="4740133348901973244">"ನೋಟಿಫಿಕೇಶನ್ ಸ್ನೂಜ್ ಆಯ್ಕೆಗಳು"</string>
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"ನನಗೆ ಜ್ಞಾಪಿಸಿ"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"ರದ್ದುಗೊಳಿಸಿ"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ಗೆ ಸ್ನೂಜ್ ಮಾಡಲಾಗಿದೆ"</string>
@@ -744,7 +748,7 @@
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ಟೈಲ್ ಸೇರಿಸಲಾಗಿದೆ"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ಟೈಲ್ ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳ ಎಡಿಟರ್."</string>
-    <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ಅಧಿಸೂಚನೆ: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
+    <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ನೋಟಿಫಿಕೇಶನ್: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ."</string>
     <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ."</string>
     <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಮುಚ್ಚಿ."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ಅವರ <xliff:g id="SONG_NAME">%1$s</xliff:g> ಹಾಡನ್ನು <xliff:g id="APP_LABEL">%3$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> ರಲ್ಲಿ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ರನ್ ಆಗುತ್ತಿದೆ"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"ಪ್ಲೇ ಮಾಡಿ"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"ವಿರಾಮಗೊಳಿಸಿ"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"ಹಿಂದಿನ ಟ್ರ್ಯಾಕ್"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ಸ್ಪೀಕರ್‌ಗಳು ಮತ್ತು ಡಿಸ್‌ಪ್ಲೇಗಳು"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ಸೂಚಿಸಿದ ಸಾಧನಗಳು"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"ಮೀಡಿಯಾವನ್ನು ಮತ್ತೊಂದು ಸಾಧನಕ್ಕೆ ಸರಿಸಲು ನಿಮ್ಮ ಹಂಚಿಕೊಂಡ ಸೆಶನ್ ಅನ್ನು ನಿಲ್ಲಿಸಿ"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"ನಿಲ್ಲಿಸಿ"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ಪ್ರಸಾರವು ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ಪ್ರಸಾರ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ಹೊಂದಾಣಿಕೆಯಾಗುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ಹೊಂದಿರುವ ಸಮೀಪದಲ್ಲಿರುವ ಜನರು ನೀವು ಪ್ರಸಾರ ಮಾಡುತ್ತಿರುವ ಮಾಧ್ಯಮವನ್ನು ಆಲಿಸಬಹುದು"</string>
@@ -1103,7 +1106,7 @@
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"ಮೈಕ್ ಆಫ್ ಆಗಿದೆ"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ ಆಫ್ ಆಗಿದೆ"</string>
     <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"ಅಸಿಸ್ಟೆಂಟ್ ಆಲಿಸುತ್ತಿದೆ"</string>
-    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ಅಧಿಸೂಚನೆ}one{# ಅಧಿಸೂಚನೆಗಳು}other{# ಅಧಿಸೂಚನೆಗಳು}}"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ನೋಟಿಫಿಕೇಶನ್}one{# ನೋಟಿಫಿಕೇಶನ್‌ಗಳು}other{# ನೋಟಿಫಿಕೇಶನ್‌ಗಳು}}"</string>
     <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
     <string name="note_task_button_label" msgid="8718616095800343136">"ಟಿಪ್ಪಣಿಗಳನ್ನು ಬರೆದುಕೊಳ್ಳುವುದು"</string>
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ಪ್ರಸಾರ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ನಿಮ್ಮ ಸ್ಟೈಲಸ್ ಅನ್ನು ಚಾರ್ಜರ್‌ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಿ"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"ಸ್ಟೈಲಸ್ ಬ್ಯಾಟರಿ ಕಡಿಮೆಯಿದೆ"</string>
     <string name="video_camera" msgid="7654002575156149298">"ವೀಡಿಯೊ ಕ್ಯಾಮರಾ"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"ಈ ಪ್ರೊಫೈಲ್‌ನಿಂದ ಕರೆ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"ನಿಮ್ಮ ಕೆಲಸದ ನೀತಿಯು ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ನಿಂದ ಮಾತ್ರ ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"ವೈಯಕ್ತಿಕ ಆ್ಯಪ್‌ನಿಂದ ಕರೆ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳಿಂದ ಮಾತ್ರ ಕರೆಗಳನ್ನು ಮಾಡಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ಗೆ ಬದಲಿಸಿ"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"ಮುಚ್ಚಿರಿ"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ಕೆಲಸದ ಫೋನ್ ಆ್ಯಪ್ ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"ರದ್ದುಗೊಳಿಸಿ"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ವೈ-ಫೈ ಲಭ್ಯವಿಲ್ಲ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index fda77c2..9459744 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"공유"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"화면 녹화 저장됨"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"탭하여 보기"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"화면 녹화는 삭제하는 중에 오류가 발생했습니다."</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"화면 녹화 저장 중에 오류가 발생했습니다."</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"화면 녹화 시작 중 오류 발생"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"뒤로"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"홈"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"얼굴이 인증되었습니다."</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"확인함"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"완료하려면 확인을 탭하세요."</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"얼굴 인식으로 잠금 해제되었습니다. 계속하려면 잠금 해제 아이콘을 누르세요."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"얼굴 인식으로 잠금 해제되었습니다. 계속하려면 누르세요."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"얼굴이 인식되었습니다. 계속하려면 누르세요."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"얼굴이 인식되었습니다. 계속하려면 아이콘을 누르세요."</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"이 기기에는 인증기관이 설치되어 있습니다. 보안 네트워크 트래픽을 모니터링 또는 수정할 수 있습니다."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"관리자가 기기에서 발생하는 트래픽을 모니터링하는 네트워크 로깅을 사용 설정했습니다."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"관리자가 직장 프로필에서 발생하는 트래픽을 모니터링하는 네트워크 로깅을 사용 설정했습니다. 하지만 개인 프로필은 모니터링되지 않습니다."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"이 기기는 <xliff:g id="VPN_APP">%1$s</xliff:g> 앱을 통해 인터넷에 연결됩니다. VPN 제공업체가 이메일, 인터넷 사용 기록 등 내 네트워크 활동을 볼 수 있습니다."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"이 기기가 <xliff:g id="VPN_APP">%1$s</xliff:g>을(를) 통해 인터넷에 연결됩니다. VPN 제공업체가 이메일, 인터넷 사용 기록 등 내 네트워크 활동을 볼 수 있습니다."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"이 기기는 <xliff:g id="VPN_APP">%1$s</xliff:g> 앱을 통해 인터넷에 연결됩니다. IT 관리자가 이메일, 인터넷 사용 기록 등 내 네트워크 활동을 볼 수 있습니다."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"이 기기는 <xliff:g id="VPN_APP_0">%1$s</xliff:g> 및 <xliff:g id="VPN_APP_1">%2$s</xliff:g> 앱을 통해 인터넷에 연결됩니다. IT 관리자가 이메일, 인터넷 사용 기록 등 내 네트워크 활동을 볼 수 있습니다."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"직장 앱은 <xliff:g id="VPN_APP">%1$s</xliff:g> 앱을 통해 인터넷에 연결됩니다. IT 관리자와 VPN 제공업체가 이메일, 인터넷 사용 기록 등 직장 앱에서 이루어진 내 네트워크 활동을 볼 수 있습니다."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"사용 중지"</string>
     <string name="sound_settings" msgid="8874581353127418308">"소리 및 진동"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"설정"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"청력 보호를 위해 적정 볼륨으로 낮춤"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"볼륨이 권장 시간보다 긴 시간 동안 높은 상태였습니다"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"볼륨을 안전한 수준으로 낮춤"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"헤드폰 볼륨이 권장 시간보다 오랫동안 높은 상태였습니다."</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"헤드폰 볼륨이 이번 주 안전 한도를 초과했습니다."</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"볼륨 유지하기"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"볼륨 낮추기"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"앱 고정됨"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"고정 해제할 때까지 계속 표시됩니다. 고정 해제하려면 뒤로 및 최근 사용을 길게 터치하세요."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"고정 해제할 때까지 계속 표시됩니다. 고정 해제하려면 뒤로 및 홈을 길게 터치하세요."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"설정"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>에서 <xliff:g id="ARTIST_NAME">%2$s</xliff:g>의 <xliff:g id="SONG_NAME">%1$s</xliff:g> 재생 중"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> 실행 중"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"재생"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"일시중지"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"이전 트랙"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"스피커 및 디스플레이"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"추천 기기"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"미디어를 다른 기기로 이동하려면 공유 세션을 중지하세요."</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"중지"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"브로드캐스팅 작동 원리"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"브로드캐스트"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"호환되는 블루투스 기기를 가진 근처의 사용자가 내가 브로드캐스트 중인 미디어를 수신 대기할 수 있습니다."</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"스타일러스를 충전기에 연결하세요"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"스타일러스 배터리 부족"</string>
     <string name="video_camera" msgid="7654002575156149298">"비디오 카메라"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"이 프로필에서 전화를 걸 수 없음"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"직장 정책이 직장 프로필에서만 전화를 걸도록 허용합니다."</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"개인 앱에서 통화를 걸 수 없습니다"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"귀하의 조직에서 직장 앱을 사용한 통화만 허용했습니다."</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"직장 프로필로 전환"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"닫기"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"직장 전화 앱 설치"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"취소"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"잠금 화면 맞춤 설정"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"잠금 화면 맞춤설정을 위해 잠금 해제"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi를 사용할 수 없음"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 3952394..c5c448e 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Бөлүшүү"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Экрандан жаздырылган нерсе сакталды"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Көрүү үчүн таптаңыз"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Экранды жаздырууну өчүрүүдө ката кетти"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Экран тартылган жок"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Экранды жаздырууну баштоодо ката кетти"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Артка"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Үйгө"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Жүздүн аныктыгы текшерилди"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Ырасталды"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Бүтүрүү үчүн \"Ырастоо\" баскычын басыңыз"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Кулпуну жүзүңүз менен ачтыңыз. Улантуу үчүн кулпусун ачуу сүрөтчөсүн басыңыз."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Кулпуну жүзүңүз менен ачтыңыз. Улантуу үчүн басыңыз."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Жүз таанылды. Улантуу үчүн басыңыз."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Жүз таанылды. Улантуу үчүн кулпусун ачуу сүрөтчөсүн басыңыз."</string>
@@ -174,11 +175,11 @@
     <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"Манжа изи менен ачуу функциясын тууралоо үчүн учурдагы манжа изи сүрөттөрү менен үлгүлөр өчүрүлөт.\n\nАлар өчүрүлгөндөн кийин, манжа изиңизди колдонуп телефонуңуздун кулпусун ачуу же өзүңүздү ырастоо үчүн Манжа изи менен ачуу функциясын кайра жөндөшүңүз керек."</string>
     <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"Манжа изи менен ачуу функциясын тууралоо үчүн учурдагы манжа изи сүрөттөрү менен үлгүсү өчүрүлөт.\n\nАлар өчүрүлгөндөн кийин, манжа изиңизди колдонуп телефонуңуздун кулпусун ачуу же өзүңүздү ырастоо үчүн Манжа изи менен ачуу функциясын кайра жөндөшүңүз керек."</string>
     <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Манжа изи менен ачуу функциясы жөндөлгөн жок. Параметрлерге өтүп, кайталап көрүңүз."</string>
-    <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Жүзүнөн таанып ачуу функциясын кайрадан жөндөңүз"</string>
+    <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Жүзүнөн таанып ачуу функциясын кайра коюңуз"</string>
     <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"Жүзүнөн таанып ачуу"</string>
     <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Жүзүнөн таанып ачууну коюу"</string>
     <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"Жүзүнөн таанып ачуу функциясын кошуу үчүн жүзүңүздүн учурдагы үлгүсү өчүрүлөт.\n\nТелефонуңуздун кулпусун жүзүңүз аркылуу ачуу үчүн бул функцияны кайра жөндөшүңүз керек болот."</string>
-    <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"Жүзүнөн таанып ачуу функциясы жөндөлгөн жок. Параметрлерге өтүп, кайталап көрүңүз."</string>
+    <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"Жүзүнөн таанып ачуу функциясы кошулган жок. Параметрлерге өтүп, кайталап көрүңүз."</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Манжа изинин сенсорун басыңыз"</string>
     <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Жүз таанылбай жатат. Манжа изин колдонуңуз."</string>
     <!-- no translation found for keyguard_face_failed_use_fp (7140293906176164263) -->
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"өчүрүү"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Үн жана дирилдөө"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Параметрлер"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Коопсуз үн көлөмүнө төмөндөтүлдү"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Үн көлөмү сунушталгандан узагыраак убакыт жогору болду"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Үндүн катуулугу коопсуз деңгээлге чейин акырындатылды"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Гарнитуранын үнүн катуу чыгарып, сунушталган убакыттан узагыраак угуп жатасыз"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Гарнитуранын үнүнүн катуулугу бул аптада коопсуз деңгээлден жогору болду"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Уга берем"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Үнүн акырындатуу"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Колдонмо кадалды"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Ал бошотулмайынча көрүнө берет. Бошотуу үчүн \"Артка\" жана \"Назар\" баскычтарын басып, кармап туруңуз."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Ал бошотулмайынча көрүнө берет. Бошотуу үчүн, \"Артка\" жана \"Башкы бет\" баскычтарын басып, кармап туруңуз."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Параметрлер"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ыры (аткаруучу: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) <xliff:g id="APP_LABEL">%3$s</xliff:g> колдонмосунан ойнотулуп жатат"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> ичинен <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> иштеп жатат"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Ойнотуу"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Тындыруу"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Мурунку трек"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Динамиктер жана дисплейлер"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Сунушталган түзмөктөр"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Медиафайлдарды башка түзмөккө жылдыруу үчүн жалпы сеансыңызды токтотуңуз"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Токтотуу"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Кабарлоо кантип иштейт"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Кабарлоо"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Шайкеш Bluetooth түзмөктөрү болгон жакын жердеги кишилер кабарлап жаткан медиаңызды уга алышат"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Стилусту кубаттаңыз"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Стилустун батареясы отурайын деп калды"</string>
     <string name="video_camera" msgid="7654002575156149298">"Видео камера"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Бул профилден чала албайсыз"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Жумуш саясатыңызга ылайык, жумуш профилинен гана чалууларды аткара аласыз"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Жеке колдонмодон чалуу мүмкүн эмес"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Уюмуңуз жумуш колдонмолорунан гана чалууга уруксат берет"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Жумуш профилине которулуу"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Жабуу"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Жумуш үчүн телефон колдонмосун орнотуу"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Жокко чыгаруу"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Кулпу экранын тууралоо"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Кулпуланган экранды тууралоо үчүн кулпусун ачыңыз"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi жеткиликтүү эмес"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 9812762..6078b7b 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"ແບ່ງປັນ"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"ຈັດເກັບການບັນທຶກໜ້າຈໍແລ້ວ"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"ແຕະເພື່ອເບິ່ງ"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"ເກີດຄວາມຜິດພາດໃນການລຶບການບັນທຶກໜ້າຈໍ"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"ເກີດຂໍ້ຜິດພາດໃນການບັນທຶກໜ້າຈໍ"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"ເກີດຄວາມຜິດພາດໃນການບັນທຶກໜ້າຈໍ"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"ກັບຄືນ"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"ໜ້າທຳອິດ"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ພິສູດຢືນຢັນໃບໜ້າແລ້ວ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ຢືນຢັນແລ້ວ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ແຕະຢືນຢັນເພື່ອສຳເລັດ"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອສືບຕໍ່."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດເພື່ອສືບຕໍ່."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດເພື່ອສືບຕໍ່."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອສືບຕໍ່."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"ປິດນຳໃຊ້"</string>
     <string name="sound_settings" msgid="8874581353127418308">"ສຽງ ແລະ ການສັ່ນເຕືອນ"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ການຕັ້ງຄ່າ"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"ໄດ້ຫຼຸດລົງຫາລະດັບສຽງທີ່ປອດໄພຍິ່ງຂຶ້ນ"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"ລະດັບສຽງສູງເປັນເວລາດົນກວ່າທີ່ແນະນໍາໃຫ້"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ຫຼຸດລະດັບສຽງໃຫ້ຢູ່ໃນລະດັບທີ່ປອດໄພຂຶ້ນແລ້ວ"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ຫູຟັງຢູ່ໃນລະດັບສຽງທີ່ດັງເປັນໄລຍະເວລາດົນກວ່າທີ່ແນະນຳ"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ລະດັບສຽງຂອງຫູຟັງໄດ້ເກີນຂີດຈຳກັດທີ່ປອດໄພສຳລັບອາທິດນີ້"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"ສືບຕໍ່ຟັງ"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"ຫຼຸດລະດັບສຽງ"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"ແອັບຖືກປັກໝຸດແລ້ວ"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"ນີ້ຈະສະແດງມັນໃນໜ້າຈໍຈົນກວ່າທ່ານຈະເຊົາປັກມຸດ. ໃຫ້ແຕະປຸ່ມກັບຄືນ ແລະ ປຸ່ມພາບຮວມຄ້າງໄວ້ເພື່ອຍົກເລີກການປັກມຸດ."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"ນີ້ຈະສະແດງມັນໃນໜ້າຈໍຈົນກວ່າທ່ານຈະເຊົາປັກໝຸດ. ໃຫ້ແຕະປຸ່ມກັບຄືນ ແລະ ປຸ່ມພາບຮວມຄ້າງໄວ້ເພື່ອຍົກເລີກການປັກໝຸດ."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ການຕັ້ງຄ່າ"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ໂດຍ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ກຳລັງຫຼິ້ນຈາກ <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> ຈາກ <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງເຮັດວຽກຢູ່"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"ຫຼິ້ນ"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"ຢຸດຊົ່ວຄາວ"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"ເພງກ່ອນໜ້າ"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ລຳໂພງ ແລະ ຈໍສະແດງຜົນ"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ອຸປະກອນທີ່ແນະນຳ"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"ຢຸດເຊດຊັນທີ່ແບ່ງປັນຂອງທ່ານເພື່ອຍ້າຍມີເດຍໄປຫາອຸປະກອນອື່ນ"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"ຢຸດ"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ການອອກອາກາດເຮັດວຽກແນວໃດ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ອອກອາກາດ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ຄົນທີ່ຢູ່ໃກ້ທ່ານທີ່ມີອຸປະກອນ Bluetooth ທີ່ເຂົ້າກັນໄດ້ຈະສາມາດຟັງມີເດຍທີ່ທ່ານກຳລັງອອກອາກາດຢູ່ໄດ້"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ເຊື່ອມຕໍ່ປາກກາຂອງທ່ານກັບສາຍສາກ"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"ແບັດເຕີຣີປາກກາເຫຼືອໜ້ອຍ"</string>
     <string name="video_camera" msgid="7654002575156149298">"ກ້ອງວິ​ດີ​ໂອ"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"ບໍ່ສາມາດໂທຈາກໂປຣໄຟລ໌ນີ້ໄດ້"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"ນະໂຍບາຍບ່ອນເຮັດວຽກຂອງທ່ານອະນຸຍາດໃຫ້ທ່ານໂທລະສັບໄດ້ຈາກໂປຣໄຟລ໌ບ່ອນເຮັດວຽກເທົ່ານັ້ນ"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"ບໍ່ສາມາດໂທຈາກແອັບສ່ວນຕົວໄດ້"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"ອົງການຈັດຕັ້ງຂອງທ່ານອະນຸຍາດໃຫ້ທ່ານໂທຈາກແອັບບ່ອນເຮັດວຽກເທົ່ານັ້ນ"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ສະຫຼັບໄປໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"ປິດ"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ຕິດຕັ້ງແອັບໂທລະສັບບ່ອນເຮັດວຽກ"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"ຍົກເລີກ"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ປັບແຕ່ງໜ້າຈໍລັອກ"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ປົດລັອກເພື່ອປັບແຕ່ງໜ້າຈໍລັອກ"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi ບໍ່ພ້ອມໃຫ້ນຳໃຊ້"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 863a97b..bb569e3 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Bendrinti"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Ekrano vaizdo įrašas išsaugotas"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Palieskite, kad peržiūrėtumėte"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ištrinant ekrano įrašą įvyko klaida"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Išsaugant ekrano įrašą įvyko klaida"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Pradedant ekrano vaizdo įrašymą iškilo problema"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Atgal"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Pagrindinis"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Veidas autentifikuotas"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Patvirtinta"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Paliesk. „Patvirtinti“, kad užbaigtumėte"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Atrakinta pagal veidą. Pasp. atrak. pikt., kad tęstumėte."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Atrakinta pagal veidą. Paspauskite, jei norite tęsti."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Veidas atpažintas. Paspauskite, jei norite tęsti."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Veidas atpažintas. Tęskite paspaudę atrakinimo piktogramą."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"išjungti"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Garsas ir vibravimas"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Nustatymai"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Sumažinta iki saugesnio garsumo"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Garsumas buvo aukštas ilgiau, nei rekomenduojama"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Garsumas sumažintas iki saugesnio lygio"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Ausinių garsumo lygis buvo aukštas ilgiau, nei rekomenduojama"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Ausinių garsumo lygis viršijo šios savaitės saugaus garsumo lygio apribojimą"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Toliau klausytis"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Sumažinti garsumą"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Programa prisegta"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Tai bus rodoma, kol atsegsite. Palieskite ir palaikykite „Atgal“ ir „Apžvalga“, kad atsegtumėte."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Tai bus rodoma, kol atsegsite. Palieskite ir palaikykite „Atgal“ ir „Pagrindinis ekranas“, kad atsegtumėte."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Nustatymai"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> – „<xliff:g id="SONG_NAME">%1$s</xliff:g>“ leidžiama iš „<xliff:g id="APP_LABEL">%3$s</xliff:g>“"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> iš <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ vykdoma"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Paleisti"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pristabdyti"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Ankstesnis takelis"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Garsiakalbiai ir ekranai"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Siūlomi įrenginiai"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Sustabdyti bendrinamą seansą norint perkelti mediją į kitą įrenginį"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Sustabdyti"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kaip veikia transliacija"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transliacija"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Netoliese esantys žmonės, turintys suderinamus „Bluetooth“ įrenginius, gali klausyti jūsų transliuojamos medijos"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Prijunkite rašiklį prie kroviklio"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Senka rašiklio akumuliatorius"</string>
     <string name="video_camera" msgid="7654002575156149298">"Vaizdo kamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Negalima skambinti iš šio profilio"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Pagal jūsų darbo politiką galite skambinti telefonu tik iš darbo profilio"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Nepavyko skambinti iš asmeninės programos"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Jūsų organizacija leidžia skambinti tik iš darbo programų"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Perjungti į darbo profilį"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Uždaryti"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Įdiegti darbo telefono programą"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Atšaukti"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Užrakinimo ekrano tinkinimas"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Atrakinę tinkinkite užrakinimo ekraną"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"„Wi-Fi“ ryšys nepasiekiamas"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index c5cbffa..2acefea 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Kopīgot"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Ekrāna ieraksts ir saglabāts"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Pieskarieties, lai skatītu"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Dzēšot ekrāna ierakstu, radās kļūda."</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Saglabājot ekrāna ierakstu, radās kļūda."</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Sākot ierakstīt ekrāna saturu, radās kļūda."</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Atpakaļ"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Sākums"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Seja autentificēta"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Apstiprināts"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Lai pabeigtu, pieskarieties Apstiprināt"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Atbloķēta ar seju. Turpināt: nospiediet atbloķēšanas ikonu."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ierīce atbloķēta ar seju. Nospiediet, lai turpinātu."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Seja atpazīta. Nospiediet, lai turpinātu."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Seja atpazīta. Lai turpinātu, nospiediet atbloķēšanas ikonu."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"atspējot"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Skaņa un vibrācija"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Iestatījumi"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Skaļums samazināts līdz drošākam"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Skaļums ir bijis liels ilgāk, nekā ieteicams."</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Skaļums samazināts līdz drošākam līmenim"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Austiņu skaļums ir bijis liels ilgāk, nekā ieteicams."</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Austiņu skaļums ir pārsniedzis šīs nedēļas drošo ierobežojumu."</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Turpināt klausīties"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Samazināt skaļumu"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Lietotne ir piesprausta"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Šādi tas būs redzams līdz brīdim, kad to atspraudīsiet. Lai atspraustu, pieskarieties pogām Atpakaļ un Pārskats un turiet tās."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Šādi tas būs redzams līdz brīdim, kad to atspraudīsiet. Lai atspraustu, pieskarieties pogām “Atpakaļ” un “Sākums” un turiet tās."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Iestatījumi"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tiek atskaņots fails “<xliff:g id="SONG_NAME">%1$s</xliff:g>” (izpildītājs: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) no lietotnes <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> no <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> darbojas"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Atskaņot"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Apturēt"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Iepriekšējais ieraksts"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Skaļruņi un displeji"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Ieteiktās ierīces"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Pārtrauciet savu kopīgoto sesiju, lai pārvietotu multivides saturu uz citu ierīci."</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Pārtraukt"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kā darbojas apraide"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Apraide"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Tuvumā esošās personas ar saderīgām Bluetooth ierīcēm var klausīties jūsu apraidīto multivides saturu."</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Pievienojiet skārienekrāna pildspalvu lādētājam"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Zems skārienekrāna pildspalvas akumulatora līmenis"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Nevar zvanīt no šī profila"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Saskaņā ar jūsu darba politiku tālruņa zvanus drīkst veikt tikai no darba profila"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Nevar zvanīt no personīgās lietotnes"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Jūsu organizācija ļauj jums veikt zvanus tikai no darba lietotnēm."</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pārslēgties uz darba profilu"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Aizvērt"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalēt darba lietotni Tālrunis"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Atcelt"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Pielāgot bloķēšanas ekrānu"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Bloķēšanas ekrāna pielāgošana pēc atbloķēšanas"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi nav pieejams"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 2df7446..b52af9b 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Сподели"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Снимката од екранот е зачувана"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Допрете за прегледување"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Грешка при бришењето на снимката од екранот"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Грешка при зачувувањето на снимката од екранот"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при почетокот на снимањето на екранот"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Почетна страница"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лицето е проверено"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потврдено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Допрете „Потврди“ за да се заврши"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Отклучено со лик. Притиснете ја иконата за отклучување за да продолжите."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Отклучено со лик. Притиснете за да продолжите."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицето е препознаено. Притиснете за да продолжите."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицето е препознаено. Притиснете ја иконата за отклучување за да продолжите."</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На уредов е инсталиран авторитет за сертификат. Вашиот безбеден мрежен сообраќај можно е да се следи или изменува."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Вашиот администратор вклучил евиденција на мрежата, што подразбира следење на сообраќајот на вашиот уред."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Вашиот администратор вклучил мрежна евиденција, што подразбира следење на сообраќајот во работниот, но не и во личниот профил."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Уредов е поврзан на интернет преку <xliff:g id="VPN_APP">%1$s</xliff:g>. Вашата мрежна активност во работните апликации, заедно со е-пораките и податоците од прелистување, е видлива за VPN-операторот."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Уредов е поврзан на интернет преку <xliff:g id="VPN_APP">%1$s</xliff:g>. Вашата мрежна активност (заедно со е-пораките и податоците од прелистувањето) е видлива за VPN-операторот."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"Уредов е поврзан на интернет преку <xliff:g id="VPN_APP">%1$s</xliff:g>. Вашата мрежна активност во работните апликации, заедно со е-пораките и податоците од прелистување, е видлива за вашиот IT-администратор."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Уредот е поврзан на интернет преку <xliff:g id="VPN_APP_0">%1$s</xliff:g> и <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Вашата мрежна активност, вклучително е-пораките и податоците од прелистување, е видлива за IT-администраторот."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Вашите работни апликации се поврзани на интернет преку <xliff:g id="VPN_APP">%1$s</xliff:g>. Вашата мрежна активност во работните апликации, вклучително е-пораките и податоците од прелистување, е видлива за вашиот IT-администратор и давател на услуги за VPN."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"оневозможи"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Звук и вибрации"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Поставки"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Намалено на побезбедна јачина на звук"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Јачината на звукот е висока подолго од препорачаното"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Звукот е намален на побезбедна вредност"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Јачината на звукот е висока подолго од препорачаното"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Јачината на звукот на слушалките го надмина безбедното ограничување за седмицава"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Продолжете со слушање"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Намалете го звукот"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Апликацијата е закачена"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Ќе се гледа сѐ додека не го откачите. Допрете и држете „Назад“ и „Краток преглед“ за откачување."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Ќе се гледа сѐ додека не го откачите. Допрете и задржете „Назад“ и „Почетен екран“ за откачување."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Поставки"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> од <xliff:g id="ARTIST_NAME">%2$s</xliff:g> е пуштено на <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> од <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> работи"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Пушти"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Пауза"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Претходна песна"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Звучници и екрани"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Предложени уреди"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Сопрете ја споделената сесија за да ги преместите аудиовизуелните содржини на друг уред"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Сопри"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Како функционира емитувањето"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Емитување"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Луѓето во ваша близина со компатибилни уреди со Bluetooth може да ги слушаат аудиозаписите што ги емитувате"</string>
@@ -1059,7 +1062,7 @@
     <string name="non_carrier_network_unavailable" msgid="770049357024492372">"Нема други достапни мрежи"</string>
     <string name="all_network_unavailable" msgid="4112774339909373349">"Нема достапни мрежи"</string>
     <string name="turn_on_wifi" msgid="1308379840799281023">"Wi-Fi"</string>
-    <string name="tap_a_network_to_connect" msgid="1565073330852369558">"Допрете на мрежа за да се поврзете"</string>
+    <string name="tap_a_network_to_connect" msgid="1565073330852369558">"Допрете мрежа за да се поврзете"</string>
     <string name="unlock_to_view_networks" msgid="5072880496312015676">"Отклучете за да се прикажат мрежите"</string>
     <string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"Се пребаруваат мрежи…"</string>
     <string name="wifi_failed_connect_message" msgid="4161863112079000071">"Не успеа да се поврзе на мрежата"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Поврзете го пенкалото со полнач"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Слаба батерија на пенкало"</string>
     <string name="video_camera" msgid="7654002575156149298">"Видеокамера"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Не можете да се јавите од профилов"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Вашето работно правило ви дозволува да упатувате повици само од работниот профил"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Не може да повикувате од лична апликација"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Вашата организацијата ви дозволува да упатувате повици само од работни апликации"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Префрли се на работен профил"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затвори"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Инсталирајте работна апликација на телефон"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Откажи"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Приспособете го заклучениот екран"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Отклучување за приспособување на заклучениот екран"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi не е достапно"</string>
diff --git a/packages/SystemUI/res/values-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
index 4c302ff..0a42d7c 100644
--- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
@@ -87,9 +87,9 @@
     <item msgid="2075645297847971154">"Вклучено"</item>
   </string-array>
   <string-array name="tile_states_color_correction">
-    <item msgid="2840507878437297682">"Недостапна"</item>
+    <item msgid="2840507878437297682">"Недостапно"</item>
     <item msgid="1909756493418256167">"Исклучено"</item>
-    <item msgid="4531508423703413340">"Вклучена"</item>
+    <item msgid="4531508423703413340">"Вклучено"</item>
   </string-array>
   <string-array name="tile_states_inversion">
     <item msgid="3638187931191394628">"Недостапно"</item>
@@ -157,9 +157,9 @@
     <item msgid="6866424167599381915">"Вклучено"</item>
   </string-array>
   <string-array name="tile_states_qr_code_scanner">
-    <item msgid="7435143266149257618">"Недостапен"</item>
-    <item msgid="3301403109049256043">"Исклучен"</item>
-    <item msgid="8878684975184010135">"Вклучен"</item>
+    <item msgid="7435143266149257618">"Недостапно"</item>
+    <item msgid="3301403109049256043">"Исклучено"</item>
+    <item msgid="8878684975184010135">"Вклучено"</item>
   </string-array>
   <string-array name="tile_states_alarm">
     <item msgid="4936533380177298776">"Недостапно"</item>
@@ -167,9 +167,9 @@
     <item msgid="7809470840976856149">"Вклучено"</item>
   </string-array>
   <string-array name="tile_states_onehanded">
-    <item msgid="8189342855739930015">"Недостапен"</item>
-    <item msgid="146088982397753810">"Исклучен"</item>
-    <item msgid="460891964396502657">"Вклучен"</item>
+    <item msgid="8189342855739930015">"Недостапно"</item>
+    <item msgid="146088982397753810">"Исклучено"</item>
+    <item msgid="460891964396502657">"Вклучено"</item>
   </string-array>
   <string-array name="tile_states_dream">
     <item msgid="6184819793571079513">"Недостапно"</item>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index b280a7a..ddd34be 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"പങ്കിടുക"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"സ്ക്രീൻ റെക്കോർഡിംഗ് സംരക്ഷിച്ചു"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"കാണാൻ ടാപ്പ് ചെയ്യുക"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"സ്ക്രീൻ റെക്കോർഡിംഗ് ഇല്ലാതാക്കുന്നതിൽ പിശക്"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"സ്ക്രീൻ റെക്കോർഡിംഗ് സംരക്ഷിക്കുന്നതിൽ പിശക്"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"സ്ക്രീൻ റെക്കോർഡിംഗ് ആരംഭിക്കുന്നതിൽ പിശക്"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"മടങ്ങുക"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"ഹോം"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"മുഖം പരിശോധിച്ചുറപ്പിച്ചു"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"സ്ഥിരീകരിച്ചു"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"പൂർത്തിയാക്കാൻ സ്ഥിരീകരിക്കുക ടാപ്പ് ചെയ്യൂ"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുടരാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുടരാൻ അമർത്തുക."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"മുഖം തിരിച്ചറിഞ്ഞു. തുടരാൻ അമർത്തുക."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"മുഖം തിരിച്ചറിഞ്ഞു. തുടരാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"പ്രവർത്തനരഹിതമാക്കുക"</string>
     <string name="sound_settings" msgid="8874581353127418308">"ശബ്‌ദവും വൈബ്രേഷനും"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ക്രമീകരണം"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"കൂടുതൽ സുരക്ഷിതമായ നിലയിലേക്ക് വോളിയം കുറച്ചു"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"നിർദ്ദേശിച്ചതിനേക്കാൾ കൂടുതൽ സമയം വോളിയം ഉയർന്ന നിലയിലായിരുന്നു"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"സുരക്ഷിതമായ തലത്തിലേക്ക് വോളിയം കുറച്ചു"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"നിർദ്ദേശിച്ചിരിക്കുന്നതിനേക്കാൾ കൂടുതൽ സമയം ഹെഡ്‌ഫോണിന്റെ വോളിയം ഉയർന്ന നിലയിലായിരുന്നു"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ഹെഡ്‌ഫോണിന്റെ വോളിയം ഈ ആഴ്‌ചത്തെ സുരക്ഷിത പരിധി കവിഞ്ഞു"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"കേൾക്കുന്നത് തുടരുക"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"വോളിയം കുറയ്‌ക്കുക"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"ആപ്പ് പിൻ ചെയ്തു"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"നിങ്ങൾ അൺപിൻ ചെയ്യുന്നതുവരെ ഇത് കാണുന്ന വിധത്തിൽ നിലനിർത്തും. അൺപിൻ ചെയ്യാൻ \'തിരികെ\', \'ചുരുക്കവിവരണം\' എന്നിവ സ്‌പർശിച്ച് പിടിക്കുക."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"നിങ്ങൾ അൺപിൻ ചെയ്യുന്നതുവരെ ഇത് കാണുന്ന വിധത്തിൽ നിലനിർത്തും. അൺപിൻ ചെയ്യാൻ \'തിരികെ പോവുക\', \'ഹോം\' ബട്ടണുകൾ സ്‌പർശിച്ച് പിടിക്കുക."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ക്രമീകരണം"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> എന്ന ആർട്ടിസ്റ്റിന്റെ <xliff:g id="SONG_NAME">%1$s</xliff:g> എന്ന ഗാനം <xliff:g id="APP_LABEL">%3$s</xliff:g> ആപ്പിൽ പ്ലേ ചെയ്യുന്നു"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>-ൽ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> റൺ ചെയ്യുന്നു"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"പ്ലേ ചെയ്യുക"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"താൽക്കാലികമായി നിർത്തുക"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"മുമ്പത്തെ ട്രാക്ക്"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"നിങ്ങളുടെ സ്റ്റൈലസ് ചാർജറുമായി കണക്റ്റ് ചെയ്യുക"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"സ്റ്റൈലസിന്റെ ബാറ്ററി ചാർജ് കുറവാണ്"</string>
     <string name="video_camera" msgid="7654002575156149298">"വീഡിയോ ക്യാമറ"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"ഈ പ്രൊഫൈലിൽ നിന്ന് കോൾ ചെയ്യാനാകില്ല"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"ഔദ്യോഗിക പ്രൊഫൈലിൽ നിന്ന് മാത്രം ഫോൺ കോളുകൾ ചെയ്യാനാണ് നിങ്ങളുടെ ഔദ്യോഗിക നയം അനുവദിക്കുന്നത്"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"വ്യക്തിപര ആപ്പിൽ നിന്ന് കോൾ ചെയ്യാനാകില്ല"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"സ്ഥാപനം ഔദ്യോഗിക ആപ്പുകളിൽ നിന്ന് കോളുകൾ ചെയ്യാൻ മാത്രമേ നിങ്ങളെ അനുവദിക്കുന്നുള്ളൂ"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ഔദ്യോഗിക പ്രൊഫൈലിലേക്ക് മാറുക"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"അടയ്ക്കുക"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ഔദ്യോഗിക ഫോൺ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്യുക"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"റദ്ദാക്കുക"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ലോക്ക് സ്‌ക്രീൻ ഇഷ്ടാനുസൃതമാക്കൂ"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ലോക്ക് സ്ക്രീൻ ഇഷ്ടാനുസൃതമാക്കാൻ അൺലോക്ക് ചെയ്യുക"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"വൈഫൈ ലഭ്യമല്ല"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index d2c2a1d..bb92324 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Хуваалцах"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Дэлгэцийн бичлэгийг хадгалсан"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Харахын тулд товшино уу"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Дэлгэцийн бичлэгийг устгахад алдаа гарлаа"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Дэлгэцийн бичлэгийг хадгалахад алдаа гарлаа"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Дэлгэцийн бичлэгийг эхлүүлэхэд алдаа гарлаа"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Буцах"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Гэрийн"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Царайг баталгаажууллаа"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Баталгаажсан"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Дуусгахын тулд баталгаажуулахыг товших"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Царайгаар түгжээг тайлсан. Үргэлжлүүлэхийн тулд түгжээг тайлах дүрс тэмдэг дээр дараарай."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Царайгаар түгжээг тайлсан. Үргэлжлүүлэхийн тулд дарна уу."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Царайг таньсан. Үргэлжлүүлэхийн тулд дарна уу."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Царайг таньсан. Үргэлжлүүлэх бол түгжээг тайлах дүрсийг дар."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"идэвхгүй болгох"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Дуу, чичиргээ"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Тохиргоо"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Аюулгүй дууны түвшин рүү багасгасан"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Дууны түвшин санал болгосноос удаан хугацааны туршид өндөр байсан"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Дууны түвшнийг илүү аюулгүй түвшин рүү багасгасан"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Чихэвчийн дууны түвшин санал болгосноос удаан хугацааны туршид өндөр байсан"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Чихэвчийн дууны түвшин энэ долоо хоногийн аюулгүй хязгаараас хэтэрсэн"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Сонссоор байх"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Дууны түвшнийг багасгах"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Аппыг бэхэлсэн"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Таныг тогтоосныг болиулах хүртэл үүнийг харуулна. Тогтоосныг болиулахын тулд Буцах, Тоймыг дараад хүлээнэ үү."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Таныг тогтоосныг болиулах хүртэл үүнийг харуулсан хэвээр байна. Тогтоосныг болиулахын тулд Буцах, Нүүр хуудас товчлуурыг дараад хүлээнэ үү."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Тохиргоо"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> дээр тоглуулж буй <xliff:g id="ARTIST_NAME">%2$s</xliff:g>-н <xliff:g id="SONG_NAME">%1$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>-н <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ажиллаж байна"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Тоглуулах"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Түр зогсоох"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Өмнөх бичлэг"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Чанга яригч ба дэлгэц"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Санал болгосон төхөөрөмжүүд"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Өөр төхөөрөмж рүү медиа зөөхийн тулд хуваалцсан харилцан үйлдлээ зогсооно уу"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Зогсоох"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Нэвтрүүлэлт хэрхэн ажилладаг вэ?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Нэвтрүүлэлт"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Тохиромжтой Bluetooth төхөөрөмжүүдтэй таны ойролцоох хүмүүс таны нэвтрүүлж буй медиаг сонсох боломжтой"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Мэдрэгч үзгээ цэнэглэгчтэй холбоорой"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Мэдрэгч үзэгний батарей бага байна"</string>
     <string name="video_camera" msgid="7654002575156149298">"Видео камер"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Энэ профайлаас залгах боломжгүй"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Таны ажлын бодлого танд зөвхөн ажлын профайлаас утасны дуудлага хийхийг зөвшөөрдөг"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Хувийн аппаас залгах боломжгүй"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Танай байгууллага танд зөвхөн ажлын аппуудаас дуудлага хийхийг зөвшөөрдөг"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Ажлын профайл руу сэлгэх"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Хаах"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Ажлын гар утасны апп суулгах"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Цуцлах"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Түгжигдсэн дэлгэцийг өөрчлөх"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Түгжээтэй дэлгэцийг өөрчлөхийн тулд түгжээг тайлна уу"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi боломжгүй байна"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index f8ae0e1..8c6fafe 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"शेअर करा"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"स्क्रीन रेकॉर्डिंग सेव्ह केली"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"पाहण्यासाठी टॅप करा"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रीन रेकॉर्डिंग हटवताना एरर आली"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"स्क्रीन रेकॉर्डिंग सेव्ह करताना एरर आली"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रीन रेकॉर्डिंग सुरू करताना एरर आली"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"मागे"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"होम"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"चेहरा ऑथेंटिकेशन केलेला आहे"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"निश्चित केले"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"पूर्ण करण्यासाठी खात्री करा वर टॅप करा"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"चेहऱ्याने अनलॉक केले. सुरू ठेवण्यासाठी अनलॉक करा आयकन प्रेस करा."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहऱ्याने अनलॉक केले आहे. पुढे सुरू ठेवण्यासाठी प्रेस करा."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी प्रेस करा."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी अनलॉक करा आयकन प्रेस करा."</string>
@@ -261,7 +262,7 @@
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"नेटवर्क उपलब्ध नाहीत"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"वाय-फाय नेटवर्क उपलब्‍ध नाहीत"</string>
     <string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"सुरू करत आहे…"</string>
-    <string name="quick_settings_cast_title" msgid="2279220930629235211">"स्क्रीन कास्ट करा"</string>
+    <string name="quick_settings_cast_title" msgid="2279220930629235211">"स्क्रीन कास्ट"</string>
     <string name="quick_settings_casting" msgid="1435880708719268055">"कास्ट करत आहे"</string>
     <string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"निनावी डिव्हाइस"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"कोणतेही डिव्हाइसेस उपलब्ध नाहीत"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"बंद करा"</string>
     <string name="sound_settings" msgid="8874581353127418308">"आवाज आणि व्हायब्रेशन"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"सेटिंग्ज"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"सुरक्षित आवाजापर्यंत कमी केले"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"आवाजाची पातळी शिफारस केलेल्या वेळेपेक्षा जास्त वेळ उच्च आहे"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"व्हॉल्यूम सुरक्षित पातळीपर्यंत कमी केला"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"व्हॉल्यूम हा शिफारस केलेल्या वेळेपेक्षा जास्त वेळ उच्च आहे"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"हेडफोनच्या व्हॉल्यूमने या आठवड्यासाठीची सुरक्षिततेची मर्यादा ओलांडली आहे"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"ऐकत रहा"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"व्हॉल्यूम कमी करा"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"ॲप पिन केले आहे"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"तुम्ही अनपिन करेर्यंत हे यास दृश्यामध्ये ठेवते. अनपिन करण्‍यासाठी परत आणि विहंगावलोकनास स्पर्श करा आणि धरून ठेवा."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"तुम्ही अनपिन करेर्यंत हे त्याला दृश्यामध्ये ठेवते. अनपिन करण्‍यासाठी मागे आणि होम वर स्पर्श करा आणि धरून ठेवा."</string>
@@ -716,8 +720,8 @@
     <string name="right_keycode" msgid="2480715509844798438">"उजवा कीकोड"</string>
     <string name="left_icon" msgid="5036278531966897006">"डावे आयकन"</string>
     <string name="right_icon" msgid="1103955040645237425">"उजवे आयकन"</string>
-    <string name="drag_to_add_tiles" msgid="8933270127508303672">"टाइल जोडण्यासाठी धरून ठेवा आणि ड्रॅग करा"</string>
-    <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"टाइलची पुनर्रचना करण्यासाठी धरून ठेवा आणि ड्रॅग करा"</string>
+    <string name="drag_to_add_tiles" msgid="8933270127508303672">"टाइल जोडण्यासाठी धरून ठेवून ड्रॅग करा"</string>
+    <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"टाइलची पुनर्रचना करण्यासाठी धरून ठेवून ड्रॅग करा"</string>
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"काढण्यासाठी येथे ड्रॅग करा"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"तुम्हाला किमान <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> टाइलची गरज आहे"</string>
     <string name="qs_edit" msgid="5583565172803472437">"संपादित करा"</string>
@@ -754,7 +758,7 @@
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> सेटिंग्ज उघडा."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"सेटिंग्जचा क्रम संपादित करा."</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"पॉवर मेनू"</string>
-    <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"पेज <xliff:g id="ID_2">%2$d</xliff:g> पैकी <xliff:g id="ID_1">%1$d</xliff:g>"</string>
+    <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> पैकी <xliff:g id="ID_1">%1$d</xliff:g> पेज"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"लॉक स्‍क्रीन"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"तापल्‍यामुळे फोन बंद झाला"</string>
     <string name="thermal_shutdown_message" msgid="6142269839066172984">"तुमचा फोन आता नेहमीप्रमाणे काम करत आहे.\nअधिक माहितीसाठी टॅप करा"</string>
@@ -903,7 +907,7 @@
     <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g> स्थानावर हलवा"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"नियंत्रणे"</string>
     <string name="controls_favorite_subtitle" msgid="5818709315630850796">"झटपट अ‍ॅक्सेस करण्यासाठी डिव्हाइस नियंत्रणे निवडा"</string>
-    <string name="controls_favorite_rearrange" msgid="5616952398043063519">"नियंत्रणांची पुनर्रचना करण्यासाठी धरून ठेवा आणि ड्रॅग करा"</string>
+    <string name="controls_favorite_rearrange" msgid="5616952398043063519">"नियंत्रणांची पुनर्रचना करण्यासाठी धरून ठेवून ड्रॅग करा"</string>
     <string name="controls_favorite_removed" msgid="5276978408529217272">"सर्व नियंत्रणे काढून टाकली आहेत"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"बदल सेव्ह केले गेले नाहीत"</string>
     <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"इतर अ‍ॅप्स पहा"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग्ज"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> मध्ये <xliff:g id="ARTIST_NAME">%2$s</xliff:g> चे <xliff:g id="SONG_NAME">%1$s</xliff:g> प्ले होत आहे"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> पैकी <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> रन होत आहे"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"प्ले करा"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"थांबवा"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"मागील गाणे"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"स्पीकर आणि डिस्प्ले"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"सुचवलेली डिव्हाइस"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"मीडिया दुसऱ्या डिव्हाइसवर शेअर करण्यासाठी तुमचे शेअर केलेले सेशन थांबवा"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"थांबवा"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ब्रॉडकास्टिंग कसे काम करते"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ब्रॉडकास्ट करा"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"कंपॅटिबल ब्लूटूथ डिव्‍हाइस असलेले तुमच्या जवळपासचे लोक हे तुम्ही ब्रॉडकास्ट करत असलेला मीडिया ऐकू शकतात"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"तुमचे स्टायलस चार्जरशी कनेक्ट करा"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"स्टायलस बॅटरी कमी आहे"</string>
     <string name="video_camera" msgid="7654002575156149298">"व्हिडिओ कॅमेरा"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"या प्रोफाइलवरून कॉल करू शकत नाही"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"तुमचे कामाशी संबंधित धोरण तुम्हाला फक्त कार्य प्रोफाइलवरून फोन कॉल करन्याची अनुमती देते"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"वैयक्तिक ॲपवरून कॉल करू शकत नाही"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"तुमची संस्था तुम्हाला फक्त work app वरून कॉल करण्याची अनुमती देते"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"कार्य प्रोफाइलवर स्विच करा"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"बंद करा"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"कामाशी संबंधित फोन अ‍ॅप इंस्टॉल करा"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"रद्द करा"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"कस्टमाइझ लॉक स्‍क्रीन"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"लॉक स्‍क्रीन कस्टमाइझ करण्यासाठी अनलॉक करा"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"वाय-फाय उपलब्ध नाही"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index ad89559..db4bff0 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Kongsi"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Rakaman skrin disimpan"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Ketik untuk lihat"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ralat semasa memadamkan rakaman skrin"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Ralat semasa menyimpan rakaman skrin"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Ralat semasa memulakan rakaman skrin"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Kembali"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Rumah"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Wajah disahkan"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Disahkan"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Ketik Sahkan untuk menyelesaikan"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Dibuka kunci dengan wajah. Tekan ikon buka kunci untuk teruskan."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Dibuka kunci dengan wajah. Tekan untuk meneruskan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Wajah dicam. Tekan untuk meneruskan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Wajah dicam. Tekan ikon buka kunci untuk meneruskan."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"lumpuhkan"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Bunyi &amp; getaran"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Tetapan"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Dikurangkan kepada kelantangan yang lebih selamat"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Kelantangan tinggi melebihi tempoh yang disyorkan"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Kelantangan dikurangkan kepada tahap yang lebih selamat"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Kelantangan fon kepala tinggi melebihi tempoh yang disyorkan"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Kelantangan fon kepala anda telah melebihi had selamat untuk minggu ini"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Teruskan mendengar"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Kurangkan kelantangan"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Apl telah disemat"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Tindakan ini memastikan skrin kelihatan sehingga anda menyahsemat. Sentuh &amp; tahan Kembali dan Ikhtisar untuk menyahsemat."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Tindakan ini memastikan skrin kelihatan sehingga anda menyahsemat. Sentuh &amp; tahan Kembali dan Skrin Utama untuk menyahsemat."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Tetapan"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> dimainkan daripada <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> daripada <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang dijalankan"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Main"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Jeda"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Lagu sebelumnya"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Sambungkan stilus anda kepada pengecas"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Bateri stilus lemah"</string>
     <string name="video_camera" msgid="7654002575156149298">"Kamera video"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Tidak dapat membuat panggilan daripada profil ini"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Dasar kerja anda membenarkan anda membuat panggilan telefon hanya daripada profil kerja"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Tidak boleh membuat panggilan daripada apl peribadi"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Organisasi anda hanya membenarkan anda membuat panggilan daripada apl kerja"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Tukar kepada profil kerja"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tutup"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Pasang apl telefon kerja"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Batal"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Sesuaikan skrin kunci"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Buka kunci untuk menyesuaikan skrin kunci"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi tidak tersedia"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index f6891d5..36f6344 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"မျှဝေရန်"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"စကရင်ရိုက်ကူးမှု သိမ်းပြီးပြီ"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"ကြည့်ရှုရန် တို့ပါ"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"ဖန်သားပြင် ရိုက်ကူးမှု ဖျက်ရာတွင် အမှားအယွင်းရှိနေသည်"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"ဖန်သားပြင်ရိုက်ကူးမှုကို သိမ်းရာတွင် အမှားရှိသည်"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"ဖန်သားပြင် ရိုက်ကူးမှု စတင်ရာတွင် အမှားအယွင်းရှိနေသည်"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"နောက်သို့"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"ပင်မစာမျက်နှာ"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"မျက်နှာ အထောက်အထားစိစစ်ပြီးပြီ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"အတည်ပြုပြီးပြီ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"အပြီးသတ်ရန်အတွက် \'အတည်ပြုရန်\' ကို တို့ပါ"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"မျက်နှာပြ လော့ခ်ဖွင့်ထားသည်။ လော့ခ်ဖွင့်သင်္ကေတနှိပ်၍ ရှေ့ဆက်ပါ။"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ရှေ့ဆက်ရန် နှိပ်ပါ။"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"မျက်နှာ မှတ်မိသည်။ ရှေ့ဆက်ရန် နှိပ်ပါ။"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"မျက်နှာ မှတ်မိသည်။ ရှေ့ဆက်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ။"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"ပိတ်ရန်"</string>
     <string name="sound_settings" msgid="8874581353127418308">"အသံနှင့် တုန်ခါမှု"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ဆက်တင်များ"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"ပိုအန္တရာယ်ကင်းသော အသံသို့ လျှော့ထားသည်"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"အသံကို အကြံပြုထားသည်ထက် ပိုကြာမြင့်စွာ ချဲ့ထားသည်"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"အသံကို ဘေးကင်းသည့်အဆင့်သို့ တိုးထားသည်"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"နားကြပ်အသံအား အကြံပြုထားသည်ထက် ပိုကြာရှည်စွာ ချဲ့ထားသည်"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"နားကြပ်အသံသည် ဤအပတ်အတွက် ဘေးကင်းသည့်ကန့်သတ်ချက်ထက် ကျော်သွားပါပြီ"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"ဆက်နားဆင်ရန်"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"အသံတိုးရန်"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"အက်ပ်ကို ပင်ထိုးထားသည်"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"သင်ပင်မဖြုတ်မခြင်း ၎င်းကို ပြသထားပါမည်။ ပင်ဖြုတ်ရန် Back နှင့် Overview ကို ထိ၍ဖိထားပါ။"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"သင်က ပင်မဖြုတ်မခြင်း ၎င်းကို ပြသထားပါမည်။ ပင်ဖြုတ်ရန် \'နောက်သို့\' နှင့် \'ပင်မ\' ခလုတ်တို့ကို တို့၍ဖိထားပါ။"</string>
@@ -908,7 +912,7 @@
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"အပြောင်းအလဲများကို သိမ်းမထားပါ"</string>
     <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"အခြားအက်ပ်များကိုကြည့်ပါ"</string>
     <string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"ပြန်စီရန်"</string>
-    <string name="controls_favorite_add_controls" msgid="1221420435546694004">"သတ်မှတ်ချက်များ ထည့်ရန်"</string>
+    <string name="controls_favorite_add_controls" msgid="1221420435546694004">"ထိန်းချုပ်မှုများ ထည့်ရန်"</string>
     <string name="controls_favorite_back_to_editing" msgid="184125114090062713">"တည်းဖြတ်ခြင်းသို့ ပြန်သွားရန်"</string>
     <string name="controls_favorite_load_error" msgid="5126216176144877419">"ထိန်းချုပ်မှုများကို ဖွင့်၍မရပါ။ အက်ပ်ဆက်တင်များ ပြောင်းမထားကြောင်း သေချာစေရန် <xliff:g id="APP">%s</xliff:g> အက်ပ်ကို စစ်ဆေးပါ။"</string>
     <string name="controls_favorite_load_none" msgid="7687593026725357775">"ကိုက်ညီသော ထိန်းချုပ်မှုများကို မရရှိနိုင်ပါ"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ဆက်တင်များ"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ၏ <xliff:g id="SONG_NAME">%1$s</xliff:g> ကို <xliff:g id="APP_LABEL">%3$s</xliff:g> တွင် ဖွင့်ထားသည်"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> အနက် <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ပွင့်နေပါသည်"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"ဖွင့်ရန်"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"ခဏရပ်ရန်"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"ယခင် တစ်ပုဒ်"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"စပီကာနှင့် ဖန်သားပြင်များ"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"အကြံပြုထားသော စက်ပစ္စည်းများ"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"အခြားစက်သို့ မီဒီယာရွှေ့ပြောင်းရန် သင်၏မျှဝေထားသောစက်ရှင်ကို ရပ်ပါ"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"ရပ်ရန်"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ထုတ်လွှင့်မှုဆောင်ရွက်ပုံ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ထုတ်လွှင့်ခြင်း"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"အနီးရှိတွဲသုံးနိုင်သော ဘလူးတုသ်သုံးစက် အသုံးပြုသူများက သင်ထုတ်လွှင့်နေသော မီဒီယာကို နားဆင်နိုင်သည်"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"စတိုင်လပ်စ်ကို အားသွင်းကိရိယာနှင့် ချိတ်ဆက်ခြင်း"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"စတိုင်လပ်စ် ဘက်ထရီ အားနည်းနေသည်"</string>
     <string name="video_camera" msgid="7654002575156149298">"ဗီဒီယိုကင်မရာ"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"ဤပရိုဖိုင်မှ ခေါ်ဆို၍ မရပါ"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"သင့်အလုပ်မူဝါဒသည် သင့်အား အလုပ်ပရိုဖိုင်မှသာ ဖုန်းခေါ်ဆိုခွင့် ပြုသည်"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"ကိုယ်ရေးသုံးအက်ပ်မှ ဖုန်းဆက်၍မရပါ"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"သင့်အဖွဲ့အစည်းသည် သင့်အား အလုပ်သုံးအက်ပ်များမှသာ ဖုန်းဆက်ခွင့်ပြုသည်"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"အလုပ်ပရိုဖိုင်သို့ ပြောင်းရန်"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"ပိတ်ရန်"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"အလုပ်သုံး ဖုန်းအက်ပ် ထည့်သွင်းရန်"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"မလုပ်တော့"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"လော့ခ်မျက်နှာပြင်စိတ်ကြိုက်လုပ်ရန်"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"လော့ခ်မျက်နှာပြင် စိတ်ကြိုက်လုပ်ရန် ဖွင့်ပါ"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi မရနိုင်ပါ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 556cbaf..36bd3b4 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Del"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Skjermopptaket er lagret"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Trykk for å se"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Feil ved sletting av skjermopptaket"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Feil ved lagring av skjermopptaket"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Feil ved start av skjermopptaket"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Tilbake"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Startside"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansiktet er autentisert"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekreftet"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Trykk på Bekreft for å fullføre"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Låst opp med ansiktet. Trykk på lås opp-ikonet for å fortsette"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Låst opp med ansiktet. Trykk for å fortsette."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansiktet er gjenkjent. Trykk for å fortsette."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet er gjenkjent. Trykk på lås opp-ikon for å fortsette"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktiver"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Lyd og vibrering"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Innstillinger"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Redusert til et tryggere volum"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Volumet har vært høyt lengre enn anbefalt"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Senk volumet til et tryggere nivå"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Volumet på hodetelefonene har vært høyt lenger enn anbefalt"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Volumet på hodetelefonene har overskredet sikkerhetsgrensen for denne uken"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Fortsett å lytte"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Senk volumet"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Appen er festet"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Gjør at den vises til du løsner den. Trykk og hold inne Tilbake og Oversikt for å løsne den."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Gjør at den vises til du løsner den. Trykk og hold inne Tilbake og Startside for å løsne den."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Innstillinger"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> av <xliff:g id="ARTIST_NAME">%2$s</xliff:g> spilles av fra <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> av <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> kjører"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Spill av"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pause"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Forrige spor"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Høyttalere og skjermer"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Foreslåtte enheter"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Stopp den delte økten for å flytte medieinnholdet til en annen enhet"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Stopp"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Slik fungerer kringkasting"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Kringkasting"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Folk i nærheten med kompatible Bluetooth-enheter kan lytte til mediene du kringkaster"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Koble pekepennen til en lader"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Det er lite batteri i pekepennen"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Kan ikke ringe fra denne profilen"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Som følge av jobbreglene dine kan du bare starte telefonanrop fra jobbprofilen."</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Kan ikke ringe fra personlige apper"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Organisasjonen din tillater bare at du ringer fra jobbapper"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Bytt til jobbprofilen"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Lukk"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installer en jobbapp på telefonen"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Avbryt"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Tilpass låseskjermen"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Du må låse opp enheten for å tilpasse låseskjermen"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi er ikke tilgjengelig"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index e128382..98e0201 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"सेयर गर्नुहोस्"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"स्क्रिन रेकर्डिङ सेभ गरियो"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"हेर्नका लागि ट्याप गर्नुहोस्"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"स्क्रिनको रेकर्डिङ मेट्ने क्रममा त्रुटि"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"स्क्रिन रेकर्डिङ सेभ गर्ने क्रममा त्रुटि भयो"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"स्क्रिन रेकर्ड गर्न थाल्ने क्रममा त्रुटि भयो"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"पछाडि"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"गृह"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"अनुहार प्रमाणीकरण गरियो"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"पुष्टि भयो"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"पूरा गर्नका लागि पुष्टि गर्नुहोस् नामक विकल्पमा ट्याप गर्नुहोस्"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"अनुहार प्रयोग गरी अनलक गरियो। जारी राख्न अनलक आइकनमा थिच्नुहोस्।"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"अनुहार प्रयोग गरी अनलक गरियो। जारी राख्न थिच्नुहोस्।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"अनुहार पहिचान गरियो। जारी राख्न थिच्नुहोस्।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"अनुहार पहिचान गरियो। जारी राख्न अनलक आइकनमा थिच्नुहोस्।"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"असक्षम पार्नुहोस्"</string>
     <string name="sound_settings" msgid="8874581353127418308">"साउन्ड तथा भाइब्रेसन"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"सेटिङ"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"तपाईं आरामदायी तरिकाले अडियो सुन्न सक्नुहोस् भन्नाका लागि भोल्युम घटाइएको छ"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"सिफारिस गरिएको समयभन्दा बढी समयदेखि भोल्युमको स्तर उच्च छ"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"भोल्युम घटाएर सुरक्षित स्तरमा पुर्‍याइएको छ"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"हेडफोनको भोल्युम सिफारिस गरिएको समयभन्दा लामो समयदेखि उच्च छ"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"यो हप्ता हेडफोनको भोल्युमले सुरक्षित स्तरको सीमा नाघेको छ"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"सुनिराख्नुहोस्"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"भोल्युम घटाउनुहोस्"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"एप पिन गरिएको छ"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न पछाडि र परिदृश्य बटनलाई टच एण्ड होल्ड गर्नुहोस्।"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न पछाडि र गृह नामक बटनहरूलाई टच एण्ड होल्ड गर्नुहोस्।"</string>
@@ -908,7 +912,7 @@
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"परिवर्तनहरू सुरक्षित गरिएका छैनन्"</string>
     <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"अन्य एपहरू हेर्नुहोस्"</string>
     <string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"पुनः मिलाउनुहोस्"</string>
-    <string name="controls_favorite_add_controls" msgid="1221420435546694004">"कन्ट्रोलहरू थप्नुहोस्"</string>
+    <string name="controls_favorite_add_controls" msgid="1221420435546694004">"कन्ट्रोलहरू हाल्नुहोस्"</string>
     <string name="controls_favorite_back_to_editing" msgid="184125114090062713">"सम्पादन गर्ने स्क्रिनमा फर्कनुहोस्"</string>
     <string name="controls_favorite_load_error" msgid="5126216176144877419">"नियन्त्रण सुविधाहरू लोड गर्न सकिएन। <xliff:g id="APP">%s</xliff:g> एपका सेटिङ परिवर्तन गरिएका छैनन् भन्ने कुरा सुनिश्चित गर्न उक्त एप जाँच्नुहोस्।"</string>
     <string name="controls_favorite_load_none" msgid="7687593026725357775">"मिल्दा नियन्त्रण सुविधाहरू उपलब्ध छैनन्"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिङ"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> को <xliff:g id="SONG_NAME">%1$s</xliff:g> बोलको गीत <xliff:g id="APP_LABEL">%3$s</xliff:g> मा बज्दै छ"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> मध्ये <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> चलिरहेको छ"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"प्ले गर्नुहोस्"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"पज गर्नुहोस्"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"अघिल्लो ट्रयाक"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"आफ्नो स्टाइलस चार्जरमा कनेक्ट गर्नुहोस्"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"स्टाइलसको ब्याट्री लो छ"</string>
     <string name="video_camera" msgid="7654002575156149298">"भिडियो क्यामेरा"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"यो प्रोफाइलबाट कल गर्न सकिँदैन"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"तपाईंको कामसम्बन्धी नीतिअनुसार कार्य प्रोफाइलबाट मात्र फोन कल गर्न सकिन्छ"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"व्यक्तिगत एपमार्फत कल गर्न मिल्दैन"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"तपाईंको सङ्गठनले तपाईंलाई कामसम्बन्धी एपहरूमार्फत मात्र कल गर्ने अनुमति दिन्छ"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"कार्य प्रोफाइल प्रयोग गर्नुहोस्"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"बन्द गर्नुहोस्"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"कामसम्बन्धी फोन एप इन्स्टल गर्नुहोस्"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"रद्द गर्नुहोस्"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"लक स्क्रिन कस्टमाइज गर्नुहोस्"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"लक स्क्रिन कस्टमाइज गर्न अनलक गर्नुहोस्"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi उपलब्ध छैन"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index c660f1e..53f0853 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Delen"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Schermopname opgeslagen"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Tik om te bekijken"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Fout bij verwijderen van schermopname"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Fout bij opslaan van schermopname"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Fout bij starten van schermopname"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Terug"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Startscherm"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Gezicht geverifieerd"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bevestigd"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tik op Bevestigen om te voltooien"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ontgrendeld via gezicht. Druk op het ontgrendelicoon."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ontgrendeld via gezicht. Druk om door te gaan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gezicht herkend. Druk om door te gaan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gezicht herkend. Druk op het ontgrendelicoon."</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Er is een certificeringsinstantie geïnstalleerd op dit apparaat. Je beveiligde netwerkverkeer kan worden bijgehouden of aangepast."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Je beheerder heeft de netwerkregistratie aangezet, waarmee het verkeer op je apparaat wordt gecontroleerd."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Je beheerder heeft netwerkregistratie aangezet. Hiermee wordt verkeer in je werkprofiel bijgehouden, maar niet in je persoonlijke profiel."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Dit apparaat heeft verbinding met internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Je netwerkactiviteit, waaronder e-mails en browsegegevens, is zichtbaar voor de VPN-provider."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Dit apparaat is verbonden met internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Je VPN-provider kan je netwerkactiviteit zien, zoals e-mails en browsegegevens."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"Dit apparaat heeft verbinding met internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Je netwerkactiviteit, waaronder e-mails en browsegegevens, is zichtbaar voor je IT-beheerder."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Dit apparaat heeft verbinding met internet via <xliff:g id="VPN_APP_0">%1$s</xliff:g> en <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Je netwerkactiviteit, waaronder e-mails en browsegegevens, is zichtbaar voor je IT-beheerder."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Je werk-apps hebben verbinding met internet via <xliff:g id="VPN_APP">%1$s</xliff:g>. Je netwerkactiviteit in werk-apps, waaronder e-mails en browsegegevens, is zichtbaar voor je IT-beheerder en VPN-provider."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"uitzetten"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Geluid en trillen"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Instellingen"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Verlaagd naar veiliger volume"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Het volume is langer dan de aanbevolen tijd hoog geweest"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume verlaagd naar een veiliger niveau"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Het hoofdtelefoonvolume is langer dan de aanbevolen tijd hoog geweest"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Het hoofdtelefoonvolume overschrijdt de veiligheidslimiet voor deze week"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Blijven luisteren"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Volume omlaag"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"App is vastgezet"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Het scherm blijft zichtbaar totdat je het losmaakt. Tik op Terug en Overzicht en houd deze vast om het scherm los te maken."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Het scherm blijft zichtbaar totdat je het losmaakt. Tik op Terug en Home en houd deze vast om het scherm los te maken."</string>
@@ -810,7 +814,7 @@
     <string name="mobile_data_disable_message" msgid="8604966027899770415">"Je hebt dan geen toegang meer tot data of internet via <xliff:g id="CARRIER">%s</xliff:g>. Internet is alleen nog beschikbaar via wifi."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"je provider"</string>
     <string name="auto_data_switch_disable_title" msgid="5146527155665190652">"Terugschakelen naar <xliff:g id="CARRIER">%s</xliff:g>?"</string>
-    <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Mobiele data worden niet automatisch overgezet op basis van beschikbaarheid"</string>
+    <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Mobiele data wordt niet automatisch omgeschakeld op basis van beschikbaarheid"</string>
     <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"Nee, bedankt"</string>
     <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Ja, overschakelen"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"Aangezien een app een rechtenverzoek afdekt, kan Instellingen je reactie niet verifiëren."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Instellingen"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> van <xliff:g id="ARTIST_NAME">%2$s</xliff:g> wordt afgespeeld via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> van <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> is actief"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Afspelen"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pauzeren"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Vorige track"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Verbind je stylus met een oplader"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Batterij van stylus bijna leeg"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videocamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Je kunt niet bellen vanuit dit profiel"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Op basis van je werkbeleid kun je alleen bellen vanuit het werkprofiel"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Kan niet bellen vanuit een app voor persoonlijke doeleinden"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Je organisatie staat je alleen toe om te bellen vanuit werk-apps"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Overschakelen naar werkprofiel"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sluiten"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installeer een telefoon-app voor werk"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Annuleren"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Vergrendelscherm aanpassen"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Ontgrendelen om het vergrendelscherm aan te passen"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi niet beschikbaar"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 2c2718b..c33c8ba 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -105,7 +105,7 @@
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"ରେକର୍ଡିଂ ଆରମ୍ଭ କରନ୍ତୁ"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"ଅଡିଓ ରେକର୍ଡ କରନ୍ତୁ"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"ଡିଭାଇସ୍ ଅଡିଓ"</string>
-    <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"ଆପଣଙ୍କ ଡିଭାଇସରୁ ସାଉଣ୍ଡ, ଯେପରିକି ସଙ୍ଗୀତ, କଲ୍ ଏବଂ ରିଂଟୋନଗୁଡ଼ିକ"</string>
+    <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"ମ୍ୟୁଜିକ, କଲ ଏବଂ ରିଂଟୋନଗୁଡ଼ିକ ପରି ଆପଣଙ୍କ ଡିଭାଇସରୁ ସାଉଣ୍ଡ"</string>
     <string name="screenrecord_mic_label" msgid="2111264835791332350">"ମାଇକ୍ରୋଫୋନ"</string>
     <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"ଡିଭାଇସ୍ ଅଡିଓ ଏବଂ ମାଇକ୍ରୋଫୋନ୍"</string>
     <string name="screenrecord_continue" msgid="4055347133700593164">"ଆରମ୍ଭ କରନ୍ତୁ"</string>
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"ସେୟାର୍‍ କରନ୍ତୁ"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ସେଭ୍ କରାଯାଇଛି"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"ଦେଖିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"ସ୍କ୍ରିନ୍‍ ରେକର୍ଡିଂ ଡିଲିଟ୍‍ କରିବାରେ ତ୍ରୁଟି"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"ସ୍କ୍ରିନ ରେକର୍ଡିଂ ସେଭ କରିବାରେ ତ୍ରୁଟି"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବାରେ ତ୍ରୁଟି"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"ଫେରନ୍ତୁ"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"ହୋମ"</string>
@@ -134,7 +134,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ଫେସ୍ ସ୍କାନିଙ୍ଗ କରାଯାଉଛି"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ପଠାନ୍ତୁ"</string>
     <string name="cancel" msgid="1089011503403416730">"ବାତିଲ କରନ୍ତୁ"</string>
-    <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ନିଶ୍ଚିତ କରନ୍ତୁ"</string>
+    <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ପ୍ରାମାଣିକତା ବାତିଲ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ମୁହଁ ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ସୁନିଶ୍ଚିତ କରାଯାଇଛି"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ସମ୍ପୂର୍ଣ୍ଣ କରିବାକୁ ସୁନିଶ୍ଚିତ କରନ୍ତୁରେ ଟାପ୍ କରନ୍ତୁ"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଦବାନ୍ତୁ।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଦବାନ୍ତୁ।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ଏହି ଡିଭାଇସରେ ଏକ ସର୍ଟିଫିକେଟ୍‍ ଅଥରିଟି ଇନଷ୍ଟଲ୍‍ କରାଯାଇଛି। ଆପଣଙ୍କ ସୁରକ୍ଷିତ ନେଟୱର୍କ ଟ୍ରାଫିକ୍‍ ନୀରିକ୍ଷଣ କିମ୍ବା ସଂଶୋଧନ କରାଯାଇ ପାରେ।"</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"ଆପଣଙ୍କ ଆଡମିନ୍‍ ନେଟୱର୍କ ଲଗଇନ୍‍ କରିବା ଅନ୍‍ କରିଛନ୍ତି, ଯାହା ଆପଣଙ୍କ ଡିଭାଇସରେ ଟ୍ରାଫିକ୍‍ ନୀରିକ୍ଷଣ କରେ।"</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"ଆପଣଙ୍କ ଆଡମିନ୍ ନେଟୱାର୍କ ଲଗିଂ ଚାଲୁ କରିଛନ୍ତି, ଯାହା ଆପଣଙ୍କ ୱାର୍କ ପ୍ରୋଫାଇଲରେ ଟ୍ରାଫିକ୍ ନିରୀକ୍ଷଣ କରେ କିନ୍ତୁ ଆପଣଙ୍କ ବ୍ୟକ୍ତିଗତ ପ୍ରୋଫାଇଲରେ ନୁହେଁ।"</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"ଏହି ଡିଭାଇସ <xliff:g id="VPN_APP">%1$s</xliff:g> ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି। ଇମେଲ ଏବଂ ବ୍ରାଉଜିଂ ଡାଟା ସମେତ, ଆପଣଙ୍କ ନେଟୱାର୍କ କାର୍ଯ୍ୟକଳାପ VPN ପ୍ରଦାନକାରୀଙ୍କୁ ଦୃଶ୍ୟମାନ ହୋଇଥାଏ।"</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"ଏହି ଡିଭାଇସ <xliff:g id="VPN_APP">%1$s</xliff:g> ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ହୋଇଛି। ଇମେଲ ଏବଂ ବ୍ରାଉଜିଂ ଡାଟା ସମେତ, ଆପଣଙ୍କ ନେଟୱାର୍କ କାର୍ଯ୍ୟକଳାପ VPN ପ୍ରଦାନକାରୀଙ୍କୁ ଦେଖାଯାଉଛି।"</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"ଏହି ଡିଭାଇସ <xliff:g id="VPN_APP">%1$s</xliff:g> ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି। ଇମେଲ ଏବଂ ବ୍ରାଉଜିଂ ଡାଟା ସମେତ, ଆପଣଙ୍କ ନେଟୱାର୍କ କାର୍ଯ୍ୟକଳାପ ଆପଣଙ୍କର IT ଆଡମିନଙ୍କୁ ଦୃଶ୍ୟମାନ ହୋଇଥାଏ।"</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ଏହି ଡିଭାଇସ <xliff:g id="VPN_APP_0">%1$s</xliff:g> ଏବଂ <xliff:g id="VPN_APP_1">%2$s</xliff:g> ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି। ଇମେଲ ଏବଂ ବ୍ରାଉଜିଂ ଡାଟା ସମେତ, ଆପଣଙ୍କ ନେଟୱାର୍କ କାର୍ଯ୍ୟକଳାପ ଆପଣଙ୍କର IT ଆଡମିନଙ୍କୁ ଦୃଶ୍ୟମାନ ହୋଇଥାଏ।"</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"ଆପଣଙ୍କ ୱାର୍କ ଆପ୍ସ <xliff:g id="VPN_APP">%1$s</xliff:g> ମାଧ୍ୟମରେ ଇଣ୍ଟରନେଟ ସହ କନେକ୍ଟ ଅଛି। ଇମେଲ ଏବଂ ବ୍ରାଉଜିଂ ଡାଟା ସମେତ, ୱାର୍କ ଆପ୍ସରେ ଆପଣଙ୍କ ନେଟୱାର୍କ କାର୍ଯ୍ୟକଳାପ ଆପଣଙ୍କର IT ଆଡମିନ ଏବଂ VPN ପ୍ରଦାନକାରୀଙ୍କୁ ଦୃଶ୍ୟମାନ ହୋଇଥାଏ।"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"ଅକ୍ଷମ କରନ୍ତୁ"</string>
     <string name="sound_settings" msgid="8874581353127418308">"ସାଉଣ୍ଡ ଓ ଭାଇବ୍ରେସନ"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ସେଟିଂସ"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"ଭଲ୍ୟୁମକୁ ସୁରକ୍ଷିତ ସ୍ତରକୁ କମ କରାଯାଇଛି"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"ସୁପାରିଶ କରାଯାଇଥିବାଠାରୁ ଅଧିକ ସମୟ ପାଇଁ ଭଲ୍ୟୁମକୁ ଉଚ୍ଚ ସ୍ତରରେ ରଖାଯାଇଛି"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ଭଲ୍ୟୁମକୁ ସୁରକ୍ଷିତ ଲେଭେଲକୁ କମ କରାଯାଇଛି"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ସୁପାରିଶ କରାଯାଇଥିବା ଅପେକ୍ଷା ଅଧିକ ସମୟ ପାଇଁ ହେଡଫୋନର ଭଲ୍ୟୁମ ଅଧିକ ଅଛି"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ଏହି ସପ୍ତାହ ପାଇଁ ହେଡଫୋନର ଭଲ୍ୟୁମ ସୁରକ୍ଷିତ ସୀମାକୁ ଅତିକ୍ରମ କରିଛି"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"ଶୁଣିବା ଜାରି ରଖନ୍ତୁ"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"ଭଲ୍ୟୁମ କମାନ୍ତୁ"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"ଆପକୁ ପିନ୍ କରାଯାଇଛି"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"ଆପଣ ଅନପିନ୍‍ ନକରିବା ପର୍ଯ୍ୟନ୍ତ ଏହା ଦେଖାଉଥିବ। ଅନପିନ୍‍ କରିବାକୁ ସ୍ପର୍ଶ କରି ଧରିରଖନ୍ତୁ ଓ ଦେଖନ୍ତୁ।"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"ଆପଣ ଅନପିନ୍ ନକରିବା ପର୍ଯ୍ୟନ୍ତ ଏହା ଦେଖାଉଥିବ। ଅନପିନ୍ କରିବା ପାଇଁ ହୋମ ଓ ବ୍ୟାକ ବଟନକୁ ଦବାଇ ଧରନ୍ତୁ।"</string>
@@ -623,7 +627,7 @@
     <string name="keyboard_key_media_fast_forward" msgid="3572444327046911822">"ଫାଷ୍ଟ ଫର୍‌ୱାର୍ଡ"</string>
     <string name="keyboard_key_page_up" msgid="173914303254199845">"ଉପର ପୃଷ୍ଠା"</string>
     <string name="keyboard_key_page_down" msgid="9035902490071829731">"ତଳ ପୃଷ୍ଠା"</string>
-    <string name="keyboard_key_forward_del" msgid="5325501825762733459">"ଡିଲିଟ୍‌ କରନ୍ତୁ"</string>
+    <string name="keyboard_key_forward_del" msgid="5325501825762733459">"ଡିଲିଟ କରନ୍ତୁ"</string>
     <string name="keyboard_key_move_home" msgid="3496502501803911971">"ହୋମ"</string>
     <string name="keyboard_key_move_end" msgid="99190401463834854">"ସମାପ୍ତ"</string>
     <string name="keyboard_key_insert" msgid="4621692715704410493">"ଇନ୍‌ସର୍ଟ"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ସେଟିଂସ୍"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ରୁ <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ଙ୍କ <xliff:g id="SONG_NAME">%1$s</xliff:g> ଚାଲୁଛି"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>ରୁ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଚାଲୁଛି"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"ଚଲାନ୍ତୁ"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"ବିରତ କରନ୍ତୁ"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"ପୂର୍ବବର୍ତ୍ତୀ ଟ୍ରାକ"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ସ୍ପିକର ଏବଂ ଡିସପ୍ଲେଗୁଡ଼ିକ"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ପ୍ରସ୍ତାବିତ ଡିଭାଇସଗୁଡ଼ିକ"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"ଅନ୍ୟ ଏକ ଡିଭାଇସକୁ ମିଡିଆ ମୁଭ କରିବା ପାଇଁ ଆପଣଙ୍କ ସେୟାର କରାଯାଇଥିବା ସେସନକୁ ବନ୍ଦ କରନ୍ତୁ"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ବ୍ରଡକାଷ୍ଟିଂ କିପରି କାମ କରେ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ବ୍ରଡକାଷ୍ଟ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ଆପଣଙ୍କ ଆଖପାଖର କମ୍ପାଟିବଲ ବ୍ଲୁଟୁଥ ଡିଭାଇସ ଥିବା ଲୋକମାନେ ଆପଣ ବ୍ରଡକାଷ୍ଟ କରୁଥିବା ମିଡିଆ ଶୁଣିପାରିବେ"</string>
@@ -1054,7 +1057,7 @@
     <string name="mobile_data_connection_active" msgid="944490013299018227">"ସଂଯୋଗ କରାଯାଇଛି"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"ଅସ୍ଥାୟୀ ରୂପେ କନେକ୍ଟ କରାଯାଇଛି"</string>
     <string name="mobile_data_poor_connection" msgid="819617772268371434">"ଦୁର୍ବଳ କନେକ୍ସନ"</string>
-    <string name="mobile_data_off_summary" msgid="3663995422004150567">"ମୋବାଇଲ ଡାଟା ସ୍ୱତଃ-ସଂଯୋଗ ହେବ ନାହିଁ"</string>
+    <string name="mobile_data_off_summary" msgid="3663995422004150567">"ମୋବାଇଲ ଡାଟା ସ୍ୱତଃ-କନେକ୍ଟ ହେବ ନାହିଁ"</string>
     <string name="mobile_data_no_connection" msgid="1713872434869947377">"ସଂଯୋଗ ନାହିଁ"</string>
     <string name="non_carrier_network_unavailable" msgid="770049357024492372">"ଅନ୍ୟ କୌଣସି ନେଟୱାର୍କ ଉପଲବ୍ଧ ନାହିଁ"</string>
     <string name="all_network_unavailable" msgid="4112774339909373349">"କୌଣସି ନେଟୱାର୍କ ଉପଲବ୍ଧ ନାହିଁ"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ଏକ ଚାର୍ଜର ସହ ଆପଣଙ୍କ ଷ୍ଟାଇଲସକୁ କନେକ୍ଟ କରନ୍ତୁ"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"ଷ୍ଟାଇଲସ ବେଟେରୀର ଚାର୍ଜ କମ ଅଛି"</string>
     <string name="video_camera" msgid="7654002575156149298">"ଭିଡିଓ କେମେରା"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"ଏହି ପ୍ରୋଫାଇଲରୁ କଲ କରାଯାଇପାରିବ ନାହିଁ"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"ଆପଣଙ୍କ ୱାର୍କ ନୀତି ଆପଣଙ୍କୁ କେବଳ ୱାର୍କ ପ୍ରୋଫାଇଲରୁ ଫୋନ କଲ କରିବାକୁ ଅନୁମତି ଦିଏ"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"ଏକ ବ୍ୟକ୍ତିଗତ ଆପରୁ କଲ କରିପାରିବେ ନାହିଁ"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"ଆପଣଙ୍କ ସଂସ୍ଥା ଆପଣଙ୍କୁ କେବଳ ୱାର୍କ ଆପ୍ସରୁ କଲ କରିବାକୁ ଅନୁମତି ଦିଏ"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ୱାର୍କ ପ୍ରୋଫାଇଲକୁ ସ୍ୱିଚ କରନ୍ତୁ"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"ବନ୍ଦ କରନ୍ତୁ"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ଏକ ୱାର୍କ ଫୋନ ଆପ ଇନଷ୍ଟଲ କରନ୍ତୁ"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"ବାତିଲ କରନ୍ତୁ"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ଲକ ସ୍କ୍ରିନକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ଲକ ସ୍କ୍ରିନକୁ କଷ୍ଟମାଇଜ କରିବା ପାଇଁ ଅନଲକ କରନ୍ତୁ"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ୱାଇ-ଫାଇ ଉପଲବ୍ଧ ନାହିଁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index ad6a4fa..281b11a 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -100,7 +100,7 @@
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਜਾਰੀ ਹੈ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ਕਿਸੇ ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਸੈਸ਼ਨ ਲਈ ਚੱਲ ਰਹੀ ਸੂਚਨਾ"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"ਕੀ ਰਿਕਾਰਡਿੰਗ ਸ਼ੁਰੂ ਕਰਨੀ ਹੈ?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਰਿਕਾਰਡਿੰਗ ਕਰਨ ਵੇਲੇ, Android ਕੋਲ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਸਣ ਵਾਲੀ ਜਾਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਚਲਾਈ ਜਾਣ ਵਾਲੀ ਹਰੇਕ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਵਾਸਤੇ ਸਾਵਧਾਨ ਰਹੋ।"</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਰਿਕਾਰਡਿੰਗ ਕਰਨ ਵੇਲੇ, Android ਕੋਲ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਸਣ ਵਾਲੀ ਜਾਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਚਲਾਈ ਜਾਣ ਵਾਲੀ ਹਰੇਕ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਸੰਬੰਧੀ ਸਾਵਧਾਨ ਰਹੋ।"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਰਿਕਾਰਡਿੰਗ ਕਰਨ \'ਤੇ, Android ਕੋਲ ਉਸ ਐਪ \'ਤੇ ਦਿਖਾਈ ਗਈ ਜਾਂ ਚਲਾਈ ਗਈ ਹਰੇਕ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਸੰਬੰਧੀ ਸਾਵਧਾਨ ਰਹੋ।"</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"ਰਿਕਾਰਡਿੰਗ ਸ਼ੁਰੂ ਕਰੋ"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"ਆਡੀਓ ਰਿਕਾਰਡ ਕਰੋ"</string>
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"ਸਾਂਝਾ ਕਰੋ"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਰੱਖਿਅਤ ਕੀਤੀ ਗਈ"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਮਿਟਾਉਣ ਦੌਰਾਨ ਗੜਬੜ ਹੋਈ"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਰੱਖਿਅਤ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋ ਗਈ"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਵੇਲੇ ਗੜਬੜ ਹੋਈ"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"ਪਿੱਛੇ"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"ਘਰ"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ਚਿਹਰਾ ਪ੍ਰਮਾਣੀਕਿਰਤ ਹੋਇਆ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ਪੁਸ਼ਟੀ ਕੀਤੀ ਗਈ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"ਪੂਰਾ ਕਰਨ ਲਈ ਪੁਸ਼ਟੀ ਕਰੋ \'ਤੇ ਟੈਪ ਕਰੋ"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"ਬੰਦ ਕਰੋ"</string>
     <string name="sound_settings" msgid="8874581353127418308">"ਧੁਨੀ ਅਤੇ ਥਰਥਰਾਹਟ"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ਸੈਟਿੰਗਾਂ"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"ਸੁਰੱਖਿਅਤ ਸੀਮਾ ਤੱਕ ਅਵਾਜ਼ ਨੂੰ ਘਟਾਇਆ ਗਿਆ"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"ਅਵਾਜ਼ ਸਿਫ਼ਾਰਸ਼ ਕੀਤੇ ਸਮੇਂ ਤੋਂ ਲੰਮੇ ਸਮੇਂ ਤੱਕ ਉੱਚੀ ਰਹੀ ਹੈ"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ਅਵਾਜ਼ ਨੂੰ ਜ਼ਿਆਦਾ ਸੁਰੱਖਿਅਤ ਪੱਧਰ ਤੱਕ ਘੱਟ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ਹੈੱਡਫ਼ੋਨ ਦੀ ਅਵਾਜ਼ ਸਿਫ਼ਾਰਸ਼ੀ ਪੱਧਰ ਨਾਲੋਂ ਜ਼ਿਆਦਾ ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਉੱਚੀ ਰਹੀ"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ਹੈੱਡਫ਼ੋਨ ਦੀ ਅਵਾਜ਼ ਇਸ ਹਫ਼ਤੇ ਦੀ ਸੁਰੱਖਿਅਤ ਸੀਮਾ ਨੂੰ ਪਾਰ ਕਰ ਗਈ"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"ਸੁਣਦੇ ਰਹੋ"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"ਅਵਾਜ਼ ਘਟਾਓ"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"ਐਪ ਨੂੰ ਪਿੰਨ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"ਇਹ ਇਸ ਨੂੰ ਤਦ ਤੱਕ ਦ੍ਰਿਸ਼ ਵਿੱਚ ਰੱਖਦਾ ਹੈ ਜਦ ਤੱਕ ਤੁਸੀਂ ਅਨਪਿੰਨ ਨਹੀਂ ਕਰਦੇ। ਅਨਪਿੰਨ ਕਰਨ ਲਈ \'ਪਿੱਛੇ\' ਅਤੇ \'ਰੂਪ-ਰੇਖਾ\' ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਅਨਪਿੰਨ ਕੀਤੇ ਜਾਣ ਤੱਕ ਇਸਨੂੰ ਦਿਖਾਇਆ ਜਾਂਦਾ ਹੈ। ਅਨਪਿੰਨ ਕਰਨ ਲਈ \'ਪਿੱਛੇ\' ਅਤੇ \'ਹੋਮ\' ਨੂੰ ਸਪਰਸ਼ ਕਰਕੇ ਰੱਖੋ।"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ਸੈਟਿੰਗਾਂ"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ਤੋਂ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ਦਾ <xliff:g id="SONG_NAME">%1$s</xliff:g> ਚੱਲ ਰਿਹਾ ਹੈ"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> ਵਿੱਚੋਂ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਚੱਲ ਰਿਹਾ ਹੈ"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"ਚਲਾਓ"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"ਰੋਕੋ"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"ਪਿਛਲਾ ਟਰੈਕ"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ਸਪੀਕਰ ਅਤੇ ਡਿਸਪਲੇਆਂ"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ਸੁਝਾਏ ਗਏ ਡੀਵਾਈਸ"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"ਮੀਡੀਆ ਨੂੰ ਕਿਸੇ ਹੋਰ ਡੀਵਾਈਸ \'ਤੇ ਲਿਜਾਉਣ ਲਈ ਆਪਣੇ ਸਾਂਝੇ ਕੀਤੇ ਸੈਸ਼ਨ ਨੂੰ ਬੰਦ ਕਰੋ"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"ਬੰਦ ਕਰੋ"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ਪ੍ਰਸਾਰਨ ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ਪ੍ਰਸਾਰਨ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ਅਨੁਰੂਪ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨਾਲ ਨਜ਼ਦੀਕੀ ਲੋਕ ਤੁਹਾਡੇ ਵੱਲੋਂ ਪ੍ਰਸਾਰਨ ਕੀਤੇ ਜਾ ਰਹੇ ਮੀਡੀਆ ਨੂੰ ਸੁਣ ਸਕਦੇ ਹਨ"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ਆਪਣੇ ਸਟਾਈਲਸ ਨੂੰ ਚਾਰਜਰ ਨਾਲ ਕਨੈਕਟ ਕਰੋ"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"ਸਟਾਈਲਸ ਦੀ ਬੈਟਰੀ ਘੱਟ ਹੈ"</string>
     <string name="video_camera" msgid="7654002575156149298">"ਵੀਡੀਓ ਕੈਮਰਾ"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"ਇਸ ਪ੍ਰੋਫਾਈਲ ਤੋਂ ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"ਤੁਹਾਡੀ ਕਾਰਜ ਨੀਤੀ ਤੁਹਾਨੂੰ ਸਿਰਫ਼ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਤੋਂ ਹੀ ਫ਼ੋਨ ਕਾਲਾਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"ਕਿਸੇ ਨਿੱਜੀ ਐਪ ਤੋਂ ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਤੁਹਾਨੂੰ ਸਿਰਫ਼ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੋਂ ਕਾਲਾਂ ਕਰਨ ਦਿੰਦੀ ਹੈ"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ \'ਤੇ ਜਾਓ"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"ਬੰਦ ਕਰੋ"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ਕੰਮ ਸੰਬੰਧੀ ਫ਼ੋਨ ਐਪ ਸਥਾਪਤ ਕਰੋ"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"ਰੱਦ ਕਰੋ"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ਲਾਕ ਸਕ੍ਰੀਨ ਨੂੰ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ਲਾਕ ਸਕ੍ਰੀਨ ਨੂੰ ਵਿਉਂਤਬੱਧ ਕਰਨ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ਵਾਈ-ਫਾਈ ਉਪਲਬਧ ਨਹੀਂ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 0400ca3..8a9608f 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -103,7 +103,7 @@
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Podczas nagrywania Android ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Podczas nagrywania treści z aplikacji Android ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Zacznij nagrywać"</string>
-    <string name="screenrecord_audio_label" msgid="6183558856175159629">"Nagraj dźwięk"</string>
+    <string name="screenrecord_audio_label" msgid="6183558856175159629">"Nagrywaj dźwięk"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Dźwięki z urządzenia"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Dźwięki odtwarzane na urządzeniu, na przykład muzyka, połączenia i dzwonki"</string>
     <string name="screenrecord_mic_label" msgid="2111264835791332350">"Mikrofon"</string>
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Udostępnij"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Zapisano nagranie zawartości ekranu"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Kliknij, aby wyświetlić"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Błąd podczas usuwania nagrania zawartości ekranu"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Podczas zapisywania nagrania ekranu wystąpił błąd"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Błąd podczas rozpoczynania rejestracji zawartości ekranu"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Wróć"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Ekran główny"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Twarz rozpoznana"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potwierdzono"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Aby zakończyć, kliknij Potwierdź"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Odblokowano skanem twarzy. Aby kontynuować, kliknij ikonę odblokowywania."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odblokowano rozpoznawaniem twarzy. Kliknij, aby kontynuować."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Twarz rozpoznana. Kliknij, aby kontynuować."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Twarz rozpoznana. Aby kontynuować, kliknij ikonę odblokowywania."</string>
@@ -170,7 +171,7 @@
     <string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"Jest to wymagane dla podniesienia poziomu bezpieczeństwa i wydajności"</string>
     <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"Skonfiguruj ponownie odblokowywanie odciskiem palca"</string>
     <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"Odblokowywanie odciskiem palca"</string>
-    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Skonfiguruj odblokowywanie odciskiem palca"</string>
+    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Skonfiguruj odblokowywanie odciskiem palca"</string>
     <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"Bieżące obrazy i modele odcisku palca zostaną usunięte, aby można było ponownie skonfigurować odblokowywanie odciskiem palca.\n\nAby odblokowywać telefon i potwierdzać tożsamość odciskiem palca, musisz ponownie skonfigurować odblokowywanie odciskiem palca."</string>
     <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"Bieżące obrazy i modele odcisku palca zostaną usunięte, aby można było ponownie skonfigurować odblokowywanie odciskiem palca.\n\nPo ich usunięciu musisz ponownie skonfigurować odblokowywanie odciskiem palca, aby odblokowywać telefon i potwierdzać tożsamość odciskiem palca."</string>
     <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Nie udało się skonfigurować odblokowywania odciskiem palca. Przejdź do ustawień, aby spróbować jeszcze raz."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"wyłącz"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Dźwięk i wibracje"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Ustawienia"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Obniżono głośność do bezpieczniejszego poziomu"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Głośność była zbyt duża przez czas dłuższy niż zalecany"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Głośność obniżona do bezpieczniejszego poziomu"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Głośność na słuchawkach jest zbyt duża przez czas dłuższy niż zalecany"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Głośność na słuchawkach przekroczyła limit bezpieczeństwa na ten tydzień"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Słuchaj dalej"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Zmniejsz głośność"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Aplikacja jest przypięta"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Ekran będzie widoczny, dopóki go nie odepniesz. Aby to zrobić, kliknij i przytrzymaj Wstecz oraz Przegląd."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Ekran będzie widoczny, dopóki go nie odepniesz. Aby to zrobić, naciśnij i przytrzymaj Wstecz oraz Ekran główny."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Ustawienia"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Aplikacja <xliff:g id="APP_LABEL">%3$s</xliff:g> odtwarza utwór <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>)"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> z <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest uruchomiona"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Odtwórz"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Wstrzymaj"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Poprzedni utwór"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Głośniki i wyświetlacze"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Proponowane urządzenia"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Zatrzymaj udostępnianie sesji, aby przenieść multimedia na inne urządzenie"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Zatrzymaj"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jak działa transmitowanie"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmisja"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osoby w pobliżu ze zgodnymi urządzeniami Bluetooth mogą słuchać transmitowanych przez Ciebie multimediów"</string>
@@ -1117,7 +1120,7 @@
     <string name="log_access_confirmation_title" msgid="4843557604739943395">"Zezwolić aplikacji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> na dostęp do wszystkich dzienników urządzenia?"</string>
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Zezwól na jednorazowy dostęp"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nie zezwalaj"</string>
-    <string name="log_access_confirmation_body" msgid="6883031912003112634">"Dzienniki urządzenia zapisują, co dzieje się na urządzeniu. Aplikacje mogą ich używać do wykrywania i rozwiązywania problemów.\n\nNiektóre dzienniki mogą zawierać poufne dane, dlatego na dostęp do wszystkich dzienników zezwalaj tylko aplikacjom, którym ufasz. \n\nNawet jeśli nie zezwolisz tej aplikacji na dostęp do wszystkich dzienników na urządzeniu, będzie mogła korzystać z własnych. Producent urządzenia nadal będzie mógł używać niektórych dzienników na urządzeniu."</string>
+    <string name="log_access_confirmation_body" msgid="6883031912003112634">"Dzienniki urządzenia zapisują, co dzieje się na urządzeniu. Aplikacje mogą ich używać do wykrywania i rozwiązywania problemów.\n\nNiektóre dzienniki mogą zawierać poufne dane, dlatego na dostęp do wszystkich dzienników zezwalaj tylko aplikacjom, którym ufasz. \n\nNawet jeśli nie zezwolisz tej aplikacji na dostęp do wszystkich dzienników na urządzeniu, będzie mogła korzystać z własnych. Producent urządzenia nadal będzie mógł używać niektórych dzienników lub informacji na urządzeniu."</string>
     <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Więcej informacji"</string>
     <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Więcej informacji: <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otwórz: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Podłącz rysik do ładowarki"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Słaba bateria w rysiku"</string>
     <string name="video_camera" msgid="7654002575156149298">"Kamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Nie można nawiązać połączenia z tego profilu"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Zasady obowiązujące w firmie zezwalają na nawiązywanie połączeń telefonicznych tylko w profilu służbowym"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Nie można nawiązać połączenia z aplikacji osobistej"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Twoja organizacja zezwala na nawiązywanie połączeń tylko z aplikacji służbowych"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Przełącz na profil służbowy"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zamknij"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Zainstaluj służbową aplikację telefonu"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Anuluj"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Dostosuj ekran blokady"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Odblokuj, aby dostosować ekran blokady"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Sieć Wi-Fi jest niedostępna"</string>
diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
index f74985f..ea6ad58 100644
--- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
@@ -108,8 +108,8 @@
   </string-array>
   <string-array name="tile_states_work">
     <item msgid="389523503690414094">"Niedostępny"</item>
-    <item msgid="8045580926543311193">"Wyłączony"</item>
-    <item msgid="4913460972266982499">"Włączony"</item>
+    <item msgid="8045580926543311193">"Wyłączono"</item>
+    <item msgid="4913460972266982499">"Włączono"</item>
   </string-array>
   <string-array name="tile_states_cast">
     <item msgid="6032026038702435350">"Niedostępny"</item>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 233a934..4018433 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Compartilhar"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Gravação de tela salva"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao excluir a gravação de tela"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Erro ao salvar a gravação da tela"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Erro ao iniciar a gravação de tela"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Voltar"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Página inicial"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Rosto autenticado"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em \"Confirmar\" para concluir"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueado pelo rosto. Pressione o ícone de desbloqueio para continuar."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado pelo rosto. Pressione para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Pressione para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Pressione o ícone para continuar."</string>
@@ -414,7 +415,7 @@
     <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Início"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Ação bloqueada pelo administrador de TI"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"A captura de tela foi desativada pela política do dispositivo"</string>
-    <string name="clear_all_notifications_text" msgid="348312370303046130">"Limpar tudo"</string>
+    <string name="clear_all_notifications_text" msgid="348312370303046130">"Remover tudo"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gerenciar"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Histórico"</string>
     <string name="notification_section_header_incoming" msgid="850925217908095197">"Novas"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"desativar"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Som e vibração"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Configurações"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Volume diminuído para um nível mais seguro"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"O volume ficou alto por mais tempo do que o recomendado"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume diminuído para um nível mais seguro"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"O volume do fones de ouvido está alto há mais tempo que o recomendado"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"O volume dos fones de ouvido excedeu o limite de segurança para esta semana"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Continuar ouvindo"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Diminuir o volume"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"O app está fixado"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Ela é mantida à vista até que seja liberada. Toque em Voltar e em Visão geral e mantenha essas opções pressionadas para liberar."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Ela é mantida à vista até que seja liberada. Toque em Voltar e em Início e mantenha essas opções pressionadas para liberar."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tocando <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> no app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> está em execução"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Iniciar"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pausar"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Faixa anterior"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Alto-falantes e telas"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Interrompa sua sessão compartilhada para transferir mídia a outro dispositivo"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Parar"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmitir"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas a você com dispositivos Bluetooth compatíveis podem ouvir a mídia que você está transmitindo"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conecte sua stylus a um carregador"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Bateria da stylus fraca"</string>
     <string name="video_camera" msgid="7654002575156149298">"Filmadora"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Não é possível fazer uma ligação por este perfil"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Sua política de trabalho só permite fazer ligações pelo perfil de trabalho"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Não é possível fazer ligações de um app pessoal"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Sua organização só permite fazer ligações usando apps de trabalho"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Alternar para o perfil de trabalho"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalar um app de telefone no perfil de trabalho"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Cancelar"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizar a tela de bloqueio"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Desbloqueie para personalizar a tela de bloqueio"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi indisponível"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 35564b2..2d9c7d3 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Partilhar"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Gravação de ecrã guardada."</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao eliminar a gravação de ecrã."</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Erro ao guardar a gravação de ecrã"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Ocorreu um erro ao iniciar a gravação do ecrã."</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Anterior"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Página inicial"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Rosto autenticado"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmado"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em Confirmar para concluir."</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueio com a face. Prima o ícone de desb. p/ continuar."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado com o rosto. Prima para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Prima para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Prima ícone de desbloqueio para continuar"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"desativar"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Som e vibração"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Definições"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Volume reduzido para um nível mais seguro"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"O volume está elevado há mais tempo que o recomendado"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume reduzido para um nível mais seguro"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"O volume dos auscultadores está elevado há mais tempo do que o recomendado"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"O volume dos auscultadores excedeu o limite seguro para esta semana"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Continuar a ouvir"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Baixar volume"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"A app está fixada"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Esta opção mantém o item visível até o soltar. Toque sem soltar em Anterior e em Vista geral para soltar."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Esta opção mantém o item visível até o soltar. Toque sem soltar em Anterior e em Página inicial para soltar."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Definições"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> em reprodução a partir da app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> em execução"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Reproduzir"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pausar"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Faixa anterior"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Altifalantes e ecrãs"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Pare a sua sessão partilhada para mover conteúdos multimédia para outro dispositivo"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Parar"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmissão"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas de si com dispositivos Bluetooth compatíveis podem ouvir o conteúdo multimédia que está a transmitir"</string>
@@ -1064,7 +1067,7 @@
     <string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"A procurar redes…"</string>
     <string name="wifi_failed_connect_message" msgid="4161863112079000071">"Não foi possível estabelecer ligação à rede"</string>
     <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Por agora, o Wi-Fi não irá estabelecer lig. automaticamente"</string>
-    <string name="see_all_networks" msgid="3773666844913168122">"Veja tudo"</string>
+    <string name="see_all_networks" msgid="3773666844913168122">"Ver tudo"</string>
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Para mudar de rede, desligue a Ethernet"</string>
     <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Para melhorar a experiência do dispositivo, as apps e os serviços podem continuar a procurar redes Wi-Fi em qualquer altura, mesmo quando o Wi-Fi está desativado. Pode alterar esta opção nas definições de procura de Wi-Fi. "<annotation id="link">"Alterar"</annotation></string>
     <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Desativar o modo de avião"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Ligue a caneta stylus a um carregador"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Bateria da caneta stylus fraca"</string>
     <string name="video_camera" msgid="7654002575156149298">"Câmara de vídeo"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Não é possível ligar a partir deste perfil"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"A sua Política de Trabalho só lhe permite fazer chamadas telefónicas a partir do perfil de trabalho"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Não é possível ligar a partir de uma app pessoal"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"A sua organização só lhe permite fazer chamadas a partir de apps de trabalho"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Mudar para perfil de trabalho"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalar app telefone de trabalho"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Cancelar"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizar o ecrã de bloqueio"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Desbloqueie para personalizar o ecrã de bloqueio"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi indisponível"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 233a934..4018433 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Compartilhar"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Gravação de tela salva"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Toque para ver"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Erro ao excluir a gravação de tela"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Erro ao salvar a gravação da tela"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Erro ao iniciar a gravação de tela"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Voltar"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Página inicial"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Rosto autenticado"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmada"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Toque em \"Confirmar\" para concluir"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Desbloqueado pelo rosto. Pressione o ícone de desbloqueio para continuar."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado pelo rosto. Pressione para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Pressione para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Pressione o ícone para continuar."</string>
@@ -414,7 +415,7 @@
     <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Início"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Ação bloqueada pelo administrador de TI"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"A captura de tela foi desativada pela política do dispositivo"</string>
-    <string name="clear_all_notifications_text" msgid="348312370303046130">"Limpar tudo"</string>
+    <string name="clear_all_notifications_text" msgid="348312370303046130">"Remover tudo"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gerenciar"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Histórico"</string>
     <string name="notification_section_header_incoming" msgid="850925217908095197">"Novas"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"desativar"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Som e vibração"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Configurações"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Volume diminuído para um nível mais seguro"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"O volume ficou alto por mais tempo do que o recomendado"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volume diminuído para um nível mais seguro"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"O volume do fones de ouvido está alto há mais tempo que o recomendado"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"O volume dos fones de ouvido excedeu o limite de segurança para esta semana"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Continuar ouvindo"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Diminuir o volume"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"O app está fixado"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Ela é mantida à vista até que seja liberada. Toque em Voltar e em Visão geral e mantenha essas opções pressionadas para liberar."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Ela é mantida à vista até que seja liberada. Toque em Voltar e em Início e mantenha essas opções pressionadas para liberar."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tocando <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> no app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> está em execução"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Iniciar"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pausar"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Faixa anterior"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Alto-falantes e telas"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Interrompa sua sessão compartilhada para transferir mídia a outro dispositivo"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Parar"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmitir"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas a você com dispositivos Bluetooth compatíveis podem ouvir a mídia que você está transmitindo"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conecte sua stylus a um carregador"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Bateria da stylus fraca"</string>
     <string name="video_camera" msgid="7654002575156149298">"Filmadora"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Não é possível fazer uma ligação por este perfil"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Sua política de trabalho só permite fazer ligações pelo perfil de trabalho"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Não é possível fazer ligações de um app pessoal"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Sua organização só permite fazer ligações usando apps de trabalho"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Alternar para o perfil de trabalho"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalar um app de telefone no perfil de trabalho"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Cancelar"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizar a tela de bloqueio"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Desbloqueie para personalizar a tela de bloqueio"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi indisponível"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 9e0a64d..060f6d7 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Trimite"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Înregistrarea ecranului a fost salvată"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Atinge pentru a afișa"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Eroare la ștergerea înregistrării ecranului"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Eroare la salvarea înregistrării ecranului"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Eroare la începerea înregistrării ecranului"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Înapoi"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Ecranul de pornire"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Chip autentificat"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Confirmat"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Atinge Confirm pentru a finaliza"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Deblocat facial. Apasă pictograma Deblocare ca să continui."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"S-a deblocat cu ajutorul feței. Apasă pentru a continua."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Chipul a fost recunoscut. Apasă pentru a continua."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Chip recunoscut. Apasă pictograma Deblocare ca să continui."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"dezactivează"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Sunete și vibrații"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Setări"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Redus la un volum mai sigur"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Volumul a fost ridicat mai mult timp decât este recomandat"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volumul a fost redus la un nivel mai sigur"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Volumul căștilor a fost ridicat mai mult timp decât este recomandat"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Volumul căștilor a depășit limita de siguranță pentru săptămâna aceasta"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Ascultă în continuare"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Redu volumul"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Aplicația este fixată"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Astfel rămâne afișat până anulezi fixarea. Atinge lung opțiunile Înapoi și Recente pentru a anula fixarea."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Astfel rămâne afișat până anulezi fixarea. Atinge lung opțiunile Înapoi și Acasă pentru a anula fixarea."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Setări"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> de la <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se redă în <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> din <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> rulează"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Redă"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Întrerupe"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Melodia anterioară"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Conectează-ți creionul la un încărcător"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Nivelul bateriei creionului este scăzut"</string>
     <string name="video_camera" msgid="7654002575156149298">"Cameră video"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Nu poți iniția apeluri din acest profil"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Politica privind activitatea îți permite să efectuezi apeluri telefonice numai din profilul de serviciu"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Nu poți iniția apeluri dintr-o aplicație personală"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Organizația îți permite să inițiezi apeluri numai din aplicațiile pentru lucru"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Comută la profilul de serviciu"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Închide"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalează o aplicație de lucru pentru telefon"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Anulează"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizează ecranul de blocare"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Deblochează pentru a personaliza ecranul de blocare"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Conexiune Wi-Fi indisponibilă"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 0ab0485..d6530fb 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Поделиться"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Видео с экрана сохранено"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Нажмите, чтобы посмотреть."</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Не удалось удалить запись видео с экрана"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Не удалось сохранить запись видео с экрана."</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Не удалось начать запись видео с экрана."</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Главный экран"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лицо распознано"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Подтверждено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Нажмите \"Подтвердить\""</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Сканирование выполнено. Нажмите на значок разблокировки."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Разблокировано сканированием лица. Нажмите, чтобы продолжить."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицо распознано. Нажмите, чтобы продолжить."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицо распознано. Нажмите на значок разблокировки."</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"На устройстве установлен сертификат ЦС. Ваш защищенный сетевой трафик могут отслеживать и изменять."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Администратор включил ведение сетевого журнала, чтобы отслеживать трафик на вашем устройстве."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Администратор включил ведение сетевого журнала, чтобы отслеживать трафик в вашем рабочем профиле (информация из личного профиля не собирается)."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Это устройство подключено к интернету через сервис \"<xliff:g id="VPN_APP">%1$s</xliff:g>\". Ваши действия в сети, включая данные о работе с электронной почтой и в браузере, видны поставщику услуг VPN."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Это устройство подключено к интернету через сервис \"<xliff:g id="VPN_APP">%1$s</xliff:g>\". Ваши действия в сети, включая электронные письма и контент в браузере, видны поставщику услуг VPN."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"Это устройство подключено к интернету через сервис \"<xliff:g id="VPN_APP">%1$s</xliff:g>\". Ваши действия в сети, включая данные о работе с электронной почтой и в браузере, видны вашему системному администратору."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Это устройство подключено к интернету через сервисы \"<xliff:g id="VPN_APP_0">%1$s</xliff:g>\" и \"<xliff:g id="VPN_APP_1">%2$s</xliff:g>\". Ваши действия в сети, включая данные о работе с электронной почтой и в браузере, видны вашему системному администратору."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Рабочие приложения подключены к интернету через сервис \"<xliff:g id="VPN_APP">%1$s</xliff:g>\". Ваши сетевые действия в этих приложениях, включая данные о работе с электронной почтой и в браузере, видны вашему системному администратору и поставщику услуг VPN."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"отключить"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Звук и вибрация"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Открыть настройки"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Громкость уменьшена до безопасного уровня"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Громкость была высокой дольше рекомендованного периода."</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Громкость уменьшена до безопасного уровня"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Вы используете наушники при высоком уровне громкости дольше, чем рекомендуется."</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Превышен безопасный лимит громкости наушников на этой неделе."</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Слушать дальше"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Убавить звук"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Приложение закреплено"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Приложение останется активным, пока вы не отмените блокировку, нажав и удерживая кнопки \"Назад\" и \"Обзор\"."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Приложение останется активным, пока вы не отмените блокировку, нажав и удерживая кнопки \"Назад\" и \"Главный экран\"."</string>
@@ -902,7 +906,7 @@
     <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"удалить из избранного"</string>
     <string name="accessibility_control_move" msgid="8980344493796647792">"Переместить на позицию <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"Элементы управления"</string>
-    <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Выберите виджеты управления устройствами для быстрого доступа"</string>
+    <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Выберите виджеты управления устройствами для быстрого доступа."</string>
     <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Чтобы изменить порядок виджетов, перетащите их."</string>
     <string name="controls_favorite_removed" msgid="5276978408529217272">"Все виджеты управления удалены."</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Изменения не сохранены."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Настройки"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Воспроизводится медиафайл \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" (исполнитель: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) из приложения \"<xliff:g id="APP_LABEL">%3$s</xliff:g>\"."</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> из <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запущено"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Воспроизвести"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Приостановить"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Предыдущий трек"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Колонки и дисплеи"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Рекомендуемые устройства"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Чтобы перенести медиафайлы на другое устройство, закройте доступ."</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Закрыть"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Как работают трансляции"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Трансляция"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Находящиеся рядом с вами люди с совместимыми устройствами Bluetooth могут слушать медиафайлы, которые вы транслируете."</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Поставьте стилус на зарядку."</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Низкий заряд батареи стилуса"</string>
     <string name="video_camera" msgid="7654002575156149298">"Видеокамера"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Невозможно совершить звонок из этого профиля"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Согласно правилам вашей организации вы можете совершать телефонные звонки только из рабочего профиля."</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Нельзя звонить из личного приложения"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"В вашей организации разрешено звонить только из рабочих приложений."</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Перейти в рабочий профиль"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрыть"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Установить рабочее приложение для звонков"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Отмена"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Настройки заблок. экрана"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Разблокируйте устройство, чтобы настроить заблокированный экран"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Функция Wi-Fi недоступна"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index eaabf49..a5c1a18 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"බෙදා ගන්න"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"තිර පටිගත කිරීම සුරකින ලදී"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"බැලීමට තට්ටු කරන්න"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"තිර පටිගත කිරීම මැකීමේ දෝෂයකි"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"තිර පටිගත කිරීම සුරැකීමේ දෝෂයකි"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"තිර පටිගත කිරීම ආරම්භ කිරීමේ දෝෂයකි"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"ආපසු"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"මුල් පිටුව"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"මුහුණ සත්‍යාපන කළා"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"තහවුරු කළා"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"සම්පූර්ණ කිරීමට තහවුරු කරන්න තට්ටු කර."</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"මුහුණ මගින් අගුලු හරින ලදි. දිගටම කරගෙන යාමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"මුහුණ මගින් අගුලු හරින ලදි. ඉදිරියට යාමට ඔබන්න."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"මුහුණ හඳුනා ගන්නා ලදි. ඉදිරියට යාමට ඔබන්න."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"මුහුණ හඳුනා ගන්නා ලදි. ඉදිරියට යාමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"අබල කරන්න"</string>
     <string name="sound_settings" msgid="8874581353127418308">"ශබ්ද සහ කම්පනය"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"සැකසීම්"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"සුරක්ෂිත පරිමාවකට අඩු කරන ලදි"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"නිර්දේශිත ප්‍රමාණයට වඩා වැඩි කාලයක් පරිමාව ඉහළ මට්ටමක පවතී"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"හඬ පරිමාව සුරක්ෂිත මට්ටමට අඩු කරන ලදි"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"නිර්දේශිත ප්‍රමාණයට වඩා වැඩි කාලයක් හෙඩ්ෆෝන් හඬ පරිමාව ඉහළ මට්ටමක පවතී"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"හෙඩ්ෆෝන් හඬ පරිමාව මෙම සතිය සඳහා සුරක්ෂිත සීමාව ඉක්මවා ඇත"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"දිගටම සවන් දෙන්න"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"හඬ පරිමාව අඩු කරන්න"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"යෙදුම අමුණා ඇත"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"මෙය ඔබ ගලවන තෙක් එය දසුන තුළ තබයි. ගැලවීමට දළ විශ්ලේෂණය ස්පර්ශ කර ආපසු අල්ලාගෙන සිටින්න."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"මෙය ඔබ ගලවන තෙක් එය දසුන තුළ තබයි. ගැලවීමට මුල් පිටුව ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"සැකසීම්"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>ගේ <xliff:g id="SONG_NAME">%1$s</xliff:g> ගීතය <xliff:g id="APP_LABEL">%3$s</xliff:g> වෙතින් ධාවනය වෙමින් පවතී"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>කින් <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ධාවනය වේ"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"වාදනය කරන්න"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"විරාම ගන්වන්න"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"පෙර ඛණ්ඩය"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ස්පීකර් සහ සංදර්ශක"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"යෝජිත උපාංග"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"මාධ්‍ය වෙනත් උපාංගයකට ගෙන යාමට ඔබේ බෙදා ගත් සැසිය නවත්වන්න"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"නවත්වන්න"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"විකාශනය ක්‍රියා කරන ආකාරය"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"විකාශනය"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ගැළපෙන බ්ලූටූත් උපාංග සහිත ඔබ අවට සිටින පුද්ගලයින්ට ඔබ විකාශනය කරන මාධ්‍යයට සවන් දිය හැකිය"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"ඔබේ පන්හිඳ චාජරයකට සම්බන්ධ කරන්න"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"පන්හිඳ බැටරිය අඩුයි"</string>
     <string name="video_camera" msgid="7654002575156149298">"වීඩියෝ කැමරාව"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"මෙම පැතිකඩෙන් ඇමතීමට නොහැක"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"ඔබේ වැඩ ප්‍රතිපත්තිය ඔබට කාර්යාල පැතිකඩෙන් පමණක් දුරකථන ඇමතුම් ලබා ගැනීමට ඉඩ සලසයි"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"පෞද්ගලික යෙදුමකින් ඇමතිය නොහැක"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"ඔබේ සංවිධානය ඔබට කාර්යාල යෙදුම්වලින් ඇමතුම් කිරීමට පමණක් ඉඩ දෙයි"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"කාර්යාල පැතිකඩ වෙත මාරු වන්න"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"වසන්න"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"කාර්යාල දුරකථන යෙදුමක් ස්ථාපනය කරන්න"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"අවලංගු කරන්න"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"අගුළු තිරය අභිරුචිකරණය කරන්න"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"අගුළු තිරය අභිරුචිකරණය කිරීමට අගුළු හරින්න"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi ලද නොහැක"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index c2c220a..e60dd5f 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Zdieľať"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Nahrávka bola uložená"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Zobrazte klepnutím"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Pri odstraňovaní záznamu obrazovky sa vyskytla chyba"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Pri ukladaní nahrávky obrazovky sa vyskytla chyba"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Pri spustení nahrávania obrazovky sa vyskytla chyba"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Späť"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Plocha"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Tvár bola overená"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potvrdené"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Overenie dokončíte klepnutím na Potvrdiť"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Odomknuté tvárou. Pokračujte klepnutím na ikonu odomknutia"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odomknuté tvárou. Pokračujte stlačením."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Tvár bola rozpoznaná. Pokračujte stlačením."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Tvár bola rozpoznaná. Pokračujte stlačením ikony odomknutia"</string>
@@ -418,7 +419,7 @@
     <string name="manage_notifications_text" msgid="6885645344647733116">"Spravovať"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"História"</string>
     <string name="notification_section_header_incoming" msgid="850925217908095197">"Nové"</string>
-    <string name="notification_section_header_gentle" msgid="6804099527336337197">"Ticho"</string>
+    <string name="notification_section_header_gentle" msgid="6804099527336337197">"Tichý"</string>
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"Upozornenia"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzácie"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vymazať všetky tiché upozornenia"</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"V tomto zariadení je nainštalovaná certifikačná autorita. Zabezpečená sieťová premávka môže byť sledovaná či upravená."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Správca aktivoval zapisovanie do denníka siete, ktoré sleduje premávku na vašom zariadení."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Správca aktivoval zapisovanie do denníka siete, ktoré sleduje premávku vo vašom pracovnom profile, ale nie osobnom."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Toto zariadenie je k internetu pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%1$s</xliff:g>. Vašu aktivitu v sieti vrátane e‑mailov a dát prehliadania vidí poskytovateľ siete VPN."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Toto zariadenie je pripojené na internet prostredníctvom aplikácie <xliff:g id="VPN_APP">%1$s</xliff:g>. Vaša sieťová aktivita, ako sú e‑maily a dáta prehliadania, je viditeľná pre poskytovateľa siete VPN."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"Toto zariadenie je k internetu pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%1$s</xliff:g>. Vašu aktivitu v sieti vrátane e‑mailov a dát prehliadania vidí váš správca IT."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Toto zariadenie je k internetu pripojené prostredníctvom aplikácií <xliff:g id="VPN_APP_0">%1$s</xliff:g> a <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Vašu aktivitu v sieti vrátane e‑mailov a dát prehliadania vidí váš správca IT."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vaše pracovné aplikácie sú k internetu pripojené prostredníctvom aplikácie <xliff:g id="VPN_APP">%1$s</xliff:g>. Vašu aktivitu v sieti v pracovných aplikáciách vrátane e‑mailov a dát prehliadania vidí váš správca IT a poskytovateľ siete VPN."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"zakázať"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Zvuk a vibrácie"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Nastavenia"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Znížené na bezpečnú hlasitosť"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Hlasitosť bola vysoká dlhšie, ako sa odporúča"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Hlasitosť bola znížená na bezpečnejšiu úroveň"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Hlasitosť slúchadiel bola vysoká dlhšie, ako sa odporúča"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Hlasitosť slúchadiel prekročila bezpečný limit pre tento týždeň"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Pokračovať v počúvaní"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Znížiť hlasitosť"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Aplikácia je pripnutá"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Uvoľníte ho stlačením a podržaním tlačidiel Späť a Prehľad."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Uvoľníte ho pridržaním tlačidiel Späť a Domov."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavenia"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> sa prehráva z aplikácie <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> z <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je spustená"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Prehrať"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pozastaviť"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Predchádzajúca skladba"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Reproduktory a obrazovky"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Navrhované zariadenia"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Ak chcete preniesť médiá do iného zariadenia, ukončite zdieľanú reláciu"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Ukončiť"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Ako vysielanie funguje"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Vysielanie"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ľudia v okolí s kompatibilnými zariadeniami s rozhraním Bluetooth si môžu vypočuť médiá, ktoré vysielate"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Pripojte dotykové pero k nabíjačke"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Stav batérie dotykového pera je nízky"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Z tohto profilu nemôžete volať"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Pracovné pravidlá vám umožňujú telefonovať iba v pracovnom profile"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Nemôžete volať z osobnej aplikácie"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Vaša organizácia vám povoľuje volať iba z pracovných aplikácií"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Prepnúť na pracovný profil"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zavrieť"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Inštalovať pracovnú telefónnu aplikáciu"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Zrušiť"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Prispôsobiť uzamknutú obrazovku"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Ak chcete prispôsobiť uzamknutú obrazovku, odomknite ju"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi‑Fi nie je k dispozícii"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index bbecf1f..dcc34c4 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Deli"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Snemanje zaslona je shranjeno"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Dotaknite se za ogled."</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Napaka pri brisanju videoposnetka zaslona"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Napaka pri shranjevanju posnetka zaslona"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Napaka pri začenjanju snemanja zaslona"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Nazaj"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Začetni zaslon"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Pristnost obraza je potrjena"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Potrjeno"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Za dokončanje se dotaknite »Potrdite«"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Odklenjeno z obrazom. Za nadaljevanje pritisnite ikono za odklepanje."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odklenjeno z obrazom. Pritisnite za nadaljevanje."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Obraz je prepoznan. Pritisnite za nadaljevanje."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Obraz je prepoznan. Za nadaljevanje pritisnite ikono za odklepanje."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"onemogoči"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Zvok in vibriranje"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Nastavitve"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Glasnost znižana na varnejšo raven"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Glasnost je bila visoka dalj časa, kot je priporočeno."</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Glasnost je bila zmanjšana na varnejšo raven"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Glasnost v slušalkah je bila visoka dalj časa, kot je priporočeno."</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Visoka glasnost v slušalkah je presegla varno omejitev za ta teden"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Ne prekini poslušanja"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Zmanjšaj glasnost"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Aplikacija je pripeta"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"S tem ostane vidna, dokler je ne odpnete. Če jo želite odpeti, hkrati pridržite gumba za nazaj in pregled."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"S tem ostane vidna, dokler je ne odpnete. Če jo želite odpeti, hkrati pridržite gumba za nazaj in za začetni zaslon."</string>
@@ -902,13 +906,13 @@
     <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"odstranitev iz priljubljenih"</string>
     <string name="accessibility_control_move" msgid="8980344493796647792">"Premakni na položaj <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrolniki"</string>
-    <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Izberite kontrolnike naprave, do katerih želite hitro dostopati."</string>
+    <string name="controls_favorite_subtitle" msgid="5818709315630850796">"Izberite kontrolnike naprav, do katerih želite hitro dostopati."</string>
     <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Držite in povlecite, da prerazporedite kontrolnike."</string>
     <string name="controls_favorite_removed" msgid="5276978408529217272">"Vsi kontrolniki so bili odstranjeni."</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Spremembe niso shranjene"</string>
     <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Prikaz drugih aplikacij"</string>
-    <string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Razvrščanje"</string>
-    <string name="controls_favorite_add_controls" msgid="1221420435546694004">"Dodajte kontrolnike"</string>
+    <string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Razvrsti"</string>
+    <string name="controls_favorite_add_controls" msgid="1221420435546694004">"Dodaj kontrolnike"</string>
     <string name="controls_favorite_back_to_editing" msgid="184125114090062713">"Nazaj na urejanje"</string>
     <string name="controls_favorite_load_error" msgid="5126216176144877419">"Kontrolnikov ni bilo mogoče naložiti. Preverite aplikacijo <xliff:g id="APP">%s</xliff:g> in se prepričajte, da se njene nastavitve niso spremenile."</string>
     <string name="controls_favorite_load_none" msgid="7687593026725357775">"Združljivi kontrolniki niso na voljo"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavitve"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Skladba <xliff:g id="SONG_NAME">%1$s</xliff:g> izvajalca <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se predvaja iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> se izvaja"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Predvajaj"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Začasno zaustavi"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Prejšnja skladba"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Povežite pisalo s polnilnikom."</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Skoraj prazna baterija pisala"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Ni mogoče klicati iz tega profila"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Službeni pravilnik dovoljuje opravljanje telefonskih klicev le iz delovnega profila."</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Ni mogoče klicati iz osebne aplikacije."</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Organizacija vam omogoča klicanje samo iz delovnih aplikacij."</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Preklopi na delovni profil"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zapri"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Namestite delovno aplikacijo za telefon"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Prekliči"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Prilagajanje zaklenjenega zaslona"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Odklenite za prilagajanje zaklenjenega zaslona"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi ni na voljo."</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 40b9eb5..f851d30 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Ndaj"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Regjistrimi i ekranit u ruajt"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Trokit për të parë"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Gabim gjatë fshirjes së regjistrimit të ekranit"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Gabim gjatë ruajtjes së regjistrimit të ekranit"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Gabim gjatë nisjes së regjistrimit të ekranit"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Prapa"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Faqja bazë"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Fytyra u vërtetua"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Konfirmuar"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Trokit \"Konfirmo\" për ta përfunduar"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"U shkyç me fytyrë. Shtyp ikonën e shkyçjes për të vazhduar."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"U shkyç me fytyrë. Shtyp për të vazhduar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Fytyra u njoh. Shtyp për të vazhduar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Fytyra u njoh. Shtyp ikonën e shkyçjes për të vazhduar."</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Në këtë pajisje është instaluar një autoritet certifikate. Trafiku i rrjetit tënd të sigurt mund të monitorohet ose modifikohet."</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administratori ka aktivizuar regjistrimin e rrjetit, i cili monitoron trafikun në pajisjen tënde."</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administratori yt ka aktivizuar regjistrimin e rrjetit, i cili monitoron trafikun në profilin tënd të punës, por jo në profilin tënd personal."</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Kjo pajisje është e lidhur me internetin nëpërmjet <xliff:g id="VPN_APP">%1$s</xliff:g>. Aktiviteti yt në rrjet, duke përfshirë email-et e dhe të dhënat e shfletimit, është i dukshëm për ofruesin e VPN-së."</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Kjo pajisje është e lidhur me internetin nëpërmjet <xliff:g id="VPN_APP">%1$s</xliff:g>. Aktiviteti yt në rrjet, duke përfshirë email-et dhe të dhënat e shfletimit, është i dukshëm për ofruesin e VPN-së."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"Kjo pajisje është e lidhur me internetin nëpërmjet <xliff:g id="VPN_APP">%1$s</xliff:g>. Aktiviteti yt në rrjet, duke përfshirë email-et e dhe të dhënat e shfletimit, është i dukshëm për administratorin tënd të teknologjisë së informacionit."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Kjo pajisje është e lidhur me internetin nëpërmjet <xliff:g id="VPN_APP_0">%1$s</xliff:g> dhe <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Aktiviteti yt në rrjet, duke përfshirë email-et e dhe të dhënat e shfletimit, është i dukshëm për administratorin tënd të teknologjisë së informacionit."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Aplikacionet e tua të punës janë të lidhura me internetin nëpërmjet <xliff:g id="VPN_APP">%1$s</xliff:g>. Aktiviteti yt në rrjet në aplikacionet e punës, duke përfshirë email-et dhe të dhënat e shfletimit, është i dukshëm për administratorin e teknologjisë së informacionit dhe ofruesin e VPN-së."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"çaktivizo"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Tingulli dhe dridhjet"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Cilësimet"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Ulur në një volum më të sigurt"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Volumi ka qenë i lartë për një kohë më të gjatë nga sa rekomandohet"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volumi është ulur në një nivel më të sigurt"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Volumi i kufjeve ka qenë i lartë për një kohë më të gjatë nga sa rekomandohet"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Volumi i kufjeve ka tejkaluar kufirin e sigurisë për këtë javë"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Vazhdo të dëgjosh"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Ul volumin"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Aplikacioni është i gozhduar"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Kjo e ruan në pamje deri sa ta heqësh nga gozhdimi. Prek dhe mbaj të shtypur \"Prapa\" dhe \"Përmbledhje\" për ta hequr nga gozhdimi."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Kjo e ruan në pamje deri sa ta heqësh nga gozhdimi. Prek dhe mbaj të shtypur \"Prapa\" dhe \"Kreu\" për ta hequr nga gozhdimi."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Cilësimet"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> nga <xliff:g id="ARTIST_NAME">%2$s</xliff:g> po luhet nga <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> nga <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> po ekzekutohet"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Luaj"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Vendos në pauzë"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Pjesa muzikore e mëparshme"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Lidhe stilolapsin me një karikues"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Bateria e stilolapsit në nivel të ulët"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Nuk mund të telefonosh nga ky profil"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Politika jote e punës të lejon të bësh telefonata vetëm nga profili i punës"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Nuk mund të telefonohet nga një aplikacion personal"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Organizata jote të lejon që të telefonosh vetëm nga aplikacionet e punës"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Kalo te profili i punës"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Mbyll"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalo një aplikacion të telefonit të punës"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Anulo"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizo ekranin e kyçjes"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Shkyçe për të personalizuar ekranin e kyçjes"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi nuk ofrohet"</string>
diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
index 45f63bf..b8e1355 100644
--- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
@@ -48,7 +48,7 @@
   </string-array>
   <string-array name="tile_states_battery">
     <item msgid="6311253873330062961">"Nuk ofrohet"</item>
-    <item msgid="7838121007534579872">"Joaktiv"</item>
+    <item msgid="7838121007534579872">"Joaktive"</item>
     <item msgid="1578872232501319194">"Aktiv"</item>
   </string-array>
   <string-array name="tile_states_dnd">
@@ -59,7 +59,7 @@
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Nuk ofrohet"</item>
     <item msgid="5044688398303285224">"Joaktiv"</item>
-    <item msgid="8527389108867454098">"Aktiv"</item>
+    <item msgid="8527389108867454098">"Aktive"</item>
   </string-array>
   <string-array name="tile_states_rotation">
     <item msgid="4578491772376121579">"Nuk ofrohet"</item>
@@ -88,13 +88,13 @@
   </string-array>
   <string-array name="tile_states_color_correction">
     <item msgid="2840507878437297682">"Nuk ofrohet"</item>
-    <item msgid="1909756493418256167">"Joaktiv"</item>
-    <item msgid="4531508423703413340">"Aktiv"</item>
+    <item msgid="1909756493418256167">"Joaktive"</item>
+    <item msgid="4531508423703413340">"Aktive"</item>
   </string-array>
   <string-array name="tile_states_inversion">
     <item msgid="3638187931191394628">"Nuk ofrohet"</item>
-    <item msgid="9103697205127645916">"Joaktiv"</item>
-    <item msgid="8067744885820618230">"Aktiv"</item>
+    <item msgid="9103697205127645916">"Joaktive"</item>
+    <item msgid="8067744885820618230">"Aktive"</item>
   </string-array>
   <string-array name="tile_states_saver">
     <item msgid="39714521631367660">"Nuk ofrohet"</item>
@@ -108,7 +108,7 @@
   </string-array>
   <string-array name="tile_states_work">
     <item msgid="389523503690414094">"Nuk ofrohet"</item>
-    <item msgid="8045580926543311193">"Joaktiv"</item>
+    <item msgid="8045580926543311193">"Joaktive"</item>
     <item msgid="4913460972266982499">"Aktiv"</item>
   </string-array>
   <string-array name="tile_states_cast">
@@ -123,13 +123,13 @@
   </string-array>
   <string-array name="tile_states_screenrecord">
     <item msgid="1085836626613341403">"Nuk ofrohet"</item>
-    <item msgid="8259411607272330225">"Joaktiv"</item>
+    <item msgid="8259411607272330225">"Joaktive"</item>
     <item msgid="578444932039713369">"Aktiv"</item>
   </string-array>
   <string-array name="tile_states_reverse">
     <item msgid="3574611556622963971">"Nuk ofrohet"</item>
-    <item msgid="8707481475312432575">"Joaktiv"</item>
-    <item msgid="8031106212477483874">"Aktiv"</item>
+    <item msgid="8707481475312432575">"Joaktive"</item>
+    <item msgid="8031106212477483874">"Aktive"</item>
   </string-array>
   <string-array name="tile_states_reduce_brightness">
     <item msgid="1839836132729571766">"Nuk ofrohet"</item>
@@ -144,7 +144,7 @@
   <string-array name="tile_states_mictoggle">
     <item msgid="6895831614067195493">"Nuk ofrohet"</item>
     <item msgid="3296179158646568218">"Joaktiv"</item>
-    <item msgid="8998632451221157987">"Aktiv"</item>
+    <item msgid="8998632451221157987">"Aktive"</item>
   </string-array>
   <string-array name="tile_states_controls">
     <item msgid="8199009425335668294">"Nuk ofrohet"</item>
@@ -158,13 +158,13 @@
   </string-array>
   <string-array name="tile_states_qr_code_scanner">
     <item msgid="7435143266149257618">"Nuk ofrohet"</item>
-    <item msgid="3301403109049256043">"Joaktiv"</item>
-    <item msgid="8878684975184010135">"Aktiv"</item>
+    <item msgid="3301403109049256043">"Joaktive"</item>
+    <item msgid="8878684975184010135">"Aktive"</item>
   </string-array>
   <string-array name="tile_states_alarm">
     <item msgid="4936533380177298776">"Nuk ofrohet"</item>
     <item msgid="2710157085538036590">"Joaktiv"</item>
-    <item msgid="7809470840976856149">"Aktiv"</item>
+    <item msgid="7809470840976856149">"Aktive"</item>
   </string-array>
   <string-array name="tile_states_onehanded">
     <item msgid="8189342855739930015">"Nuk ofrohet"</item>
@@ -173,12 +173,12 @@
   </string-array>
   <string-array name="tile_states_dream">
     <item msgid="6184819793571079513">"Nuk ofrohet"</item>
-    <item msgid="8014986104355098744">"Joaktiv"</item>
-    <item msgid="5966994759929723339">"Aktiv"</item>
+    <item msgid="8014986104355098744">"Joaktive"</item>
+    <item msgid="5966994759929723339">"Aktive"</item>
   </string-array>
   <string-array name="tile_states_font_scaling">
     <item msgid="3173069902082305985">"Nuk ofrohet"</item>
-    <item msgid="2478289035899842865">"Joaktiv"</item>
-    <item msgid="5137565285664080143">"Aktiv"</item>
+    <item msgid="2478289035899842865">"Joaktive"</item>
+    <item msgid="5137565285664080143">"Aktive"</item>
   </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 424eb44..576cad0 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Дели"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Снимак екрана је сачуван"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Додирните да бисте прегледали"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Дошло је до проблема при брисању снимка екрана"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Грешка при чувању снимка екрана"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Грешка при покретању снимања екрана"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Почетна"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Лице је потврђено"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Потврђено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Додирните Потврди да бисте завршили"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Откључано је лицем. Притисните икону откључавања за наставак"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Откључано је лицем. Притисните да бисте наставили."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лице је препознато. Притисните да бисте наставили."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лице препознато. Притисните икону откључавања за наставак."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"онемогућите"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Звук и вибрирање"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Подешавања"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Звук је смањен на безбедну јачину"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Звук је био гласан дуже него што се препоручује"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Звук је смањен на безбедну јачину"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Звук у слушалицама је био гласан дуже него што се препоручује"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Јачина звука у слушалицама је премашила безбедносно ограничење за ову недељу"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Наставите да слушате"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Смањите јачину звука"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Апликација је закачена"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Назад и Преглед да бисте га откачили."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Назад и Почетна да бисте га откачили."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Подешавања"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> извођача <xliff:g id="ARTIST_NAME">%2$s</xliff:g> се пушта из апликације <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> од <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је покренута"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Пусти"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Паузирај"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Претходна песма"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Звучници и екрани"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Предложени уређаји"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Зауставите дељену сесију да бисте преместили медијски садржај на други уређај"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Заустави"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Како функционише емитовање"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Емитовање"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Људи у близини са компатибилним Bluetooth уређајима могу да слушају медијски садржај који емитујете"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Повежите писаљку са пуњачем"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Низак ниво батерије писаљке"</string>
     <string name="video_camera" msgid="7654002575156149298">"Видео камера"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Не можете да упућујете позиве са овог профила"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Смернице за посао вам омогућавају да телефонирате само са пословног профила"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Не можете да упућујете позиве из личне апликације"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Ваша организација дозвољава позивање само из пословних апликација"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Пређи на пословни профил"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затвори"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Инсталирајте пословну апликацију за телефон"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Откажи"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Прилагоди закључани екран"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Откључајте да бисте прилагодили закључани екран"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"WiFi није доступан"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 4996e1b..8fe491b 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Dela"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Skärminspelning sparad"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Tryck för att visa"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Det gick inte att radera skärminspelningen"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Det gick inte att spara skärminspelningen"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Det gick inte att starta skärminspelningen"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Tillbaka"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Startsida"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ansiktet har autentiserats"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Bekräftat"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Slutför genom att trycka på Bekräfta"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Upplåst med ansiktslås. Tryck på ikonen lås upp för att fortsätta."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Upplåst med ansiktslås. Tryck för att fortsätta."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansiktet har identifierats. Tryck för att fortsätta."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet har identifierats. Tryck på ikonen lås upp."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"inaktivera"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Ljud och vibration"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Inställningar"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Sänkte till säkrare volym"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Volymen har varit hög längre än vad som rekommenderas"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volymen har sänkts till en säkrare nivå"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Volymen i hörlurarna har varit hög längre än vad som rekommenderas"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Volymen i hörlurarna har överskridit den säkra gränsen för veckan"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Fortsätt lyssna"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Sänk volymen"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Appen har fästs"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Skärmen visas tills du lossar den. Tryck länge på Tillbaka och Översikt om du vill lossa skärmen."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Skärmen visas tills du lossar den. Tryck länge på Tillbaka och Startsida om du vill lossa skärmen."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Inställningar"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> med <xliff:g id="ARTIST_NAME">%2$s</xliff:g> spelas upp från <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> av <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> körs"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Spela upp"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pausa"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Föregående spår"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Högtalare och skärmar"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Förslag på enheter"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Stoppa din delade session för att flytta media till en annan enhet"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Stoppa"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Så fungerar utsändning"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Utsändning"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personer i närheten med kompatibla Bluetooth-enheter kan lyssna på medieinnehåll som du sänder ut"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Anslut e-pennan till en laddare"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"E-pennans batterinivå är låg"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Det går inte att ringa från den här profilen"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Jobbprincipen tillåter endast att du ringer telefonsamtal från jobbprofilen"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Det går inte att ringa samtal med en privat app"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Organisationen tillåter endast att du ringer samtal med jobbappar"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Byt till jobbprofilen"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Stäng"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installera en jobbapp"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Avbryt"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Anpassa låsskärmen"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Lås upp för att anpassa låsskärmen"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi är inte tillgängligt"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 7f162eb..e359c01 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Shiriki"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Imehifadhi rekodi ya skrini"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Gusa ili uangalie"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Hitilafu imetokea wakati wa kufuta rekodi ya skrini"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Hitilafu imetokea wakati wa kuhifadhi rekodi ya skrini"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Hitilafu imetokea wakati wa kuanza kurekodi skrini"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Nyuma"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Nyumbani"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Uso umethibitishwa"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Imethibitishwa"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Gusa Thibitisha ili ukamilishe"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Imefunguliwa kwa kutumia uso wako. Bonyeza aikoni ya kufungua ili uendelee."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Imefunguliwa kwa kutumia uso wako. Bonyeza ili uendelee."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Uso umetambuliwa. Bonyeza ili uendelee."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Uso umetambuliwa. Bonyeza aikoni ya kufungua ili uendelee."</string>
@@ -165,7 +166,7 @@
     <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Ukiweka mchoro usio sahihi utakapojaribu tena, wasifu wako wa kazini utafutwa pamoja na data yake."</string>
     <string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Ukiweka PIN isiyo sahihi utakapojaribu tena, wasifu wako wa kazini utafutwa pamoja na data yake."</string>
     <string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Ukiweka nenosiri lisilo sahihi utakapojaribu tena, wasifu wako wa kazini utafutwa pamoja na data yake."</string>
-    <string name="biometric_re_enroll_dialog_confirm" msgid="3049858021857801836">"Weka mipangilio"</string>
+    <string name="biometric_re_enroll_dialog_confirm" msgid="3049858021857801836">"Weka mipangilio ya"</string>
     <string name="biometric_re_enroll_dialog_cancel" msgid="93760939407091417">"Labda baadaye"</string>
     <string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"Hii inahitajika ili kuboresha usalama na utendaji"</string>
     <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"Weka upya mipangilio ya Kufungua kwa Alama ya Kidole"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"zima"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Sauti na mtetemo"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Mipangilio"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Sauti imepunguzwa kuwa kiwango salama"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Sauti imekuwa juu kwa muda mrefu kuliko inavyopendekezwa"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Kiwango cha sauti kimepunguzwa hadi kiwango salama"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Kiwango cha sauti ya vipokea sauti vya kichwani kimekuwa juu kwa muda mrefu kuliko inavyopendekezwa"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Kiwango cha sauti ya vipokea sauti vya kichwani kimezidi kikomo cha kiwango salama kwa wiki hii"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Endelea kusikiliza"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Punguza kiwango cha sauti"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Programu imebandikwa"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Hali hii huifanya ionekane hadi utakapoibandua. Gusa na ushikilie kipengele cha Nyuma na Muhtasari ili ubandue."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Hali hii huifanya ionekane hadi utakapoibandua. Gusa na ushikilie kitufe cha kurudisha Nyuma na cha Mwanzo kwa pamoja ili ubandue."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Mipangilio"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ulioimbwa na <xliff:g id="ARTIST_NAME">%2$s</xliff:g> unacheza katika <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> kati ya <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> inatumika"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Cheza"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Simamisha"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Wimbo uliotangulia"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Unganisha stylus yako kwenye chaja"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Chaji ya betri ya Stylus imepungua"</string>
     <string name="video_camera" msgid="7654002575156149298">"Kamera ya kuchukulia video"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Huwezi kupiga simu kutoka kwenye wasifu huu"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Sera ya mahali pako pa kazi inakuruhusu upige simu kutoka kwenye wasifu wa kazini pekee"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Huwezi kupiga simu kwa kutumia programu ya binafsi"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Shirika lako linakuruhusu upige simu ukitumia programu za kazini pekee"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Tumia wasifu wa kazini"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Funga"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Sakinisha programu ya simu ya kazini"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Ghairi"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Wekea mapendeleo skrini iliyofungwa"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Fungua ili uweke mapendeleo ya skrini iliyofungwa"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi haipatikani"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index a2d4925..7dcd0fb 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"பகிர்"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"ஸ்கிரீன் ரெக்கார்டிங் சேமிக்கப்பட்டது"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"பார்க்கத் தட்டவும்"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"திரை ரெக்கார்டிங்கை நீக்குவதில் பிழை"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"ஸ்கிரீன் ரெக்கார்டிங்கைச் சேமிப்பதில் பிழை ஏற்பட்டது"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"ஸ்கிரீன் ரெக்கார்டிங்கைத் தொடங்குவதில் பிழை"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"பின்செல்"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"முகப்பு"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"முகம் அங்கீகரிக்கப்பட்டது"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"உறுதிப்படுத்தப்பட்டது"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"முடிக்க \'உறுதிப்படுத்துக\' என்பதை தட்டவும்"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. தொடர, அன்லாக் ஐகானை அழுத்துக."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. தொடர அழுத்தவும்."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"முகம் அங்கீகரிக்கப்பட்டது. தொடர அழுத்தவும்."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"முகம் அங்கீகரிக்கப்பட்டது. தொடர அன்லாக் ஐகானை அழுத்தவும்."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"முடக்கும்"</string>
     <string name="sound_settings" msgid="8874581353127418308">"ஒலி &amp; அதிர்வு"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"அமைப்புகள்"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"பாதுகாப்பான ஒலியளவிற்குக் குறைக்கப்பட்டது"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"பரிந்துரைக்கப்பட்டதை விட ஒலியளவு அதிகமாக உள்ளது"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"பாதுகாப்பான நிலைக்கு ஒலியளவு குறைக்கப்பட்டது"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ஹெட்ஃபோன் ஒலியளவு பரிந்துரைக்கப்பட்டதைவிட அதிகளவில் நீண்ட நேரமாக உள்ளது"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"இந்த வாரம் ஹெட்ஃபோன் ஒலியளவு பாதுகாப்பு வரம்பைக் கடந்துவிட்டது"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"இவ்வாறே இருக்கட்டும்"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"ஒலியளவைக் குறை"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"ஆப்ஸ் பின் செய்யப்பட்டது"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"பொருத்தியதை அகற்றும் வரை இதைக் காட்சியில் வைக்கும். அகற்ற, முந்தையது மற்றும் மேலோட்டப் பார்வையைத் தொட்டுப் பிடிக்கவும்."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"இதற்கான பின்னை அகற்றும் வரை, இந்தப் பயன்முறை செயல்பாட்டிலேயே இருக்கும். அகற்றுவதற்கு, முந்தையது மற்றும் முகப்பு பட்டன்களைத் தொட்டுப் பிடிக்கவும்."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"அமைப்புகள்"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> இன் <xliff:g id="SONG_NAME">%1$s</xliff:g> பாடல் <xliff:g id="APP_LABEL">%3$s</xliff:g> ஆப்ஸில் பிளேயாகிறது"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> / <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> இயங்கிக் கொண்டிருக்கிறது"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"பிளே செய்"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"இடைநிறுத்து"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"முந்தைய டிராக்"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ஸ்பீக்கர்கள் &amp; டிஸ்ப்ளேக்கள்"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"பரிந்துரைக்கப்படும் சாதனங்கள்"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"மீடியாவை வேறொரு சாதனத்திற்கு மாற்ற \'பகிரப்படும் அமர்வை\' நிறுத்தவும்"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"நிறுத்து"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"பிராட்காஸ்ட் எவ்வாறு செயல்படுகிறது?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"பிராட்காஸ்ட்"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"நீங்கள் பிராட்காஸ்ட் செய்யும் மீடியாவை அருகிலுள்ளவர்கள் இணக்கமான புளூடூத் சாதனங்கள் மூலம் கேட்கலாம்"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"உங்கள் ஸ்டைலஸைச் சார்ஜருடன் இணையுங்கள்"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"ஸ்டைலஸின் பேட்டரி குறைவாக உள்ளது"</string>
     <string name="video_camera" msgid="7654002575156149298">"வீடியோ கேமரா"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"இந்தக் கணக்கிலிருந்து அழைக்க முடியாது"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"உங்கள் பணிக் கொள்கையின்படி நீங்கள் பணிக் கணக்கில் இருந்து மட்டுமே ஃபோன் அழைப்புகளைச் செய்ய முடியும்"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"தனிப்பட்ட ஆப்ஸில் இருந்து அழைக்க முடியாது"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"உங்கள் நிறுவனம் பணி ஆப்ஸில் இருந்து மட்டுமே அழைக்க உங்களை அனுமதிக்கிறது"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"பணிக் கணக்கிற்கு மாறு"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"மூடுக"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"பணி மொபைல் ஆப்ஸை நிறுவு"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"ரத்துசெய்"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"பூட்டுத் திரையை பிரத்தியேகமாக்கு"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"பூட்டுத் திரையைப் பிரத்தியேகப்படுத்த அன்லாக் செய்யுங்கள்"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"வைஃபை கிடைக்கவில்லை"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 1749dc5..9680b3e 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -103,7 +103,7 @@
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"మీరు రికార్డ్ చేసేటప్పుడు, మీ స్క్రీన్‌పై కనిపించే దేనికైనా లేదా మీ పరికరంలో ప్లే అయిన దేనికైనా Androidకు యాక్సెస్ ఉంటుంది. కాబట్టి పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"మీరు ఏదైనా యాప్‌ను రికార్డ్ చేసేటప్పుడు, ఆ యాప్‌లో చూపబడిన దేనికైనా లేదా ప్లే అయిన దేనికైనా Androidకు యాక్సెస్ ఉంటుంది. కాబట్టి పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"రికార్డింగ్‌ను ప్రారంభించండి"</string>
-    <string name="screenrecord_audio_label" msgid="6183558856175159629">"ఆడియోను రికార్డ్ చేయి"</string>
+    <string name="screenrecord_audio_label" msgid="6183558856175159629">"ఆడియోను రికార్డ్ చేయండి"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"పరికరం ఆడియో"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"మీ పరికరం నుండి వచ్చే మ్యూజిక్, కాల్స్‌, రింగ్‌టోన్‌ల వంటి ధ్వనులు"</string>
     <string name="screenrecord_mic_label" msgid="2111264835791332350">"మైక్రోఫోన్"</string>
@@ -111,12 +111,12 @@
     <string name="screenrecord_continue" msgid="4055347133700593164">"ప్రారంభించండి"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"స్క్రీన్ రికార్డింగ్ చేయబడుతోంది"</string>
     <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"స్క్రీన్, ఆడియో రికార్డింగ్ చేయబడుతున్నాయి"</string>
-    <string name="screenrecord_taps_label" msgid="1595690528298857649">"స్క్రీన్‌పై తాకే స్థానాలను చూపు"</string>
+    <string name="screenrecord_taps_label" msgid="1595690528298857649">"స్క్రీన్‌పై తాకే స్థానాలను చూపండి"</string>
     <string name="screenrecord_stop_label" msgid="72699670052087989">"ఆపివేయి"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"షేర్ చేయి"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"స్క్రీన్ రికార్డింగ్ సేవ్ చేయబడింది"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"చూడటానికి ట్యాప్ చేయండి"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"స్క్రీన్ రికార్డింగ్‌ని తొలగిస్తున్నప్పుడు ఎర్రర్ ఏర్పడింది"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"స్క్రీన్ రికార్డింగ్‌ను సేవ్ చేయడంలో ఎర్రర్ ఏర్పడింది"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"స్క్రీన్ రికార్డింగ్ ప్రారంభించడంలో ఎర్రర్ ఏర్పడింది"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"వెనుకకు"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"హోమ్"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ముఖం ప్రామాణీకరించబడింది"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"నిర్ధారించబడింది"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"పూర్తి చేయడానికి \"నిర్ధారించు\" నొక్కండి"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. కొనసాగించడానికి అన్‌లాక్ చిహ్నాన్ని నొక్కండి."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. కొనసాగించడానికి నొక్కండి."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ముఖం గుర్తించబడింది. కొనసాగించడానికి నొక్కండి."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ముఖం గుర్తించబడింది. కొనసాగడానికి అన్‌లాక్ చిహ్నం నొక్కండి."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"నిలిపివేయండి"</string>
     <string name="sound_settings" msgid="8874581353127418308">"సౌండ్ &amp; వైబ్రేషన్"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"సెట్టింగ్‌లు"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"సురక్షితమైన వాల్యూమ్‌కు తగ్గించబడింది"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"సిఫార్సు చేసిన దానికంటే ఎక్కువ కాలం వాల్యూమ్ ఎక్కువగా ఉంది"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"వాల్యూమ్‌ను సురక్షిత స్థాయికి తగ్గించడం జరిగింది"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"హెడ్‌ఫోన్ వాల్యూమ్, సిఫార్సు చేసిన సమయం కంటే ఎక్కువసేపు అధిక వాల్యూమ్‌లో ఉంది"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"హెడ్‌ఫోన్ వాల్యూమ్ ఈ వారం సురక్షిత పరిమితిని మించిపోయింది"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"వింటూ ఉండండి"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"వాల్యూమ్‌ను తగ్గించండి"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"యాప్ పిన్ చేయబడి ఉంది"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"దీని వలన మీరు అన్‌పిన్ చేసే వరకు ఇది వీక్షణలో ఉంచబడుతుంది. అన్‌పిన్ చేయడానికి వెనుకకు మరియు స్థూలదృష్టి తాకి &amp; అలాగే పట్టుకోండి."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"దీని వలన మీరు అన్‌పిన్ చేసే వరకు ఇది వీక్షణలో ఉంచబడుతుంది. అన్‌పిన్ చేయడానికి వెనుకకు మరియు హోమ్‌ని తాకి &amp; అలాగే పట్టుకోండి."</string>
@@ -933,13 +937,14 @@
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"మరిన్నింటిని చూడటం కోసం స్వైప్ చేయండి"</string>
     <string name="controls_seeding_in_progress" msgid="3033855341410264148">"సిఫార్సులు లోడ్ అవుతున్నాయి"</string>
     <string name="controls_media_title" msgid="1746947284862928133">"మీడియా"</string>
-    <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> కోసమై ఏర్పరిచిన ఈ మీడియా కంట్రోల్‌ను దాచాలా?"</string>
+    <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> కోసం ఈ మీడియా కంట్రోల్‌ను దాచి ఉంచాలా?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"ప్రస్తుత మీడియా సెషన్‌ను దాచడం సాధ్యం కాదు."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"దాచండి"</string>
     <string name="controls_media_resume" msgid="1933520684481586053">"కొనసాగించండి"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"సెట్టింగ్‌లు"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> పాడిన <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%3$s</xliff:g> నుండి ప్లే అవుతోంది"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>లో <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> రన్ అవుతోంది"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"ప్లే చేయండి"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"పాజ్ చేయండి"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"మునుపటి ట్రాక్"</string>
@@ -1064,7 +1069,7 @@
     <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"ప్రస్తుతానికి Wi-Fi ఆటోమేటిక్‌గా కనెక్ట్ అవ్వదు"</string>
     <string name="see_all_networks" msgid="3773666844913168122">"అన్నీ చూడండి"</string>
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"నెట్‌వర్క్‌లను మార్చడానికి, ఈథర్‌నెట్‌ను డిస్‌కనెక్ట్ చేయండి"</string>
-    <string name="wifi_scan_notify_message" msgid="3753839537448621794">"పరికర అనుభవాన్ని మెరుగుపరచడానికి, Wi‑Fi ఆఫ్‌లో ఉన్నప్పుడు కూడా, ఏ సమయంలో అయినా ఇప్పటికీ Wi‑Fi నెట్‌వర్క్‌ల కోసం యాప్‌లు, సర్వీస్‌లు స్కాన్ చేయగలవు. మీరు దీనిని Wi‑Fi స్కానింగ్ సెట్టింగ్‌లలో మార్చవచ్చు. "<annotation id="link">"మార్చండి"</annotation></string>
+    <string name="wifi_scan_notify_message" msgid="3753839537448621794">"పరికర అనుభవాన్ని మెరుగుపరచడానికి, ఇప్పటికీ, యాప్‌లు, సర్వీస్‌లు ఏ సమయంలో అయినా Wi‑Fi నెట్‌వర్క్‌ల కోసం స్కాన్ చేయగలవు. Wi‑Fi ఆఫ్‌లో ఉన్నప్పుడు కూడా ఇలా చేయగలవు. "<annotation id="link">"మార్చండి"</annotation></string>
     <string name="turn_off_airplane_mode" msgid="8425587763226548579">"విమానం మోడ్‌ను ఆఫ్ చేయండి"</string>
     <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"కింది టైల్‌ను క్విక్ సెట్టింగ్‌లకు జోడించడానికి <xliff:g id="APPNAME">%1$s</xliff:g> అనుమతి కోరుతోంది"</string>
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"టైల్‌ను జోడించండి"</string>
@@ -1073,7 +1078,7 @@
     <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# యాప్ యాక్టివ్‌గా ఉంది}other{# యాప్‌లు యాక్టివ్‌గా ఉన్నాయి}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"కొత్త సమాచారం"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"యాక్టివ్‌గా ఉన్న యాప్‌లు"</string>
-    <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"మీరు వాటిని ఉపయోగించనప్పటికీ, ఈ యాప్‌లు యాక్టివ్‌గా ఉంటాయి, రన్ అవుతాయి. ఇది వాటి ఫంక్షనాలిటీని మెరుగుపరుస్తుంది, అయితే ఇది బ్యాటరీ జీవితకాలాన్ని కూడా ప్రభావితం చేయవచ్చు."</string>
+    <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"మీరు ఈ యాప్‌లను ఉపయోగించపోయినా కూడా అవి యాక్టివ్‌గా ఉండి, రన్ అవుతూ ఉంటాయి. దీని వల్ల వాటి ఫంక్షనాలిటీ మెరుగవుతుంది. అయితే ఇది బ్యాటరీ లైఫ్‌ను కూడా ప్రభావితం చేయవచ్చు."</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"ఆపివేయండి"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"ఆపివేయబడింది"</string>
     <string name="clipboard_edit_text_done" msgid="4551887727694022409">"పూర్తయింది"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"మీ స్టైలస్‌ను ఛార్జర్‌కి కనెక్ట్ చేయండి"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"తక్కువ స్టైలస్ బ్యాటరీ"</string>
     <string name="video_camera" msgid="7654002575156149298">"వీడియో కెమెరా"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"ఈ ప్రొఫైల్ నుండి కాల్ చేయడం సాధ్యపడలేదు"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"మీ వర్క్ పాలసీ, మిమ్మల్ని వర్క్ ప్రొఫైల్ నుండి మాత్రమే ఫోన్ కాల్స్ చేయడానికి అనుమతిస్తుంది"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"వ్యక్తిగత యాప్ నుండి కాల్ చేయడం సాధ్యం కాదు"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"మీ సంస్థ, వర్క్ యాప్‌ల నుండి మాత్రమే కాల్స్ చేయడానికి మిమ్మల్ని అనుమతిస్తుంది"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"వర్క్ ప్రొఫైల్‌కు మారండి"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"మూసివేయండి"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ఆఫీస్ ఫోన్ యాప్‌ను ఇన్‌స్టాల్ చేయండి"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"రద్దు చేయండి"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"లాక్ స్క్రీన్‌ను అనుకూలీకరించండి"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"లాక్ స్క్రీన్‌ను అనుకూలంగా మార్చుకోవడానికి అన్‌లాక్ చేయండి"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi అందుబాటులో లేదు"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index ef33744..93365fe 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"แชร์"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"บันทึกการบันทึกหน้าจอแล้ว"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"แตะเพื่อดู"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"เกิดข้อผิดพลาดในการลบการบันทึกหน้าจอ"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"เกิดข้อผิดพลาดในการบันทึกหน้าจอ"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"เกิดข้อผิดพลาดขณะเริ่มบันทึกหน้าจอ"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"กลับ"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"หน้าแรก"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"ตรวจสอบสิทธิ์ใบหน้าแล้ว"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"ยืนยันแล้ว"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"แตะยืนยันเพื่อดำเนินการให้เสร็จสมบูรณ์"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"ปลดล็อกด้วยใบหน้าแล้ว กดไอคอนปลดล็อกเพื่อดำเนินการต่อ"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ปลดล็อกด้วยใบหน้าแล้ว กดเพื่อดำเนินการต่อ"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"จดจำใบหน้าได้ กดเพื่อดำเนินการต่อ"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"จดจำใบหน้าได้ กดไอคอนปลดล็อกเพื่อดำเนินการต่อ"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"ปิดใช้"</string>
     <string name="sound_settings" msgid="8874581353127418308">"เสียงและการสั่น"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"การตั้งค่า"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"ลดเสียงลงไประดับที่ปลอดภัยขึ้นแล้ว"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"เสียงอยู่ในระดับที่ดังเป็นระยะเวลานานกว่าที่แนะนำ"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ลดเสียงให้อยู่ในระดับที่ปลอดภัยยิ่งขึ้น"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"เสียงของหูฟังอยู่ในระดับที่ดังเป็นระยะเวลานานกว่าที่แนะนำ"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"เสียงของหูฟังอยู่ในระดับที่ดังเกินขีดจำกัดความปลอดภัยสำหรับสัปดาห์นี้"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"ฟังต่อ"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"ลดเสียงลง"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"ปักหมุดแอปอยู่"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกปักหมุด แตะ \"กลับ\" และ \"ภาพรวม\" ค้างไว้เพื่อเลิกปักหมุด"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกปักหมุด แตะ \"กลับ\" และ \"หน้าแรก\" ค้างไว้เพื่อเลิกปักหมุด"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"การตั้งค่า"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"กำลังเปิดเพลง <xliff:g id="SONG_NAME">%1$s</xliff:g> ของ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> จาก <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> จาก <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังทำงาน"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"เล่น"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"หยุดชั่วคราว"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"แทร็กก่อนหน้า"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ลำโพงและจอแสดงผล"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"อุปกรณ์ที่แนะนำ"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"หยุดเซสชันที่แชร์อยู่เพื่อย้ายสื่อไปยังอุปกรณ์อื่น"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"หยุด"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"วิธีการทำงานของการออกอากาศ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ประกาศ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ผู้ที่อยู่ใกล้คุณและมีอุปกรณ์บลูทูธที่รองรับสามารถรับฟังสื่อที่คุณกำลังออกอากาศได้"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"เชื่อมต่อสไตลัสกับที่ชาร์จ"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"แบตเตอรี่สไตลัสเหลือน้อย"</string>
     <string name="video_camera" msgid="7654002575156149298">"กล้องวิดีโอ"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"โทรจากโปรไฟล์นี้ไม่ได้"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"นโยบายการทำงานอนุญาตให้คุณโทรออกได้จากโปรไฟล์งานเท่านั้น"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"โทรออกจากแอปส่วนตัวไม่ได้"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"องค์กรอนุญาตให้คุณโทรออกได้จากแอปงานเท่านั้น"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"สลับไปใช้โปรไฟล์งาน"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"ปิด"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ติดตั้งแอปโทรศัพท์ในโปรไฟล์งาน"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"ยกเลิก"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"ปรับแต่งหน้าจอล็อก"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"ปลดล็อกเพื่อปรับแต่งหน้าจอล็อก"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi ไม่พร้อมใช้งาน"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 14ed532..fec9aad 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Ibahagi"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Na-save ang pag-record ng screen"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"I-tap para tingnan"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Error sa pag-delete sa pag-record ng screen"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Nagka-error sa pag-save ng recording ng screen"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Nagkaroon ng error sa pagsisimula ng pag-record ng screen"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Bumalik"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Na-authenticate ang mukha"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Nakumpirma"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"I-tap ang Kumpirmahin para kumpletuhin"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Na-unlock gamit ang mukha. Pindutin ang icon ng unlock para magpatuloy."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Na-unlock gamit ang mukha. Pindutin para magpatuloy."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Nakilala ang mukha. Pindutin para magpatuloy."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Nakilala ang mukha. Pindutin ang unlock para magpatuloy."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"i-disable"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Tunog at pag-vibrate"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Mga Setting"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Hininaan sa mas ligtas na volume"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Naging malakas ang volume nang mas matagal sa inirerekomenda"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Ibinaba sa mas ligtas na level ang volume"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Naging malakas ang volume ng headphones nang mas matagal sa inirerekomenda"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Lampas na sa ligtas na limitasyon para sa linggong ito ang volume ng headphone"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Magpatuloy sa pakikinig"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Hinaan"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Naka-pin ang app"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Pinapanatili nitong nakikita ito hanggang sa mag-unpin ka. Pindutin nang matagal ang Bumalik at Overview upang mag-unpin."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Pinapanatili nitong nakikita ito hanggang sa mag-unpin ka. Pindutin nang matagal ang Bumalik at Home upang mag-unpin."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Mga Setting"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Nagpe-play ang <xliff:g id="SONG_NAME">%1$s</xliff:g> ni/ng <xliff:g id="ARTIST_NAME">%2$s</xliff:g> mula sa <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> sa <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"Tumatakbo ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"I-play"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"I-pause"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Nakaraang track"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Ikonekta sa charger ang iyong stylus"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Paubos na ang baterya ng stylus"</string>
     <string name="video_camera" msgid="7654002575156149298">"Video camera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Hindi puwedeng tumawag mula sa profile na ito"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Pinapayagan ka ng iyong patakaran sa trabaho na tumawag lang mula sa profile sa trabaho"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Hindi puwedeng tumawag mula sa personal na app"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Pinapayagan ka lang ng iyong organisasyon na tumawag mula sa mga app para sa trabaho"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Lumipat sa profile sa trabaho"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Isara"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Mag-install ng phone app para sa trabaho"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Kanselahin"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"I-customize ang lock screen"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"I-unlock para i-customize ang lock screen"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Hindi available ang Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index d0e3331..b5201fe 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Paylaş"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Ekran kaydı kaydedildi"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Görüntülemek için dokunun"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekran kaydı silinirken hata oluştu"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Ekran kaydı saklanırken hata oluştu"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Ekran kaydı başlatılırken hata oluştu"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Geri"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Ana sayfa"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Yüz kimliği doğrulandı"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Onaylandı"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tamamlamak için Onayla\'ya dokunun"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Kilit, yüzünüzle açıldı. Kilit açma simgesine basın."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Cihazın kilidini yüzünüzle açtınız. Devam etmek için basın."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Yüzünüz tanındı. Devam etmek için basın."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Yüzünüz tanındı. Kilit açma simgesine basın."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"devre dışı bırak"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Ses ve titreşim"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Ayarlar"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Ses, sağlık açısından daha güvenli bir seviyeye düşürüldü"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Ses, önerilenden daha uzun süredir yüksek seviyede"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Ses düzeyi daha güvenli bir düzeye indirildi"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Ses, önerilenden daha uzun süredir yüksek düzeydeydi"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Bu hafta kulaklığın ses düzeyi güvenli sınırı aştı"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Dinlemeye devam"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Sesi kıs"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Uygulama sabitlendi"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Bu işlem, siz sabitlemeyi kaldırana kadar ekranı görünür durumda tutar. Sabitlemeyi kaldırmak için Geri\'ye ve Genel Bakış\'a dokunup basılı tutun."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Bu işlem, siz sabitlemeyi kaldırana kadar ekranı görünür durumda tutar. Sabitlemeyi kaldırmak için Geri\'ye ve Ana sayfaya dokunup basılı tutun."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> uygulamasından <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, <xliff:g id="SONG_NAME">%1$s</xliff:g> şarkısı çalıyor"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> çalışıyor"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Çal"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Duraklat"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Önceki parça"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%%<xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Hoparlörler ve Ekranlar"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Önerilen Cihazlar"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Medyayı başka bir cihaza taşımak için paylaşılan oturumunuzu durdurun"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Durdur"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Yayınlamanın işleyiş şekli"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Anons"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Yakınınızda ve uyumlu Bluetooth cihazları olan kişiler yayınladığınız medya içeriğini dinleyebilir"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Ekran kaleminizi bir şarj cihazına bağlayın"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Ekran kaleminin pil seviyesi düşük"</string>
     <string name="video_camera" msgid="7654002575156149298">"Video kamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Bu profilden telefon araması yapılamıyor"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"İşletme politikanız yalnızca iş profilinden telefon araması yapmanıza izin veriyor"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Kişisel bir uygulamadan arama yapılamaz"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Kuruluşunuz yalnızca iş uygulamalarından telefon etmenize izin veriyor"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"İş profiline geç"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Kapat"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"İş telefonu uygulaması yükle"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"İptal"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Kilit ekranını özelleştir"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Kilit ekranını özelleştirmek için kilidi açın"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Kablosuz bağlantı kullanılamıyor"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 700d875..e7d7e2e 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Поділитися"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Запис екрана збережено"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Натисніть, щоб переглянути"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Не вдалося видалити запис екрана"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Не вдалося зберегти запис відео з екрана"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Не вдалося почати запис екрана"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Назад"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Головна"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Обличчя автентифіковано"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Підтверджено"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Щоб завершити, натисніть \"Підтвердити\""</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Розблоковано (фейсконтроль). Натисніть значок розблокування."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Розблоковано (фейсконтроль). Натисніть, щоб продовжити."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Обличчя розпізнано. Натисніть, щоб продовжити."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Обличчя розпізнано. Натисніть значок розблокування."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"вимкнути"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Звук і вібрація"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Налаштування"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Гучність знижено до безпечнішого рівня"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Аудіо відтворювалося з високою гучністю довше, ніж рекомендується"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Гучність знижено до безпечнішого рівня"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Аудіо в навушниках відтворювалося з високою гучністю довше, ніж рекомендується"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Гучність навушників перевищила безпечний рівень, допустимий протягом тижня"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Слухати далі"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Зменшити гучність"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Додаток закріплено"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Ви постійно бачитимете екран, доки не відкріпите його. Щоб відкріпити екран, натисніть і втримуйте кнопки \"Назад\" та \"Огляд\"."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Ви бачитимете цей екран, доки не відкріпите його. Для цього натисніть і утримуйте кнопки \"Назад\" та \"Головний екран\"."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Налаштування"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Пісня \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\", яку виконує <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, грає в додатку <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> з <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> працює"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Відтворити"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Призупинити"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Попередня композиція"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Колонки й екрани"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Пропоновані пристрої"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Зупиніть сеанс спільного доступу, щоб перенести медіаконтент на інший пристрій"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Зупинити"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Як працює трансляція"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Трансляція"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Люди поблизу, які мають сумісні пристрої з Bluetooth, можуть слухати медіаконтент, який ви транслюєте."</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Підключіть стилус до зарядного пристрою"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Низький заряд акумулятора стилуса"</string>
     <string name="video_camera" msgid="7654002575156149298">"Відеокамера"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Неможливо телефонувати з цього профілю"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Відповідно до правил організації ви можете телефонувати лише з робочого профілю"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Не можна телефонувати з особистого додатка"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Ваша організація дозволяє телефонувати лише з робочих додатків"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Перейти в робочий профіль"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрити"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Установити робочий додаток Телефон"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Скасувати"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Налаштувати заблокований екран"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Розблокуйте, щоб налаштувати заблокований екран"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Мережа Wi-Fi недоступна"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 1affc4e..a67cc5a 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"اشتراک کریں"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"اسکرین ریکارڈنگ محفوظ ہو گئی"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"دیکھنے کے لیے تھپتھپائیں"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"اسکرین ریکارڈنگ کو حذف کرنے میں خرابی"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"اسکرین ریکارڈنگ محفوظ کرنے میں خرابی"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"اسکرین ریکارڈنگ شروع کرنے میں خرابی"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"واپس جائیں"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"ہوم"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"چہرے کی تصدیق ہو گئی"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تصدیق شدہ"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"مکمل کرنے کیلئے \'تصدیق کریں\' تھپتھپائیں"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"چہرے سے انلاک کیا گیا۔ جاری رکھنے کیلئے انلاک آئیکن دبائیں۔"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"چہرے سے انلاک کیا گیا۔ جاری رکھنے کے لیے دبائیں۔"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"چہرے کی شناخت ہو گئی۔ جاری رکھنے کے لیے دبائیں۔"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"چہرے کی شناخت ہو گئی۔ جاری رکھنے کیلئے انلاک آئیکن دبائیں۔"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"غیر فعال کریں"</string>
     <string name="sound_settings" msgid="8874581353127418308">"آواز اور وائبریشن"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ترتیبات"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"محفوظ والیوم تک کم کر دیا گیا"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"والیوم تجویز کردہ مدت سے زیادہ بلند رہا ہے"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"والیوم کو محفوظ سطح تک کم کر دیا گیا"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ہیڈ فون کا والیوم تجویز کردہ وقت سے زیادہ دیر تک بلند رہا ہے"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ہیڈ فون والیوم اس ہفتے محفوظ حد سے تجاوز کر گیا ہے"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"سنتے رہیں"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"والیوم کم کریں"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"ایپ کو پن کر دیا گیا ہے"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"اس سے یہ اس وقت تک منظر میں رہتی ہے جب تک آپ اس سے پن ہٹا نہیں دیتے۔ پن ہٹانے کیلئے پیچھے اور مجموعی جائزہ کے بٹنز کو ٹچ کریں اور دبائے رکھیں۔"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"اس سے یہ اس وقت تک منظر میں رہتی ہے جب تک آپ اس سے پن نہیں ہٹا دیتے۔ پن ہٹانے کیلئے \"پیچھے\" اور \"ہوم\" بٹنز کو ٹچ کریں اور دبائے رکھیں۔"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ترتیبات"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> سے <xliff:g id="ARTIST_NAME">%2$s</xliff:g> کا <xliff:g id="SONG_NAME">%1$s</xliff:g> چل رہا ہے"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> از <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> چل رہی ہے"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"چلائیں"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"روکیں"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"پچھلا ٹریک"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%%<xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"اسپیکرز اور ڈسپلیز"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"تجویز کردہ آلات"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"میڈیا کو دوسرے آلے پر منتقل کرنے کے لیے اپنا مشترکہ سیشن بند کریں"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"بند کریں"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"براڈکاسٹنگ کیسے کام کرتا ہے"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"براڈکاسٹ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"موافق بلوٹوتھ آلات کے ساتھ آپ کے قریبی لوگ آپ کے نشر کردہ میڈیا کو سن سکتے ہیں"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"اپنے اسٹائلس کو چارجر منسلک کریں"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"اسٹائلس بیٹری کم ہے"</string>
     <string name="video_camera" msgid="7654002575156149298">"ویڈیو کیمرا"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"اس پروفائل سے کال نہیں کر سکتے"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"آپ کے کام سے متعلق پالیسی آپ کو صرف دفتری پروفائل سے فون کالز کرنے کی اجازت دیتی ہے"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"ذاتی ایپ سے کال نہیں کر سکتے"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"آپ کی تنظیم آپ کو صرف ورک ایپس سے کالز کرنے کی اجازت دیتی ہے"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"دفتری پروفائل پر سوئچ کریں"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"بند کریں"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ورک فون ایپ انسٹال کریں"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"منسوخ کریں"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"مقفل اسکرین کو حسب ضرورت بنائیں"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"مقفل اسکرین کو حسب ضرورت بنانے کے لیے غیر مقفل کریں"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"‏Wi-Fi دستیاب نہیں ہے"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index af12ebe..86dc332 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Ulashish"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Ekran lavhasi saqlandi"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Koʻrish uchun bosing"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Ekrandan yozib olingan vi olib tashlanmadi"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Ekran yozuvi saqlanmadi"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Ekranni yozib olish boshlanmadi"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Orqaga"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Uyga"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Yuzingiz aniqlandi"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Tasdiqlangan"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Tasdiqlash uchun tegining"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Yuz orqali ochilgan. Davom etish uchun ochish belgisini bosing."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Yuz orqali ochildi. Davom etish uchun bosing."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Yuz aniqlandi. Davom etish uchun bosing."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Yuz aniqlandi. Davom etish uchun ochish belgisini bosing."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"faolsizlantirish"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Tovush va tebranish"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Sozlamalar"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Tovush balandligi xavfsiz darajaga tushirildi"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Tovush tavsiya qilinganidan koʻra uzoqroq vaqt baland boʻldi"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Tovush xavfsiz darajaga pasaytirildi"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Quloqlik tavsiya etilganidan uzoqroq vaqt baland tovushda ishladi"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Quloqlik tovushi bu hafta xavfsiz balandlik limitidan oshib ketdi"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Davom etish"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Pasaytirish"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Ilova mahkamlandi"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Ekran yechilmaguncha u o‘zgarmas holatda qoladi. Uni yechish uchun “Orqaga” va “Umumiy ma’lumot” tugmalarini bosib turing."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Ekran yechib olinmagunicha u mahkamlangan holatda qoladi. Uni yechish uchun Orqaga va Asosiy tugmalarni birga bosib turing."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Sozlamalar"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ilovasida ijro etilmoqda: <xliff:g id="SONG_NAME">%1$s</xliff:g> – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> / <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> ishlamoqda"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Ijro"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Pauza"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Avvalgi trek"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Karnaylar va displeylar"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Taklif qilingan qurilmalar"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Mediani boshqa qurilmaga koʻchirish uchun umumiy seansingizni toʻxtating"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Toʻxtatish"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Translatsiya qanday ishlaydi"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Translatsiya"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Atrofingizdagi mos Bluetooth qurilmasiga ega foydalanuvchilar siz translatsiya qilayotgan mediani tinglay olishadi"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Stilusni quvvat manbaiga ulang"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Stilus batareyasi kam"</string>
     <string name="video_camera" msgid="7654002575156149298">"Videokamera"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Bu profildan chaqiruv qilish imkonsiz"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Ishga oid siyosatingiz faqat ish profilidan telefon chaqiruvlarini amalga oshirish imkonini beradi"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Shaxsiy ilova orqali chaqiruv imkonsiz"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Tashkilotingiz faqat ishga oid ilovalar orqali chaqiruvga ruxsat beradi"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Ish profiliga almashish"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Yopish"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Ishga oid telefon ilovasini oʻrnatish"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Bekor qilish"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Ekran qulfini moslash"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Ekran qulfini sozlash uchun qulfni oching"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi mavjud emas"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 4fc63c9..e4073e4 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Chia sẻ"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Đã lưu bản ghi màn hình"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Nhấn để xem"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Lỗi khi xóa bản ghi màn hình"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Có lỗi xảy ra khi lưu video ghi màn hình"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Lỗi khi bắt đầu ghi màn hình"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Quay lại"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Trang chủ"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Đã xác thực khuôn mặt"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Ðã xác nhận"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Nhấn vào Xác nhận để hoàn tất"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Đã mở khoá bằng khuôn mặt. Nhấn vào biểu tượng mở khoá để tiếp tục."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Đã mở khoá bằng khuôn mặt. Hãy nhấn để tiếp tục."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Đã nhận diện khuôn mặt. Hãy nhấn để tiếp tục."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Đã nhận diện khuôn mặt. Nhấn biểu tượng mở khoá để tiếp tục."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"tắt"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Âm thanh và chế độ rung"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Cài đặt"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Đã giảm âm lượng xuống mức an toàn hơn"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Âm lượng ở mức cao trong khoảng thời gian lâu hơn khuyến nghị"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Âm lượng đã giảm xuống mức an toàn hơn"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Bạn đã dùng tai nghe ở mức âm lượng cao lâu hơn khoảng thời gian khuyến nghị, điều này có thể gây tổn hại đến thính giác của bạn"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Âm lượng tai nghe đã vượt quá giới hạn an toàn của tuần này"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Tiếp tục nghe"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Giảm âm lượng"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"Đã ghim ứng dụng"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Ứng dụng này sẽ ở cố định trên màn hình cho đến khi bạn bỏ ghim. Hãy chạm và giữ Quay lại và Tổng quan để bỏ ghim."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Ứng dụng này sẽ ở cố định trên màn hình cho đến khi bạn bỏ ghim. Hãy chạm và giữ nút Quay lại và nút Màn hình chính để bỏ ghim."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Cài đặt"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Đang phát <xliff:g id="SONG_NAME">%1$s</xliff:g> của <xliff:g id="ARTIST_NAME">%2$s</xliff:g> trên <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang chạy"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Phát"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Tạm dừng"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Bản nhạc trước"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Loa và màn hình"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Thiết bị được đề xuất"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"Dừng phiên chia sẻ của bạn để chuyển nội dung nghe nhìn sang thiết bị khác"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"Dừng"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cách tính năng truyền hoạt động"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Truyền"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Những người ở gần có thiết bị Bluetooth tương thích có thể nghe nội dung nghe nhìn bạn đang truyền"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Hãy kết nối bút cảm ứng với bộ sạc"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Bút cảm ứng bị yếu pin"</string>
     <string name="video_camera" msgid="7654002575156149298">"Máy quay video"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Không thể gọi điện từ hồ sơ này"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Chính sách của nơi làm việc chỉ cho phép bạn gọi điện thoại từ hồ sơ công việc"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Không thể gọi điện bằng ứng dụng cá nhân"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Tổ chức của bạn chỉ cho phép bạn gọi điện bằng ứng dụng công việc"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Chuyển sang hồ sơ công việc"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Đóng"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Cài đặt ứng dụng điện thoại cho công việc"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Huỷ"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Tuỳ chỉnh màn hình khoá"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Mở khoá để tuỳ chỉnh màn hình khoá"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Không có Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index cb2730e..cde0536 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"已保存屏幕录制内容"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"点按即可查看"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"删除屏幕录制内容时出错"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"保存屏幕录制内容时出错"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"启动屏幕录制时出错"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"返回"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"主屏幕"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"面孔身份验证成功"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"已确认"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"点按“确认”即可完成"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"已通过面孔识别解锁。按下解锁图标即可继续。"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"已通过面孔识别解锁。点按即可继续。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"识别出面孔。点按即可继续。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"识别出面孔。按下解锁图标即可继续。"</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"此设备上已安装证书授权中心。您的安全网络流量可能会受到监控或修改。"</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"您的管理员已开启网络日志记录功能(该功能会监控您设备上的流量)。"</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"您的管理员已开启网络日志记录功能,该功能会监控您的工作资料的流量,但不会监控您个人资料的流量。"</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"此设备已通过“<xliff:g id="VPN_APP">%1$s</xliff:g>”连接到互联网。VPN 提供方可以查看您的网络活动,包括电子邮件和浏览数据。"</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"此设备通过“<xliff:g id="VPN_APP">%1$s</xliff:g>”连接到互联网。VPN 提供方可以查看您的网络活动,包括电子邮件和浏览数据。"</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"此设备已通过“<xliff:g id="VPN_APP">%1$s</xliff:g>”连接到互联网。IT 管理员可以查看您的网络活动,包括电子邮件和浏览数据。"</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"此设备已通过“<xliff:g id="VPN_APP_0">%1$s</xliff:g>”和“<xliff:g id="VPN_APP_1">%2$s</xliff:g>”连接到互联网。您的 IT 管理员可以查看您的网络活动,包括电子邮件和浏览数据。"</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"您的工作应用已通过“<xliff:g id="VPN_APP">%1$s</xliff:g>”连接到互联网。您的 IT 管理员和 VPN 提供商可以查看工作应用的网络活动,包括电子邮件和浏览数据。"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"停用"</string>
     <string name="sound_settings" msgid="8874581353127418308">"声音和振动"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"设置"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"已降低至较安全的音量"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"音量保持较高的时间超过了建议时长"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"音量已降到更安全的水平"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"耳机音量保持较高的时间超过了建议时长"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"耳机音量已超出这周的安全上限"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"继续聆听"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"调低音量"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"应用已固定"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"这将会固定显示此屏幕,直到您取消固定为止。触摸并按住“返回”和“概览”即可取消固定屏幕。"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"这将会固定显示此屏幕,直到您取消固定为止。触摸并按住“返回”和“主屏幕”即可取消固定屏幕。"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"设置"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"正在通过<xliff:g id="APP_LABEL">%3$s</xliff:g>播放<xliff:g id="ARTIST_NAME">%2$s</xliff:g>的《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> / <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正在运行"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"播放"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"暂停"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"上一首"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"音箱和显示屏"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"建议的设备"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"停止共享的会话,即可将媒体移到其他设备"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"停止"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"广播的运作方式"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"广播"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"附近使用兼容蓝牙设备的用户可以收听您广播的媒体内容"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"请将触控笔连接充电器"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"触控笔电池电量低"</string>
     <string name="video_camera" msgid="7654002575156149298">"摄像机"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"无法通过这份资料拨打电话"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"根据您的工作政策,您只能通过工作资料拨打电话"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"无法通过个人应用拨打电话"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"贵组织仅允许您通过工作应用拨打电话"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"切换到工作资料"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"关闭"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"安装工作电话应用"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"取消"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"自定义锁屏状态"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"解锁以自定义锁定屏幕"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"没有 WLAN 连接"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index a164a5f..1504fce 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"已儲存螢幕錄影內容"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"輕按即可查看"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"刪除錄影畫面時發生錯誤"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"儲存螢幕錄影時發生錯誤"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"開始錄影畫面時發生錯誤"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"返回"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"首頁"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"面孔已經驗證"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"已確認"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"輕按 [確定] 以完成"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"已使用面孔解鎖。按解鎖圖示即可繼續。"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"已使用面孔解鎖。按下即可繼續操作。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"已識別面孔。按下即可繼續操作。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"已識別面孔。按解鎖圖示即可繼續。"</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"此裝置已安裝憑證授權單位。你的安全網絡流量可能會受監控或修改。"</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"你的管理員已開啟網絡記錄功能,以監控你裝置上的流量。"</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"你的管理員已開啟網絡記錄功能,可監控你工作設定檔 (而非個人設定檔) 的流量。"</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"此裝置已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網。你的 VPN 供應商可以看到你的網絡活動,包括電郵和瀏覽資料。"</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"此裝置目前透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網。你的 VPN 供應商可以看到你的網絡活動,包括電郵和瀏覽資料。"</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"此裝置已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網。IT 管理員可以看到你的網絡活動,包括電郵和瀏覽資料。"</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"此裝置已透過「<xliff:g id="VPN_APP_0">%1$s</xliff:g>」和「<xliff:g id="VPN_APP_1">%2$s</xliff:g>」連接至互聯網。IT 管理員可以看到你的網絡活動,包括電郵和瀏覽資料。"</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"你的工作應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連接至互聯網。IT 管理員和 VPN 供應商可以看到你在工作應用程式的網絡活動,包括電郵和瀏覽資料。"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"停用"</string>
     <string name="sound_settings" msgid="8874581353127418308">"音效和震動"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"設定"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"已調低至較安全的音量"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"使用高音量已超過建議的時間"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"音量已降至較安全的水平"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"以高音量使用耳機的時間已超過建議範圍"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"耳機音量已超過本週安全限制"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"繼續聆聽"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"降低音量"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"已固定應用程式"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"應用程式將會固定在螢幕上顯示,直至你取消固定為止。按住「返回」和「概覽」按鈕即可取消固定。"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"應用程式將會固定在螢幕上顯示,直至你取消固定為止。按住「返回」按鈕和主按鈕即可取消固定。"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"正在透過 <xliff:g id="APP_LABEL">%3$s</xliff:g> 播放 <xliff:g id="ARTIST_NAME">%2$s</xliff:g> 的《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」執行中"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"播放"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"暫停"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"上一首曲目"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"喇叭和螢幕"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"建議的裝置"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"停止共享工作階段以移動媒體至其他裝置"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"停止"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"廣播運作方式"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"廣播"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"附近有兼容藍牙裝置的人可收聽你正在廣播的媒體內容"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"將觸控筆連接充電器"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"觸控筆電量不足"</string>
     <string name="video_camera" msgid="7654002575156149298">"攝影機"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"無法透過此設定檔撥打電話"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"你的公司政策只允許透過工作設定檔撥打電話"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"無法透過個人應用程式打電話"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"你的機構只允許你透過工作應用程式打電話"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"切換至工作設定檔"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"關閉"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"安裝工作電話應用程式"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"取消"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"自訂上鎖畫面"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"解鎖後即可自訂上鎖畫面"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"無法連線至 Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index c206206..1450588 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"已儲存螢幕錄影檔"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"輕觸即可查看"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"刪除螢幕畫面錄製內容時發生錯誤"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"儲存螢幕錄影內容時發生錯誤"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"開始錄製螢幕畫面時發生錯誤"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"返回"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"主畫面"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"臉孔驗證成功"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"確認完畢"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"輕觸 [確認] 完成驗證設定"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"裝置已透過人臉解鎖,按下「解鎖」圖示即可繼續操作。"</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"裝置已透過你的臉解鎖,按下即可繼續操作。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"臉孔辨識完成,按下即可繼續操作。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"臉孔辨識完成,按下「解鎖」圖示即可繼續操作。"</string>
@@ -460,7 +461,7 @@
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"這個裝置已安裝憑證授權單位憑證。你的安全網路流量可能會受到監控或修改。"</string>
     <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"你的管理員已啟用網路記錄功能,可監控你裝置的流量。"</string>
     <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"你的管理員已啟用網路記錄功能,可監控你的工作資料夾流量,但不會監控個人資料夾的流量。"</string>
-    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"這部裝置已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連線到網際網路。請注意,VPN 供應商可以看見你的網路活動,包括電子郵件和瀏覽資料。"</string>
+    <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"這部裝置目前透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連線到網際網路。請注意,VPN 供應商可以看見你的網路活動,包括電子郵件和瀏覽資料。"</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"這部裝置已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連線到網際網路。請注意,IT 管理員可以看見你的網路活動,包括電子郵件和瀏覽資料。"</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"這部裝置已透過「<xliff:g id="VPN_APP_0">%1$s</xliff:g>」和「<xliff:g id="VPN_APP_1">%2$s</xliff:g>」連線到網際網路。請注意,IT 管理員可以看見你的網路活動,包括電子郵件和瀏覽資料。"</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"你的工作應用程式已透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」連線到網際網路。請注意,IT 管理員和 VPN 供應商可以看見你在工作應用程式中的網路活動,包括電子郵件和瀏覽資料。"</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"停用"</string>
     <string name="sound_settings" msgid="8874581353127418308">"音效與震動"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"設定"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"已調低至較安全的音量"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"已超過建議的高音量時間"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"音量已調低至安全範圍"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"耳罩式耳機以高音量播放已超過建議時間"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"耳罩式耳機的音量已超過本週的安全限制"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"繼續聆聽"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"調低音量"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"應用程式已固定"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"這會讓目前的螢幕畫面保持顯示狀態,直到取消固定為止。按住 [返回] 按鈕和 [總覽] 按鈕即可取消固定。"</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"這會讓應用程式顯示在螢幕上,直到取消固定為止。按住 [返回] 按鈕和主畫面按鈕即可取消固定。"</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"系統正透過「<xliff:g id="APP_LABEL">%3$s</xliff:g>」播放<xliff:g id="ARTIST_NAME">%2$s</xliff:g>的〈<xliff:g id="SONG_NAME">%1$s</xliff:g>〉"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>,共 <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」執行中"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"播放"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"暫停"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"上一首"</string>
@@ -985,10 +990,8 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"喇叭和螢幕"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"建議的裝置"</string>
-    <!-- no translation found for media_output_end_session_dialog_summary (5954520685989877347) -->
-    <skip />
-    <!-- no translation found for media_output_end_session_dialog_stop (208189434474624412) -->
-    <skip />
+    <string name="media_output_end_session_dialog_summary" msgid="5954520685989877347">"停止共用的工作階段,即可將媒體移至其他裝置"</string>
+    <string name="media_output_end_session_dialog_stop" msgid="208189434474624412">"停止"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"廣播功能的運作方式"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"廣播"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"如果附近的人有相容的藍牙裝置,就可以聽到你正在廣播的媒體內容"</string>
@@ -1141,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"將觸控筆接上充電器"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"觸控筆電力不足"</string>
     <string name="video_camera" msgid="7654002575156149298">"攝影機"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"無法透過這個資料夾撥打電話"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"貴公司政策僅允許透過工作資料夾撥打電話"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"無法透過個人應用程式撥號"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"貴機構僅允許透過工作應用程式撥打電話"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"切換至工作資料夾"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"關閉"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"安裝工作用電話應用程式"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"取消"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"自訂螢幕鎖定畫面"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"解鎖後即可自訂螢幕鎖定畫面"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"無法連上 Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 07cab2c..64bf21a 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -116,7 +116,7 @@
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Yabelana"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Okokuqopha iskrini kulondoloziwe"</string>
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Thepha ukuze ubuke"</string>
-    <string name="screenrecord_delete_error" msgid="2870506119743013588">"Iphutha lokususa ukurekhoda isikrini"</string>
+    <string name="screenrecord_save_error" msgid="5862648532560118815">"Iphutha lokulondoloza okokuqopha iskrini"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Iphutha lokuqala ukurekhoda isikrini"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Emuva"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Ekhaya"</string>
@@ -142,7 +142,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"Ubuso bufakazelwe ubuqiniso"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"Kuqinisekisiwe"</string>
     <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Thepha okuthi Qinisekisa ukuze uqedele"</string>
-    <string name="biometric_dialog_tap_confirm_with_face" msgid="1092050545851021991">"Ivulwe ngobuso. Cindezela isithonjana sokuvula ukuze uqhubeke."</string>
+    <!-- no translation found for biometric_dialog_tap_confirm_with_face (3783056044917913453) -->
+    <skip />
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Vula ngobuso. Cindezela ukuze uqhubeke."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ubuso buyaziwa. Cindezela ukuze uqhubeke."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ubuso buyaziwa. Cindezela isithonjana sokuvula ukuze uqhubeke."</string>
@@ -479,8 +480,11 @@
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"khubaza"</string>
     <string name="sound_settings" msgid="8874581353127418308">"Umsindo nokudlidliza"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Amasethingi"</string>
-    <string name="csd_lowered_title" product="default" msgid="1786173629015030856">"Yehliselwe kuvolumu ephephile"</string>
-    <string name="csd_system_lowered_text" product="default" msgid="2001603282316829500">"Ivolumu beyiphezulu isikhathi eside kunokunconyiwe"</string>
+    <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Ivolumu yehliselwe kuleveli ephephile"</string>
+    <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Ivolumu yama-headphone beyiphezulu isikhathi eside kunokunconyiwe"</string>
+    <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Ivolumu yama-headphone ibe phezulu kunokunconyiwe, okungalimaza ukuzwa kwakho"</string>
+    <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Qhubeka nokulalela"</string>
+    <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Yehlisa ivolomu"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"I-app iphiniwe"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Lokhu kuyigcina ibukeka uze ususe ukuphina. Thinta uphinde ubambe okuthi Emuva Nokubuka konke ukuze ususe ukuphina."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Lokhu kuyigcina ibonakala uze uyisuse. Thinta uphinde ubambe okuthi Emuva nokuthi Ekhaya ukuze ususe ukuphina."</string>
@@ -940,6 +944,7 @@
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Izilungiselelo"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"I-<xliff:g id="SONG_NAME">%1$s</xliff:g> ka-<xliff:g id="ARTIST_NAME">%2$s</xliff:g> idlala kusuka ku-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> ku-<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
+    <string name="controls_media_empty_title" msgid="8296102892421573325">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> iyasebenza"</string>
     <string name="controls_media_button_play" msgid="2705068099607410633">"Dlala"</string>
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Misa"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Ithrekhi yangaphambilini"</string>
@@ -1139,10 +1144,11 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Xhuma i-stylus yakho kushaja"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Ibhethri le-stylus liphansi"</string>
     <string name="video_camera" msgid="7654002575156149298">"Ikhamera yevidiyo"</string>
-    <string name="call_from_work_profile_title" msgid="6991157106804289643">"Ayikwazi ukufonela le phrofayela"</string>
-    <string name="call_from_work_profile_text" msgid="3458704745640229638">"Inqubomgomo yakho yomsebenzi ikuvumela ukuthi wenze amakholi wefoni kuphela ngephrofayela yomsebenzi"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Ayikwazi ukuthumela umlayezo ukusuka ku-app yomuntu siqu"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Inhlangano yakho ikuvumela kuphela ukuthi wenze amakholi ngama-app asemsebenzini"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Shintshela kuphrofayela yomsebenzi"</string>
-    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Vala"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Faka i-app yefoni yasemsebenzini"</string>
+    <string name="call_from_work_profile_close" msgid="5830072964434474143">"Khansela"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Yenza ngokwezifiso ukukhiya isikrini"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Vula ukuze wenze ukuvala isikrini ngendlela oyifisayo"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"I-Wi-Fi ayitholakali"</string>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 8d8fdf0..bd86e51 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -146,6 +146,7 @@
         <attr name="allCaps" format="boolean" />
         <attr name="showMissingSim" format="boolean" />
         <attr name="showAirplaneMode" format="boolean" />
+        <attr name="debugLocation" format="string" />
     </declare-styleable>
 
     <declare-styleable name="IlluminationDrawable">
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 26d6875..c3651cf 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -44,6 +44,12 @@
     <!-- orientation of the dead zone when touches have recently occurred elsewhere on screen -->
     <integer name="navigation_bar_deadzone_orientation">0</integer>
 
+    <!-- Whether or not lockscreen shortcuts can be customized -->
+    <bool name="custom_lockscreen_shortcuts_enabled">false</bool>
+
+    <!-- Whether or not long-pressing on keyguard will display to customize lockscreen -->
+    <bool name="long_press_keyguard_customize_lockscreen_enabled">false</bool>
+
     <bool name="config_dead_zone_flash">false</bool>
 
     <!-- Whether to enable dimming navigation buttons when wallpaper is not visible, should be
@@ -577,6 +583,9 @@
     <!-- Whether to show the side fps hint while on bouncer -->
     <bool name="config_show_sidefps_hint_on_bouncer">true</bool>
 
+    <!-- Max number of lines we want to show for the bouncer secondary message -->
+    <integer name="bouncer_secondary_message_lines">2</integer>
+
     <!-- Whether to use the split 2-column notification shade -->
     <bool name="config_use_split_notification_shade">false</bool>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 2024dae..8d3ba36 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -45,6 +45,9 @@
     <dimen name="navigation_edge_action_drag_threshold">16dp</dimen>
     <!-- The threshold to progress back animation for edge swipe -->
     <dimen name="navigation_edge_action_progress_threshold">412dp</dimen>
+    <!-- This value is used to calculate the target if the screen is wider than the
+        navigation_edge_action_progress_threshold. See BackAnimation#setSwipeThresholds -->
+    <item name="back_progress_non_linear_factor" format="float" type="dimen">0.2</item>
     <!-- The minimum display position of the arrow on the screen -->
     <dimen name="navigation_edge_arrow_min_y">64dp</dimen>
     <!-- The amount by which the arrow is shifted to avoid the finger-->
@@ -713,7 +716,7 @@
     <!-- Minimum margin between clock and status bar -->
     <dimen name="keyguard_clock_top_margin">18dp</dimen>
     <!-- The amount to shift the clocks during a small/large transition -->
-    <dimen name="keyguard_clock_switch_y_shift">10dp</dimen>
+    <dimen name="keyguard_clock_switch_y_shift">14dp</dimen>
     <!-- When large clock is showing, offset the smartspace by this amount -->
     <dimen name="keyguard_smartspace_top_offset">12dp</dimen>
     <!-- With the large clock, move up slightly from the center -->
@@ -807,6 +810,7 @@
     <!-- The width/height of the unlock icon view on keyguard. -->
     <dimen name="keyguard_lock_height">42dp</dimen>
     <dimen name="keyguard_lock_padding">20dp</dimen>
+    <dimen name="secondary_message_padding">8dp</dimen>
 
     <dimen name="keyguard_security_container_padding_top">20dp</dimen>
 
@@ -1315,9 +1319,10 @@
     <dimen name="media_output_dialog_title_anim_y_delta">12.5dp</dimen>
     <dimen name="media_output_dialog_app_tier_icon_size">20dp</dimen>
     <dimen name="media_output_dialog_background_radius">16dp</dimen>
-    <dimen name="media_output_dialog_active_background_radius">28dp</dimen>
+    <dimen name="media_output_dialog_active_background_radius">30dp</dimen>
     <dimen name="media_output_dialog_default_margin_end">16dp</dimen>
     <dimen name="media_output_dialog_selectable_margin_end">80dp</dimen>
+    <dimen name="media_output_dialog_list_padding_top">8dp</dimen>
 
     <!-- Distance that the full shade transition takes in order to complete by tapping on a button
          like "expand". -->
@@ -1641,6 +1646,19 @@
     <dimen name="dream_overlay_bottom_affordance_height">64dp</dimen>
     <dimen name="dream_overlay_bottom_affordance_width">64dp</dimen>
     <dimen name="dream_overlay_bottom_affordance_radius">32dp</dimen>
+    <dimen name="dream_overlay_bottom_affordance_key_text_shadow_dx">0.5dp</dimen>
+    <dimen name="dream_overlay_bottom_affordance_key_text_shadow_dy">0.5dp</dimen>
+    <dimen name="dream_overlay_bottom_affordance_key_text_shadow_radius">1dp</dimen>
+    <item name="dream_overlay_bottom_affordance_key_shadow_alpha" format="float" type="dimen">
+        0.35
+    </item>
+    <dimen name="dream_overlay_bottom_affordance_ambient_text_shadow_dx">0.5dp</dimen>
+    <dimen name="dream_overlay_bottom_affordance_ambient_text_shadow_dy">0.5dp</dimen>
+    <dimen name="dream_overlay_bottom_affordance_ambient_text_shadow_radius">2dp</dimen>
+    <item name="dream_overlay_bottom_affordance_ambient_shadow_alpha" format="float" type="dimen">
+        0.4
+    </item>
+    <dimen name="dream_overlay_bottom_affordance_inset">1dp</dimen>
     <dimen name="dream_overlay_bottom_affordance_padding">14dp</dimen>
     <dimen name="dream_overlay_complication_clock_time_text_size">86dp</dimen>
     <dimen name="dream_overlay_complication_clock_subtitle_text_size">24sp</dimen>
@@ -1712,15 +1730,15 @@
     <!-- Keyboard backlight indicator-->
     <dimen name="backlight_indicator_root_corner_radius">48dp</dimen>
     <dimen name="backlight_indicator_root_vertical_padding">8dp</dimen>
-    <dimen name="backlight_indicator_root_horizontal_padding">4dp</dimen>
+    <dimen name="backlight_indicator_root_horizontal_padding">6dp</dimen>
     <dimen name="backlight_indicator_icon_width">22dp</dimen>
     <dimen name="backlight_indicator_icon_height">11dp</dimen>
-    <dimen name="backlight_indicator_icon_left_margin">2dp</dimen>
+    <dimen name="backlight_indicator_icon_padding">10dp</dimen>
     <dimen name="backlight_indicator_step_width">52dp</dimen>
     <dimen name="backlight_indicator_step_height">40dp</dimen>
-    <dimen name="backlight_indicator_step_horizontal_margin">4dp</dimen>
+    <dimen name="backlight_indicator_step_horizontal_margin">2dp</dimen>
     <dimen name="backlight_indicator_step_small_radius">4dp</dimen>
-    <dimen name="backlight_indicator_step_large_radius">48dp</dimen>
+    <dimen name="backlight_indicator_step_large_radius">28dp</dimen>
 
     <!-- Broadcast dialog -->
     <dimen name="broadcast_dialog_title_img_margin_top">18dp</dimen>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index eaeaabe..e5c9461 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -203,5 +203,8 @@
 
     <item type="id" name="log_access_dialog_allow_button" />
     <item type="id" name="log_access_dialog_deny_button" />
+
+    <!-- keyboard backlight indicator-->
+    <item type="id" name="backlight_icon" />
 </resources>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index cbc73fa..67fdb4c 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -295,9 +295,8 @@
     <string name="screenrecord_save_title">Screen recording saved</string>
     <!-- Subtext for a notification shown after saving a screen recording to prompt the user to view it [CHAR_LIMIT=100] -->
     <string name="screenrecord_save_text">Tap to view</string>
-    <!-- A toast message shown when there is an error deleting a screen recording [CHAR LIMIT=NONE] -->
-    <string name="screenrecord_delete_error">Error deleting screen recording</string>
-    <!-- A toast message shown when the screen recording cannot be started due to insufficient permissions [CHAR LIMIT=NONE] -->
+    <!-- A toast message shown when there is an error saving a screen recording [CHAR LIMIT=NONE] -->
+    <string name="screenrecord_save_error">Error saving screen recording</string>
     <!-- A toast message shown when the screen recording cannot be started due to a generic error [CHAR LIMIT=NONE] -->
     <string name="screenrecord_start_error">Error starting screen recording</string>
 
@@ -354,7 +353,7 @@
     <!-- Message shown when a biometric is authenticated, waiting for the user to confirm authentication [CHAR LIMIT=40]-->
     <string name="biometric_dialog_tap_confirm">Tap Confirm to complete</string>
     <!-- Message shown when a biometric has authenticated with a user's face and is waiting for the user to confirm authentication [CHAR LIMIT=60]-->
-    <string name="biometric_dialog_tap_confirm_with_face">Unlocked by face. Press the unlock icon to continue.</string>
+    <string name="biometric_dialog_tap_confirm_with_face">Unlocked by face.</string>
     <!-- Message shown when a biometric has authenticated with a user's face and is waiting for the user to confirm authentication [CHAR LIMIT=60]-->
     <string name="biometric_dialog_tap_confirm_with_face_alt_1">Unlocked by face. Press to continue.</string>
     <!-- Message shown when a biometric has authenticated with a user's face and is waiting for the user to confirm authentication [CHAR LIMIT=60]-->
@@ -2583,7 +2582,7 @@
     <!-- Title for media controls [CHAR_LIMIT=50] -->
     <string name="controls_media_title">Media</string>
     <!-- Explanation for closing controls associated with a specific media session [CHAR_LIMIT=50] -->
-    <string name="controls_media_close_session">Hide this media control for <xliff:g id="app_name" example="YouTube Music">%1$s</xliff:g>?</string>
+    <string name="controls_media_close_session">Hide this media control for <xliff:g id="app_name" example="Foo Music App">%1$s</xliff:g>?</string>
     <!-- Explanation that controls associated with a specific media session are active [CHAR_LIMIT=50] -->
     <string name="controls_media_active_session">The current media session cannot be hidden.</string>
     <!-- Label for a button that will hide media controls [CHAR_LIMIT=30] -->
@@ -2596,6 +2595,8 @@
     <string name="controls_media_playing_item_description"><xliff:g id="song_name" example="Daily mix">%1$s</xliff:g> by <xliff:g id="artist_name" example="Various artists">%2$s</xliff:g> is playing from <xliff:g id="app_label" example="Spotify">%3$s</xliff:g></string>
     <!-- Content description for media cotnrols progress bar [CHAR_LIMIT=NONE] -->
     <string name="controls_media_seekbar_description"><xliff:g id="elapsed_time" example="1:30">%1$s</xliff:g> of <xliff:g id="total_time" example="3:00">%2$s</xliff:g></string>
+    <!-- Placeholder title to inform user that an app has posted media controls [CHAR_LIMIT=NONE] -->
+    <string name="controls_media_empty_title"><xliff:g id="app_name" example="Foo Music App">%1$s</xliff:g> is running</string>
 
     <!-- Description for button in media controls. Pressing button starts playback [CHAR_LIMIT=NONE] -->
     <string name="controls_media_button_play">Play</string>
@@ -3101,17 +3102,20 @@
     <!-- Switch to work profile dialer app for placing a call dialog. -->
     <!-- Text for Switch to work profile dialog's Title. Switch to work profile dialog guide users to make call from work
     profile dialer app as it's not possible to make call from current profile due to an admin policy. [CHAR LIMIT=60] -->
-    <string name="call_from_work_profile_title">Can\'t call from this profile</string>
+    <string name="call_from_work_profile_title">Can\'t call from a personal app</string>
     <!-- Text for switch to work profile for call dialog to guide users to make call from work
     profile dialer app as it's not possible to make call from current profile due to an admin policy. [CHAR LIMIT=NONE]
     -->
-    <string name="call_from_work_profile_text">Your work policy allows you to make phone calls only from the work profile</string>
+    <string name="call_from_work_profile_text">Your organization only allows you to make calls from work apps</string>
     <!-- Label for the button to switch to work profile for placing call. Switch to work profile dialog guide users to make call from work
     profile dialer app as it's not possible to make call from current profile due to an admin policy.[CHAR LIMIT=60] -->
     <string name="call_from_work_profile_action">Switch to work profile</string>
+    <!-- Label for the button to switch to work profile for placing call. Switch to work profile dialog guide users to make call from work
+    profile dialer app as it's not possible to make call from current profile due to an admin policy.[CHAR LIMIT=60] -->
+    <string name="install_dialer_on_work_profile_action">Install a work phone app</string>
     <!-- Label for the close button on switch to work profile dialog. Switch to work profile dialog guide users to make call from work
     profile dialer app as it's not possible to make call from current profile due to an admin policy.[CHAR LIMIT=60] -->
-    <string name="call_from_work_profile_close">Close</string>
+    <string name="call_from_work_profile_close">Cancel</string>
 
     <!--
     Label for a menu item in a menu that is shown when the user wishes to customize the lock screen.
diff --git a/packages/SystemUI/res/xml/media_session_collapsed.xml b/packages/SystemUI/res/xml/media_session_collapsed.xml
index 5129fc0..c053b33 100644
--- a/packages/SystemUI/res/xml/media_session_collapsed.xml
+++ b/packages/SystemUI/res/xml/media_session_collapsed.xml
@@ -63,8 +63,8 @@
         android:layout_marginEnd="@dimen/qs_media_padding"
         app:layout_constraintEnd_toStartOf="@id/action_button_guideline"
         app:layout_constrainedWidth="true"
-        app:layout_constraintTop_toBottomOf="@id/icon"
         app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintBottom_toTopOf="@id/header_artist"
         app:layout_constraintHorizontal_bias="0" />
 
     <Constraint
@@ -87,11 +87,12 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginEnd="@dimen/qs_media_padding"
+        android:layout_marginBottom="@dimen/qs_media_padding"
         android:layout_marginTop="0dp"
         app:layout_constraintEnd_toStartOf="@id/action_button_guideline"
         app:layout_constrainedWidth="true"
-        app:layout_constraintTop_toBottomOf="@id/header_title"
         app:layout_constraintStart_toEndOf="@id/media_explicit_indicator"
+        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintVertical_bias="0" />
 
     <Constraint
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.java b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.java
index 6bf1ce5..9bead94 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.java
@@ -234,10 +234,27 @@
     }
 
     protected final String getTag() {
+        if (isOverridingCondition()) {
+            return mTag + "[OVRD]";
+        }
+
         return mTag;
     }
 
     /**
+     * Returns the state of the condition.
+     * - "Invalid", condition hasn't been set / not monitored
+     * - "True", condition has been met
+     * - "False", condition has not been met
+     */
+    protected final String getState() {
+        if (!isConditionSet()) {
+            return "Invalid";
+        }
+        return isConditionMet() ? "True" : "False";
+    }
+
+    /**
      * Creates a new condition which will only be true when both this condition and all the provided
      * conditions are true.
      */
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Monitor.java b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Monitor.java
index 43df08d..1f61c64 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Monitor.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Monitor.java
@@ -22,6 +22,7 @@
 import androidx.annotation.NonNull;
 
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.log.TableLogBufferBase;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -41,6 +42,7 @@
     private final String mTag = getClass().getSimpleName();
     private final Executor mExecutor;
     private final Set<Condition> mPreconditions;
+    private final TableLogBufferBase mLogBuffer;
 
     private final HashMap<Condition, ArraySet<Subscription.Token>> mConditions = new HashMap<>();
     private final HashMap<Subscription.Token, SubscriptionState> mSubscriptions = new HashMap<>();
@@ -160,11 +162,23 @@
      * Main constructor, allowing specifying preconditions.
      */
     public Monitor(Executor executor, Set<Condition> preconditions) {
+        this(executor, preconditions, null);
+    }
+
+    /**
+     * Main constructor, allowing specifying preconditions and a log buffer for logging.
+     */
+    public Monitor(Executor executor, Set<Condition> preconditions, TableLogBufferBase logBuffer) {
         mExecutor = executor;
         mPreconditions = preconditions;
+        mLogBuffer = logBuffer;
     }
 
     private void updateConditionMetState(Condition condition) {
+        if (mLogBuffer != null) {
+            mLogBuffer.logChange(/* prefix= */ "", condition.getTag(), condition.getState());
+        }
+
         final ArraySet<Subscription.Token> subscriptions = mConditions.get(condition);
 
         // It's possible the condition was removed between the time the callback occurred and
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
index b8bddd1..117cf78a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
@@ -34,12 +34,12 @@
     /**
      * Begins screen pinning on the provided {@param taskId}.
      */
-    void startScreenPinning(int taskId) = 1;
+    oneway void startScreenPinning(int taskId) = 1;
 
     /**
      * Notifies SystemUI that Overview is shown.
      */
-    void onOverviewShown(boolean fromHome) = 6;
+    oneway void onOverviewShown(boolean fromHome) = 6;
 
     /**
      * Proxies motion events from the homescreen UI to the status bar. Only called when
@@ -48,57 +48,57 @@
      *
      * Normal gesture: DOWN, MOVE/POINTER_DOWN/POINTER_UP)*, UP or CANCLE
      */
-    void onStatusBarMotionEvent(in MotionEvent event) = 9;
+    oneway void onStatusBarMotionEvent(in MotionEvent event) = 9;
 
     /**
      * Proxies the assistant gesture's progress started from navigation bar.
      */
-    void onAssistantProgress(float progress) = 12;
+    oneway void onAssistantProgress(float progress) = 12;
 
     /**
     * Proxies the assistant gesture fling velocity (in pixels per millisecond) upon completion.
     * Velocity is 0 for drag gestures.
     */
-    void onAssistantGestureCompletion(float velocity) = 18;
+    oneway void onAssistantGestureCompletion(float velocity) = 18;
 
     /**
      * Start the assistant.
      */
-    void startAssistant(in Bundle bundle) = 13;
+    oneway void startAssistant(in Bundle bundle) = 13;
 
     /**
      * Notifies that the accessibility button in the system's navigation area has been clicked
      */
-    void notifyAccessibilityButtonClicked(int displayId) = 15;
+    oneway void notifyAccessibilityButtonClicked(int displayId) = 15;
 
     /**
      * Notifies that the accessibility button in the system's navigation area has been long clicked
      */
-    void notifyAccessibilityButtonLongClicked() = 16;
+    oneway void notifyAccessibilityButtonLongClicked() = 16;
 
     /**
      * Ends the system screen pinning.
      */
-    void stopScreenPinning() = 17;
+    oneway void stopScreenPinning() = 17;
 
     /**
      * Notifies that quickstep will switch to a new task
      * @param rotation indicates which Surface.Rotation the gesture was started in
      */
-    void notifyPrioritizedRotation(int rotation) = 25;
+    oneway void notifyPrioritizedRotation(int rotation) = 25;
 
     /**
      * Notifies to expand notification panel.
      */
-    void expandNotificationPanel() = 29;
+    oneway void expandNotificationPanel() = 29;
 
     /**
      * Notifies SystemUI to invoke Back.
      */
-    void onBackPressed() = 44;
+    oneway void onBackPressed() = 44;
 
     /** Sets home rotation enabled. */
-    void setHomeRotationEnabled(boolean enabled) = 45;
+    oneway void setHomeRotationEnabled(boolean enabled) = 45;
 
     /** Notifies when taskbar status updated */
     oneway void notifyTaskbarStatus(boolean visible, boolean stashed) = 47;
@@ -113,17 +113,17 @@
     /**
      * Notifies SystemUI to invoke IME Switcher.
      */
-    void onImeSwitcherPressed() = 49;
+    oneway void onImeSwitcherPressed() = 49;
 
     /**
      * Notifies to toggle notification panel.
      */
-    void toggleNotificationPanel() = 50;
+    oneway void toggleNotificationPanel() = 50;
 
     /**
      * Handle the screenshot request.
      */
-    void takeScreenshot(in ScreenshotRequest request) = 51;
+    oneway void takeScreenshot(in ScreenshotRequest request) = 51;
 
     // Next id = 52
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSampler.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSampler.kt
index 482158e..9a00447 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSampler.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSampler.kt
@@ -21,9 +21,9 @@
 import android.graphics.Point
 import android.graphics.Rect
 import android.graphics.RectF
+import android.util.Log
 import android.view.View
 import androidx.annotation.VisibleForTesting
-import com.android.systemui.shared.navigationbar.RegionSamplingHelper
 import java.io.PrintWriter
 import java.util.concurrent.Executor
 
@@ -31,20 +31,21 @@
 open class RegionSampler
 @JvmOverloads
 constructor(
-    val sampledView: View?,
+    val sampledView: View,
     mainExecutor: Executor?,
     val bgExecutor: Executor?,
     val regionSamplingEnabled: Boolean,
+    val isLockscreen: Boolean = false,
+    val wallpaperManager: WallpaperManager? = WallpaperManager.getInstance(sampledView.context),
     val updateForegroundColor: UpdateColorCallback,
-    val wallpaperManager: WallpaperManager? = WallpaperManager.getInstance(sampledView?.context)
 ) : WallpaperManager.LocalWallpaperColorConsumer {
     private var regionDarkness = RegionDarkness.DEFAULT
     private var samplingBounds = Rect()
     private val tmpScreenLocation = IntArray(2)
-    @VisibleForTesting var regionSampler: RegionSamplingHelper? = null
     private var lightForegroundColor = Color.WHITE
     private var darkForegroundColor = Color.BLACK
-    private val displaySize = Point()
+    @VisibleForTesting val displaySize = Point()
+    private var initialSampling: WallpaperColors? = null
 
     /**
      * Sets the colors to be used for Dark and Light Foreground.
@@ -57,6 +58,36 @@
         darkForegroundColor = darkColor
     }
 
+    private val layoutChangedListener =
+        object : View.OnLayoutChangeListener {
+
+            override fun onLayoutChange(
+                view: View?,
+                left: Int,
+                top: Int,
+                right: Int,
+                bottom: Int,
+                oldLeft: Int,
+                oldTop: Int,
+                oldRight: Int,
+                oldBottom: Int
+            ) {
+
+                // don't pass in negative bounds when region is in transition state
+                if (sampledView.locationOnScreen[0] < 0 || sampledView.locationOnScreen[1] < 0) {
+                    return
+                }
+
+                val currentViewRect = Rect(left, top, right, bottom)
+                val oldViewRect = Rect(oldLeft, oldTop, oldRight, oldBottom)
+
+                if (currentViewRect != oldViewRect) {
+                    stopRegionSampler()
+                    startRegionSampler()
+                }
+            }
+        }
+
     /**
      * Determines which foreground color to use based on region darkness.
      *
@@ -84,40 +115,57 @@
 
     /** Start region sampler */
     fun startRegionSampler() {
-        if (!regionSamplingEnabled || sampledView == null) {
+
+        if (!regionSamplingEnabled) {
+            if (DEBUG) Log.d(TAG, "startRegionSampler() | RegionSampling flag not enabled")
             return
         }
 
-        val sampledRegion = calculateSampledRegion(sampledView)
-        val regions = ArrayList<RectF>()
-        val sampledRegionWithOffset = convertBounds(sampledRegion)
+        sampledView.addOnLayoutChangeListener(layoutChangedListener)
 
+        val screenLocationBounds = calculateScreenLocation(sampledView)
+        if (screenLocationBounds == null) {
+            if (DEBUG) Log.d(TAG, "startRegionSampler() | passed in null region")
+            return
+        }
+        if (screenLocationBounds.isEmpty) {
+            if (DEBUG) Log.d(TAG, "startRegionSampler() | passed in empty region")
+            return
+        }
+
+        val sampledRegionWithOffset = convertBounds(screenLocationBounds)
         if (
             sampledRegionWithOffset.left < 0.0 ||
                 sampledRegionWithOffset.right > 1.0 ||
                 sampledRegionWithOffset.top < 0.0 ||
                 sampledRegionWithOffset.bottom > 1.0
         ) {
-            android.util.Log.e(
-                "RegionSampler",
-                "view out of bounds: $sampledRegion | " +
-                    "screen width: ${displaySize.x}, screen height: ${displaySize.y}",
-                Exception()
-            )
+            if (DEBUG)
+                Log.d(
+                    TAG,
+                    "startRegionSampler() | view out of bounds: $screenLocationBounds | " +
+                        "screen width: ${displaySize.x}, screen height: ${displaySize.y}",
+                    Exception()
+                )
             return
         }
 
+        val regions = ArrayList<RectF>()
         regions.add(sampledRegionWithOffset)
 
-        wallpaperManager?.removeOnColorsChangedListener(this)
-        wallpaperManager?.addOnColorsChangedListener(this, regions)
+        wallpaperManager?.addOnColorsChangedListener(
+            this,
+            regions,
+            if (isLockscreen) WallpaperManager.FLAG_LOCK else WallpaperManager.FLAG_SYSTEM
+        )
 
-        // TODO(b/265969235): conditionally set FLAG_LOCK or FLAG_SYSTEM once HS smartspace
-        // implemented
         bgExecutor?.execute(
             Runnable {
-                val initialSampling =
-                    wallpaperManager?.getWallpaperColors(WallpaperManager.FLAG_LOCK)
+                initialSampling =
+                    wallpaperManager?.getWallpaperColors(
+                        if (isLockscreen) WallpaperManager.FLAG_LOCK
+                        else WallpaperManager.FLAG_SYSTEM
+                    )
                 onColorsChanged(sampledRegionWithOffset, initialSampling)
             }
         )
@@ -126,6 +174,7 @@
     /** Stop region sampler */
     fun stopRegionSampler() {
         wallpaperManager?.removeOnColorsChangedListener(this)
+        sampledView.removeOnLayoutChangeListener(layoutChangedListener)
     }
 
     /** Dump region sampler */
@@ -138,22 +187,23 @@
         pw.println("passed-in sampledView: $sampledView")
         pw.println("calculated samplingBounds: $samplingBounds")
         pw.println(
-            "sampledView width: ${sampledView?.width}, sampledView height: ${sampledView?.height}"
+            "sampledView width: ${sampledView.width}, sampledView height: ${sampledView.height}"
         )
         pw.println("screen width: ${displaySize.x}, screen height: ${displaySize.y}")
         pw.println(
-            "sampledRegionWithOffset: ${convertBounds(calculateSampledRegion(sampledView!!))}"
+            "sampledRegionWithOffset: ${convertBounds(
+                    calculateScreenLocation(sampledView) ?: RectF())}"
         )
-        // TODO(b/265969235): mock initialSampling based on if component is on HS or LS wallpaper
-        // HS Smartspace - wallpaperManager?.getWallpaperColors(WallpaperManager.FLAG_SYSTEM)
-        // LS Smartspace, clock - wallpaperManager?.getWallpaperColors(WallpaperManager.FLAG_LOCK)
         pw.println(
-            "initialSampling for lockscreen: " +
-                "${wallpaperManager?.getWallpaperColors(WallpaperManager.FLAG_LOCK)}"
+            "initialSampling for ${if (isLockscreen) "lockscreen" else "homescreen" }" +
+                ": $initialSampling"
         )
     }
 
-    fun calculateSampledRegion(sampledView: View): RectF {
+    fun calculateScreenLocation(sampledView: View): RectF? {
+
+        if (!sampledView.isLaidOut) return null
+
         val screenLocation = tmpScreenLocation
         /**
          * The method getLocationOnScreen is used to obtain the view coordinates relative to its
@@ -181,7 +231,8 @@
      */
     fun convertBounds(originalBounds: RectF): RectF {
 
-        // TODO(b/265969235): GRAB # PAGES + CURRENT WALLPAPER PAGE # FROM LAUNCHER
+        // TODO(b/265969235): GRAB # PAGES + CURRENT WALLPAPER PAGE # FROM LAUNCHER (--> HS
+        // Smartspace always on 1st page)
         // TODO(b/265968912): remove hard-coded value once LS wallpaper supported
         val wallpaperPageNum = 0
         val numScreens = 1
@@ -214,6 +265,11 @@
             )
         updateForegroundColor()
     }
+
+    companion object {
+        private const val TAG = "RegionSampler"
+        private const val DEBUG = false
+    }
 }
 
 typealias UpdateColorCallback = () -> Unit
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowIconDrawable.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowIconDrawable.kt
index 19d0a3d..6b9274c 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowIconDrawable.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowIconDrawable.kt
@@ -15,6 +15,7 @@
  */
 package com.android.systemui.shared.shadow
 
+import android.content.res.ColorStateList
 import android.graphics.BlendMode
 import android.graphics.Canvas
 import android.graphics.Color
@@ -106,6 +107,14 @@
         mIconDrawable.draw(canvas)
     }
 
+    override fun getIntrinsicHeight(): Int {
+        return mCanvasSize
+    }
+
+    override fun getIntrinsicWidth(): Int {
+        return mCanvasSize
+    }
+
     override fun getOpacity(): Int {
         return PixelFormat.TRANSPARENT
     }
@@ -121,4 +130,8 @@
     override fun setTint(color: Int) {
         mIconDrawable.setTint(color)
     }
+
+    override fun setTintList(tint: ColorStateList?) {
+        mIconDrawable.setTintList(tint)
+    }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java
index 8dcd2aa..1e7222d 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java
@@ -41,6 +41,7 @@
 import com.android.wm.shell.util.CounterRotator;
 
 public abstract class RemoteAnimationRunnerCompat extends IRemoteAnimationRunner.Stub {
+    private static final String TAG = "RemoteAnimRunnerCompat";
 
     public abstract void onAnimationStart(@WindowManager.TransitionOldType int transit,
             RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
@@ -58,20 +59,24 @@
                     try {
                         finishedCallback.onAnimationFinished();
                     } catch (RemoteException e) {
-                        Log.e("ActivityOptionsCompat", "Failed to call app controlled animation"
-                                + " finished callback", e);
+                        Log.e(TAG, "Failed to call app controlled animation finished callback", e);
                     }
                 });
     }
 
     public IRemoteTransition toRemoteTransition() {
+        return wrap(this);
+    }
+
+    /** Wraps a remote animation runner in a remote-transition. */
+    public static IRemoteTransition.Stub wrap(IRemoteAnimationRunner runner) {
         return new IRemoteTransition.Stub() {
             final ArrayMap<IBinder, Runnable> mFinishRunnables = new ArrayMap<>();
 
             @Override
             public void startAnimation(IBinder token, TransitionInfo info,
                     SurfaceControl.Transaction t,
-                    IRemoteTransitionFinishedCallback finishCallback) {
+                    IRemoteTransitionFinishedCallback finishCallback) throws RemoteException {
                 final ArrayMap<SurfaceControl, SurfaceControl> leashMap = new ArrayMap<>();
                 final RemoteAnimationTarget[] apps =
                         RemoteAnimationTargetCompat.wrapApps(info, t, leashMap);
@@ -115,8 +120,14 @@
                 final CounterRotator counterLauncher = new CounterRotator();
                 final CounterRotator counterWallpaper = new CounterRotator();
                 if (launcherTask != null && rotateDelta != 0 && launcherTask.getParent() != null) {
-                    counterLauncher.setup(t, info.getChange(launcherTask.getParent()).getLeash(),
-                            rotateDelta, displayW, displayH);
+                    final TransitionInfo.Change parent = info.getChange(launcherTask.getParent());
+                    if (parent != null) {
+                        counterLauncher.setup(t, parent.getLeash(), rotateDelta, displayW,
+                                displayH);
+                    } else {
+                        Log.e(TAG, "Malformed: " + launcherTask + " has parent="
+                                + launcherTask.getParent() + " but it's not in info.");
+                    }
                     if (counterLauncher.getSurface() != null) {
                         t.setLayer(counterLauncher.getSurface(), launcherLayer);
                     }
@@ -150,8 +161,14 @@
                         counterLauncher.addChild(t, leashMap.get(launcherTask.getLeash()));
                     }
                     if (wallpaper != null && rotateDelta != 0 && wallpaper.getParent() != null) {
-                        counterWallpaper.setup(t, info.getChange(wallpaper.getParent()).getLeash(),
-                                rotateDelta, displayW, displayH);
+                        final TransitionInfo.Change parent = info.getChange(wallpaper.getParent());
+                        if (parent != null) {
+                            counterWallpaper.setup(t, parent.getLeash(), rotateDelta, displayW,
+                                    displayH);
+                        } else {
+                            Log.e(TAG, "Malformed: " + wallpaper + " has parent="
+                                    + wallpaper.getParent() + " but it's not in info.");
+                        }
                         if (counterWallpaper.getSurface() != null) {
                             t.setLayer(counterWallpaper.getSurface(), -1);
                             counterWallpaper.addChild(t, leashMap.get(wallpaper.getLeash()));
@@ -175,20 +192,27 @@
                         finishCallback.onTransitionFinished(null /* wct */, finishTransaction);
                         finishTransaction.close();
                     } catch (RemoteException e) {
-                        Log.e("ActivityOptionsCompat", "Failed to call app controlled animation"
-                                + " finished callback", e);
+                        Log.e(TAG, "Failed to call app controlled animation finished callback", e);
                     }
                 };
                 synchronized (mFinishRunnables) {
                     mFinishRunnables.put(token, animationFinishedCallback);
                 }
                 // TODO(bc-unlcok): Pass correct transit type.
-                onAnimationStart(TRANSIT_OLD_NONE,
-                        apps, wallpapers, nonApps, () -> {
-                            synchronized (mFinishRunnables) {
-                                if (mFinishRunnables.remove(token) == null) return;
+                runner.onAnimationStart(TRANSIT_OLD_NONE,
+                        apps, wallpapers, nonApps, new IRemoteAnimationFinishedCallback() {
+                            @Override
+                            public void onAnimationFinished() {
+                                synchronized (mFinishRunnables) {
+                                    if (mFinishRunnables.remove(token) == null) return;
+                                }
+                                animationFinishedCallback.run();
                             }
-                            animationFinishedCallback.run();
+
+                            @Override
+                            public IBinder asBinder() {
+                                return null;
+                            }
                         });
             }
 
@@ -206,7 +230,7 @@
                 t.close();
                 info.releaseAllSurfaces();
                 if (finishRunnable == null) return;
-                onAnimationCancelled();
+                runner.onAnimationCancelled();
                 finishRunnable.run();
             }
         };
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
index 1fbf743..74c325d 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
@@ -352,7 +352,8 @@
 
         @Override public TaskSnapshot screenshotTask(int taskId) {
             try {
-                return ActivityTaskManager.getService().takeTaskSnapshot(taskId);
+                return ActivityTaskManager.getService().takeTaskSnapshot(taskId,
+                        true /* updateCache */);
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to screenshot task", e);
             }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/utils/TraceUtils.kt b/packages/SystemUI/shared/src/com/android/systemui/util/TraceUtils.kt
similarity index 100%
rename from packages/SystemUI/shared/src/com/android/systemui/utils/TraceUtils.kt
rename to packages/SystemUI/shared/src/com/android/systemui/util/TraceUtils.kt
diff --git a/packages/SystemUI/src-debug/com/android/systemui/util/StartBinderLoggerModule.kt b/packages/SystemUI/src-debug/com/android/systemui/util/StartBinderLoggerModule.kt
new file mode 100644
index 0000000..d48c5b9
--- /dev/null
+++ b/packages/SystemUI/src-debug/com/android/systemui/util/StartBinderLoggerModule.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.util
+
+import com.android.systemui.CoreStartable
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
+
+@Module
+abstract class StartBinderLoggerModule {
+    @Binds
+    @IntoMap
+    @ClassKey(BinderLogger::class)
+    abstract fun bindBinderLogger(impl: BinderLogger): CoreStartable
+}
diff --git a/packages/SystemUI/src-release/com/android/systemui/util/StartBinderLoggerModule.kt b/packages/SystemUI/src-release/com/android/systemui/util/StartBinderLoggerModule.kt
new file mode 100644
index 0000000..6914c57
--- /dev/null
+++ b/packages/SystemUI/src-release/com/android/systemui/util/StartBinderLoggerModule.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.util
+
+import dagger.Module
+
+@Module
+abstract class StartBinderLoggerModule {
+    // Empty because this module is only used on debug builds
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt b/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
index a82f0e3..0842953 100644
--- a/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
+++ b/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
@@ -22,8 +22,6 @@
 import android.animation.ObjectAnimator
 import android.content.Context
 import android.content.res.ColorStateList
-import android.content.res.TypedArray
-import android.graphics.Color
 import android.util.AttributeSet
 import android.view.View
 import com.android.app.animation.Interpolators
@@ -41,12 +39,28 @@
     protected open val SHOW_DURATION_MILLIS = 150L
     protected open val HIDE_DURATION_MILLIS = 200L
 
+    override fun onFinishInflate() {
+        super.onFinishInflate()
+        mDefaultColorState = getColorInStyle()
+    }
+
+    private fun getColorInStyle(): ColorStateList? {
+        val styledAttributes =
+            context.obtainStyledAttributes(styleResId, intArrayOf(android.R.attr.textColor))
+        var colorStateList: ColorStateList? = null
+        if (styledAttributes != null) {
+            colorStateList = styledAttributes.getColorStateList(0)
+        }
+        styledAttributes.recycle()
+        return colorStateList
+    }
+
     override fun updateTextColor() {
         var colorState = mDefaultColorState
         mNextMessageColorState?.defaultColor?.let { color ->
             if (color != DEFAULT_COLOR) {
                 colorState = mNextMessageColorState
-                mNextMessageColorState = ColorStateList.valueOf(DEFAULT_COLOR)
+                mNextMessageColorState = mDefaultColorState ?: ColorStateList.valueOf(DEFAULT_COLOR)
             }
         }
         setTextColor(colorState)
@@ -57,15 +71,12 @@
     }
 
     override fun onThemeChanged() {
-        val array: TypedArray = mContext.obtainStyledAttributes(intArrayOf(TITLE))
-        val newTextColors: ColorStateList = ColorStateList.valueOf(array.getColor(0, Color.RED))
-        array.recycle()
-        mDefaultColorState = newTextColors
+        mDefaultColorState = getColorInStyle() ?: Utils.getColorAttr(context, TITLE)
         super.onThemeChanged()
     }
 
     override fun reloadColor() {
-        mDefaultColorState = Utils.getColorAttr(context, TITLE)
+        mDefaultColorState = getColorInStyle() ?: Utils.getColorAttr(context, TITLE)
         super.reloadColor()
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierText.java b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
index e4f6e131..87a9b0f 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierText.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
@@ -33,6 +33,8 @@
 
     private final boolean mShowAirplaneMode;
 
+    private final String mDebugLocation;
+
     public CarrierText(Context context) {
         this(context, null);
     }
@@ -46,6 +48,7 @@
             useAllCaps = a.getBoolean(R.styleable.CarrierText_allCaps, false);
             mShowAirplaneMode = a.getBoolean(R.styleable.CarrierText_showAirplaneMode, false);
             mShowMissingSim = a.getBoolean(R.styleable.CarrierText_showMissingSim, false);
+            mDebugLocation = a.getString(R.styleable.CarrierText_debugLocation);
         } finally {
             a.recycle();
         }
@@ -70,6 +73,10 @@
         return mShowMissingSim;
     }
 
+    public String getDebugLocation() {
+        return mDebugLocation;
+    }
+
     private static class CarrierTextTransformationMethod extends SingleLineTransformationMethod {
         private final Locale mLocale;
         private final boolean mAllCaps;
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index 997c527..33f9ecd 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -53,6 +53,7 @@
         mCarrierTextManager = carrierTextManagerBuilder
                 .setShowAirplaneMode(mView.getShowAirplaneMode())
                 .setShowMissingSim(mView.getShowMissingSim())
+                .setDebugLocationString(mView.getDebugLocation())
                 .build();
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
index b153785..a724514 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
@@ -16,6 +16,11 @@
 
 package com.android.keyguard;
 
+import static com.android.keyguard.logging.CarrierTextManagerLogger.REASON_ACTIVE_DATA_SUB_CHANGED;
+import static com.android.keyguard.logging.CarrierTextManagerLogger.REASON_ON_SIM_STATE_CHANGED;
+import static com.android.keyguard.logging.CarrierTextManagerLogger.REASON_ON_TELEPHONY_CAPABLE;
+import static com.android.keyguard.logging.CarrierTextManagerLogger.REASON_REFRESH_CARRIER_INFO;
+
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -32,6 +37,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.keyguard.logging.CarrierTextManagerLogger;
 import com.android.settingslib.WirelessUtils;
 import com.android.systemui.R;
 import com.android.systemui.dagger.qualifiers.Background;
@@ -40,6 +46,7 @@
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository;
 import com.android.systemui.telephony.TelephonyListenerManager;
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.Executor;
@@ -68,6 +75,7 @@
     private final AtomicBoolean mNetworkSupported = new AtomicBoolean();
     @VisibleForTesting
     protected KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    private final CarrierTextManagerLogger mLogger;
     private final WifiRepository mWifiRepository;
     private final boolean[] mSimErrorState;
     private final int mSimSlotsNumber;
@@ -97,19 +105,13 @@
     protected final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
         @Override
         public void onRefreshCarrierInfo() {
-            if (DEBUG) {
-                Log.d(TAG, "onRefreshCarrierInfo(), mTelephonyCapable: "
-                        + Boolean.toString(mTelephonyCapable));
-            }
+            mLogger.logUpdateCarrierTextForReason(REASON_REFRESH_CARRIER_INFO);
             updateCarrierText();
         }
 
         @Override
         public void onTelephonyCapable(boolean capable) {
-            if (DEBUG) {
-                Log.d(TAG, "onTelephonyCapable() mTelephonyCapable: "
-                        + Boolean.toString(capable));
-            }
+            mLogger.logUpdateCarrierTextForReason(REASON_ON_TELEPHONY_CAPABLE);
             mTelephonyCapable = capable;
             updateCarrierText();
         }
@@ -121,7 +123,7 @@
                 return;
             }
 
-            if (DEBUG) Log.d(TAG, "onSimStateChanged: " + getStatusForIccState(simState));
+            mLogger.logUpdateCarrierTextForReason(REASON_ON_SIM_STATE_CHANGED);
             if (getStatusForIccState(simState) == CarrierTextManager.StatusMode.SimIoError) {
                 mSimErrorState[slotId] = true;
                 updateCarrierText();
@@ -137,6 +139,7 @@
         @Override
         public void onActiveDataSubscriptionIdChanged(int subId) {
             if (mNetworkSupported.get() && mCarrierTextCallback != null) {
+                mLogger.logUpdateCarrierTextForReason(REASON_ACTIVE_DATA_SUB_CHANGED);
                 updateCarrierText();
             }
         }
@@ -175,7 +178,9 @@
             WakefulnessLifecycle wakefulnessLifecycle,
             @Main Executor mainExecutor,
             @Background Executor bgExecutor,
-            KeyguardUpdateMonitor keyguardUpdateMonitor) {
+            KeyguardUpdateMonitor keyguardUpdateMonitor,
+            CarrierTextManagerLogger logger) {
+
         mContext = context;
         mIsEmergencyCallCapable = telephonyManager.isVoiceCapable();
 
@@ -191,6 +196,7 @@
         mMainExecutor = mainExecutor;
         mBgExecutor = bgExecutor;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+        mLogger = logger;
         mBgExecutor.execute(() -> {
             boolean supported = mContext.getPackageManager()
                     .hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
@@ -315,7 +321,7 @@
             subOrderBySlot[i] = -1;
         }
         final CharSequence[] carrierNames = new CharSequence[numSubs];
-        if (DEBUG) Log.d(TAG, "updateCarrierText(): " + numSubs);
+        mLogger.logUpdate(numSubs);
 
         for (int i = 0; i < numSubs; i++) {
             int subId = subs.get(i).getSubscriptionId();
@@ -325,9 +331,7 @@
             int simState = mKeyguardUpdateMonitor.getSimState(subId);
             CharSequence carrierName = subs.get(i).getCarrierName();
             CharSequence carrierTextForSimState = getCarrierTextForSimState(simState, carrierName);
-            if (DEBUG) {
-                Log.d(TAG, "Handling (subId=" + subId + "): " + simState + " " + carrierName);
-            }
+            mLogger.logUpdateLoopStart(subId, simState, String.valueOf(carrierName));
             if (carrierTextForSimState != null) {
                 allSimsMissing = false;
                 carrierNames[i] = carrierTextForSimState;
@@ -340,9 +344,7 @@
                     // Wi-Fi is disassociated or disabled
                     if (ss.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
                             || mWifiRepository.isWifiConnectedWithValidSsid()) {
-                        if (DEBUG) {
-                            Log.d(TAG, "SIM ready and in service: subId=" + subId + ", ss=" + ss);
-                        }
+                        mLogger.logUpdateWfcCheck();
                         anySimReadyAndInService = true;
                     }
                 }
@@ -379,7 +381,7 @@
                     if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_PLMN, false)) {
                         plmn = i.getStringExtra(TelephonyManager.EXTRA_PLMN);
                     }
-                    if (DEBUG) Log.d(TAG, "Getting plmn/spn sticky brdcst " + plmn + "/" + spn);
+                    mLogger.logUpdateFromStickyBroadcast(plmn, spn);
                     if (Objects.equals(plmn, spn)) {
                         text = plmn;
                     } else {
@@ -409,6 +411,7 @@
                 !allSimsMissing,
                 subsIds,
                 airplaneMode);
+        mLogger.logCallbackSentFromUpdate(info);
         postToCallback(info);
         Trace.endSection();
     }
@@ -645,8 +648,10 @@
         private final Executor mMainExecutor;
         private final Executor mBgExecutor;
         private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+        private final CarrierTextManagerLogger mLogger;
         private boolean mShowAirplaneMode;
         private boolean mShowMissingSim;
+        private String mDebugLocation;
 
         @Inject
         public Builder(
@@ -658,7 +663,8 @@
                 WakefulnessLifecycle wakefulnessLifecycle,
                 @Main Executor mainExecutor,
                 @Background Executor bgExecutor,
-                KeyguardUpdateMonitor keyguardUpdateMonitor) {
+                KeyguardUpdateMonitor keyguardUpdateMonitor,
+                CarrierTextManagerLogger logger) {
             mContext = context;
             mSeparator = resources.getString(
                     com.android.internal.R.string.kg_text_message_separator);
@@ -669,6 +675,7 @@
             mMainExecutor = mainExecutor;
             mBgExecutor = bgExecutor;
             mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+            mLogger = logger;
         }
 
         /** */
@@ -683,14 +690,25 @@
             return this;
         }
 
+        /**
+         * To help disambiguate logs, set a location to be used in the LogBuffer calls, e.g.:
+         * "keyguard" or "keyguard emergency status bar"
+         */
+        public Builder setDebugLocationString(String debugLocationString) {
+            mDebugLocation = debugLocationString;
+            return this;
+        }
+
         /** Create a CarrierTextManager. */
         public CarrierTextManager build() {
+            mLogger.setLocation(mDebugLocation);
             return new CarrierTextManager(
                     mContext, mSeparator, mShowAirplaneMode, mShowMissingSim, mWifiRepository,
                     mTelephonyManager, mTelephonyListenerManager, mWakefulnessLifecycle,
-                    mMainExecutor, mBgExecutor, mKeyguardUpdateMonitor);
+                    mMainExecutor, mBgExecutor, mKeyguardUpdateMonitor, mLogger);
         }
     }
+
     /**
      * Data structure for passing information to CarrierTextController subscribers
      */
@@ -716,6 +734,17 @@
             this.subscriptionIds = subscriptionIds;
             this.airplaneMode = airplaneMode;
         }
+
+        @Override
+        public String toString() {
+            return "CarrierTextCallbackInfo{"
+                    + "carrierText=" + carrierText
+                    + ", listOfCarriers=" + Arrays.toString(listOfCarriers)
+                    + ", anySimReady=" + anySimReady
+                    + ", subscriptionIds=" + Arrays.toString(subscriptionIds)
+                    + ", airplaneMode=" + airplaneMode
+                    + '}';
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index 4bf7be6..8ea4c31a 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -21,13 +21,12 @@
 import android.content.Intent
 import android.content.IntentFilter
 import android.content.res.Resources
-import android.graphics.Rect
 import android.text.format.DateFormat
 import android.util.TypedValue
+import android.util.Log
 import android.view.View
 import android.view.View.OnAttachStateChangeListener
 import android.view.ViewTreeObserver
-import android.widget.FrameLayout
 import androidx.annotation.VisibleForTesting
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
@@ -55,16 +54,16 @@
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.concurrency.DelayableExecutor
-import java.util.Locale
-import java.util.TimeZone
-import java.util.concurrent.Executor
-import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.DisposableHandle
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.launch
+import java.util.Locale
+import java.util.TimeZone
+import java.util.concurrent.Executor
+import javax.inject.Inject
 
 /**
  * Controller for a Clock provided by the registry and used on the keyguard. Instantiated by
@@ -98,16 +97,17 @@
 
                 value.initialize(resources, dozeAmount, 0f)
 
-                if (regionSamplingEnabled) {
-                    clock?.run {
-                        smallClock.view.addOnLayoutChangeListener(mLayoutChangedListener)
-                        largeClock.view.addOnLayoutChangeListener(mLayoutChangedListener)
-                    }
-                } else {
+                if (!regionSamplingEnabled) {
                     updateColors()
                 }
                 updateFontSizes()
                 updateTimeListeners()
+                cachedWeatherData?.let {
+                    if (WeatherData.DEBUG) {
+                        Log.i(TAG, "Pushing cached weather data to new clock: $it")
+                    }
+                    value.events.onWeatherDataChanged(it)
+                }
                 value.smallClock.view.addOnAttachStateChangeListener(
                     object : OnAttachStateChangeListener {
                         override fun onViewAttachedToWindow(p0: View?) {
@@ -139,44 +139,10 @@
     private var disposableHandle: DisposableHandle? = null
     private val regionSamplingEnabled = featureFlags.isEnabled(REGION_SAMPLING)
 
-    private val mLayoutChangedListener =
-        object : View.OnLayoutChangeListener {
-
-            override fun onLayoutChange(
-                view: View?,
-                left: Int,
-                top: Int,
-                right: Int,
-                bottom: Int,
-                oldLeft: Int,
-                oldTop: Int,
-                oldRight: Int,
-                oldBottom: Int
-            ) {
-                view?.removeOnLayoutChangeListener(this)
-
-                val parent = (view?.parent) as FrameLayout
-
-                // don't pass in negative bounds when clocks are in transition state
-                if (view.locationOnScreen[0] < 0 || view.locationOnScreen[1] < 0) {
-                    return
-                }
-
-                val currentViewRect = Rect(left, top, right, bottom)
-                val oldViewRect = Rect(oldLeft, oldTop, oldRight, oldBottom)
-
-                if (
-                    currentViewRect.width() != oldViewRect.width() ||
-                        currentViewRect.height() != oldViewRect.height()
-                ) {
-                    updateRegionSampler(view)
-                }
-            }
-        }
 
     private fun updateColors() {
         val wallpaperManager = WallpaperManager.getInstance(context)
-        if (regionSamplingEnabled && !wallpaperManager.lockScreenWallpaperExists()) {
+        if (regionSamplingEnabled) {
             regionSampler?.let { regionSampler ->
                 clock?.let { clock ->
                     if (regionSampler.sampledView == clock.smallClock.view) {
@@ -211,6 +177,7 @@
                     mainExecutor,
                     bgExecutor,
                     regionSamplingEnabled,
+                    isLockscreen = true,
                     ::updateColors
                 )
                 ?.apply { startRegionSampler() }
@@ -219,10 +186,11 @@
     }
 
     protected open fun createRegionSampler(
-        sampledView: View?,
+        sampledView: View,
         mainExecutor: Executor?,
         bgExecutor: Executor?,
         regionSamplingEnabled: Boolean,
+        isLockscreen: Boolean,
         updateColors: () -> Unit
     ): RegionSampler? {
         return RegionSampler(
@@ -230,8 +198,8 @@
             mainExecutor,
             bgExecutor,
             regionSamplingEnabled,
-            updateColors
-        )
+            isLockscreen,
+        ) { updateColors() }
     }
 
     var regionSampler: RegionSampler? = null
@@ -239,6 +207,7 @@
     var largeTimeListener: TimeListener? = null
     val shouldTimeListenerRun: Boolean
         get() = isKeyguardVisible && dozeAmount < DOZE_TICKRATE_THRESHOLD
+    private var cachedWeatherData: WeatherData? = null
 
     private var smallClockIsDark = true
     private var largeClockIsDark = true
@@ -305,6 +274,7 @@
             }
 
             override fun onWeatherDataChanged(data: WeatherData) {
+                cachedWeatherData = data
                 clock?.run { events.onWeatherDataChanged(data) }
             }
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index b18abf3..c6d1471 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -22,6 +22,8 @@
 import android.view.KeyEvent;
 import android.view.View;
 
+import androidx.annotation.CallSuper;
+
 import com.android.internal.widget.LockscreenCredential;
 import com.android.systemui.R;
 
@@ -48,7 +50,9 @@
     protected abstract void resetState();
 
     @Override
+    @CallSuper
     protected void onFinishInflate() {
+        super.onFinishInflate();
         mEcaView = findViewById(R.id.keyguard_selector_fade_container);
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
index 510fcbf..e057188 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
@@ -37,6 +37,7 @@
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingClassifier;
 import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.flags.FeatureFlags;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -77,9 +78,10 @@
             KeyguardSecurityCallback keyguardSecurityCallback,
             KeyguardMessageAreaController.Factory messageAreaControllerFactory,
             LatencyTracker latencyTracker, FalsingCollector falsingCollector,
-            EmergencyButtonController emergencyButtonController) {
+            EmergencyButtonController emergencyButtonController,
+            FeatureFlags featureFlags) {
         super(view, securityMode, keyguardSecurityCallback, emergencyButtonController,
-                messageAreaControllerFactory);
+                messageAreaControllerFactory, featureFlags);
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mLockPatternUtils = lockPatternUtils;
         mLatencyTracker = latencyTracker;
@@ -179,10 +181,10 @@
                     handleAttemptLockout(deadline);
                 }
             }
+            mView.resetPasswordText(true /* animate */, false /* announce deletion if no match */);
             if (timeoutMs == 0) {
                 mMessageAreaController.setMessage(mView.getWrongPasswordStringId());
             }
-            mView.resetPasswordText(true /* animate */, false /* announce deletion if no match */);
             startErrorAnimation();
         }
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockFrame.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardClockFrame.kt
new file mode 100644
index 0000000..635f0fa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockFrame.kt
@@ -0,0 +1,52 @@
+package com.android.keyguard
+
+import android.content.Context
+import android.graphics.Canvas
+import android.util.AttributeSet
+import android.view.View
+import android.widget.FrameLayout
+
+class KeyguardClockFrame(
+    context: Context,
+    attrs: AttributeSet,
+) : FrameLayout(context, attrs) {
+    private var drawAlpha: Int = 255
+
+    protected override fun onSetAlpha(alpha: Int): Boolean {
+        drawAlpha = alpha
+        return true
+    }
+
+    protected override fun dispatchDraw(canvas: Canvas) {
+        saveCanvasAlpha(this, canvas, drawAlpha) { super.dispatchDraw(it) }
+    }
+
+    companion object {
+        @JvmStatic
+        fun saveCanvasAlpha(view: View, canvas: Canvas, alpha: Int, drawFunc: (Canvas) -> Unit) {
+            if (alpha <= 0) {
+                // Zero Alpha -> skip drawing phase
+                return
+            }
+
+            if (alpha >= 255) {
+                // Max alpha -> no need for layer
+                drawFunc(canvas)
+                return
+            }
+
+            // Find x & y of view on screen
+            var (x, y) =
+                run {
+                    val locationOnScreen = IntArray(2)
+                    view.getLocationOnScreen(locationOnScreen)
+                    Pair(locationOnScreen[0].toFloat(), locationOnScreen[1].toFloat())
+                }
+
+            val restoreTo =
+                canvas.saveLayerAlpha(-1f * x, -1f * y, x + view.width, y + view.height, alpha)
+            drawFunc(canvas)
+            canvas.restoreToCount(restoreTo)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 644a9bc..d9d64ad 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -1,15 +1,18 @@
 package com.android.keyguard;
 
+import static android.view.View.ALPHA;
+import static android.view.View.TRANSLATION_Y;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
+import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.FrameLayout;
 import android.widget.RelativeLayout;
 
 import androidx.annotation.IntDef;
@@ -35,11 +38,12 @@
 
     private static final String TAG = "KeyguardClockSwitch";
 
-    private static final long CLOCK_OUT_MILLIS = 150;
-    private static final long CLOCK_IN_MILLIS = 200;
-    public static final long CLOCK_IN_START_DELAY_MILLIS = CLOCK_OUT_MILLIS / 2;
-    private static final long STATUS_AREA_START_DELAY_MILLIS = 50;
-    private static final long STATUS_AREA_MOVE_MILLIS = 350;
+    private static final long CLOCK_OUT_MILLIS = 133;
+    private static final long CLOCK_IN_MILLIS = 167;
+    public static final long CLOCK_IN_START_DELAY_MILLIS = 133;
+    private static final long STATUS_AREA_START_DELAY_MILLIS = 0;
+    private static final long STATUS_AREA_MOVE_UP_MILLIS = 967;
+    private static final long STATUS_AREA_MOVE_DOWN_MILLIS = 467;
 
     @IntDef({LARGE, SMALL})
     @Retention(RetentionPolicy.SOURCE)
@@ -66,15 +70,27 @@
                 top + targetHeight);
     }
 
+    /** Returns a region for the small clock to position itself, based on the given parent. */
+    public static Rect getSmallClockRegion(ViewGroup parent) {
+        int targetHeight = parent.getResources()
+                .getDimensionPixelSize(R.dimen.small_clock_text_size);
+        return new Rect(
+                parent.getLeft(),
+                parent.getTop(),
+                parent.getRight(),
+                parent.getTop() + targetHeight);
+    }
+
     /**
      * Frame for small/large clocks
      */
-    private FrameLayout mSmallClockFrame;
-    private FrameLayout mLargeClockFrame;
+    private KeyguardClockFrame mSmallClockFrame;
+    private KeyguardClockFrame mLargeClockFrame;
     private ClockController mClock;
 
     private View mStatusArea;
     private int mSmartspaceTopOffset;
+    private int mDrawAlpha = 255;
 
     /**
      * Maintain state so that a newly connected plugin can be initialized.
@@ -89,7 +105,7 @@
 
     @VisibleForTesting AnimatorSet mClockInAnim = null;
     @VisibleForTesting AnimatorSet mClockOutAnim = null;
-    private ObjectAnimator mStatusAreaAnim = null;
+    private AnimatorSet mStatusAreaAnim = null;
 
     private int mClockSwitchYAmount;
     @VisibleForTesting boolean mChildrenAreLaidOut = false;
@@ -121,6 +137,22 @@
         onDensityOrFontScaleChanged();
     }
 
+    @Override
+    protected boolean onSetAlpha(int alpha) {
+        mDrawAlpha = alpha;
+        return true;
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        KeyguardClockFrame.saveCanvasAlpha(
+                this, canvas, mDrawAlpha,
+                c -> {
+                    super.dispatchDraw(c);
+                    return kotlin.Unit.INSTANCE;
+                });
+    }
+
     public void setLogBuffer(LogBuffer logBuffer) {
         mLogBuffer = logBuffer;
     }
@@ -155,13 +187,8 @@
     void updateClockTargetRegions() {
         if (mClock != null) {
             if (mSmallClockFrame.isLaidOut()) {
-                int targetHeight =  getResources()
-                        .getDimensionPixelSize(R.dimen.small_clock_text_size);
-                mClock.getSmallClock().getEvents().onTargetRegionChanged(new Rect(
-                        mSmallClockFrame.getLeft(),
-                        mSmallClockFrame.getTop(),
-                        mSmallClockFrame.getRight(),
-                        mSmallClockFrame.getTop() + targetHeight));
+                Rect targetRegion = getSmallClockRegion(mSmallClockFrame);
+                mClock.getSmallClock().getEvents().onTargetRegionChanged(targetRegion);
             }
 
             if (mLargeClockFrame.isLaidOut()) {
@@ -203,39 +230,44 @@
         mStatusAreaAnim = null;
 
         View in, out;
-        int direction = 1;
-        float statusAreaYTranslation;
+        float statusAreaYTranslation, clockInYTranslation, clockOutYTranslation;
         if (useLargeClock) {
             out = mSmallClockFrame;
             in = mLargeClockFrame;
             if (indexOfChild(in) == -1) addView(in, 0);
-            direction = -1;
             statusAreaYTranslation = mSmallClockFrame.getTop() - mStatusArea.getTop()
                     + mSmartspaceTopOffset;
+            clockInYTranslation = 0;
+            clockOutYTranslation = 0; // Small clock translation is handled with statusArea
         } else {
             in = mSmallClockFrame;
             out = mLargeClockFrame;
             statusAreaYTranslation = 0f;
+            clockInYTranslation = 0f;
+            clockOutYTranslation = mClockSwitchYAmount * -1f;
 
-            // Must remove in order for notifications to appear in the proper place
+            // Must remove in order for notifications to appear in the proper place, ideally this
+            // would happen after the out animation runs, but we can't guarantee that the
+            // nofications won't enter only after the out animation runs.
             removeView(out);
         }
 
         if (!animate) {
             out.setAlpha(0f);
+            out.setTranslationY(clockOutYTranslation);
             in.setAlpha(1f);
-            in.setVisibility(VISIBLE);
+            in.setTranslationY(clockInYTranslation);
+            in.setVisibility(View.VISIBLE);
             mStatusArea.setTranslationY(statusAreaYTranslation);
             return;
         }
 
         mClockOutAnim = new AnimatorSet();
         mClockOutAnim.setDuration(CLOCK_OUT_MILLIS);
-        mClockOutAnim.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
+        mClockOutAnim.setInterpolator(Interpolators.LINEAR);
         mClockOutAnim.playTogether(
-                ObjectAnimator.ofFloat(out, View.ALPHA, 0f),
-                ObjectAnimator.ofFloat(out, View.TRANSLATION_Y, 0,
-                        direction * -mClockSwitchYAmount));
+                ObjectAnimator.ofFloat(out, ALPHA, 0f),
+                ObjectAnimator.ofFloat(out, TRANSLATION_Y, clockOutYTranslation));
         mClockOutAnim.addListener(new AnimatorListenerAdapter() {
             public void onAnimationEnd(Animator animation) {
                 mClockOutAnim = null;
@@ -247,8 +279,9 @@
         mClockInAnim = new AnimatorSet();
         mClockInAnim.setDuration(CLOCK_IN_MILLIS);
         mClockInAnim.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
-        mClockInAnim.playTogether(ObjectAnimator.ofFloat(in, View.ALPHA, 1f),
-                ObjectAnimator.ofFloat(in, View.TRANSLATION_Y, direction * mClockSwitchYAmount, 0));
+        mClockInAnim.playTogether(
+                ObjectAnimator.ofFloat(in, ALPHA, 1f),
+                ObjectAnimator.ofFloat(in, TRANSLATION_Y, clockInYTranslation));
         mClockInAnim.setStartDelay(CLOCK_IN_START_DELAY_MILLIS);
         mClockInAnim.addListener(new AnimatorListenerAdapter() {
             public void onAnimationEnd(Animator animation) {
@@ -256,19 +289,22 @@
             }
         });
 
-        mClockInAnim.start();
-        mClockOutAnim.start();
-
-        mStatusAreaAnim = ObjectAnimator.ofFloat(mStatusArea, View.TRANSLATION_Y,
-                statusAreaYTranslation);
-        mStatusAreaAnim.setStartDelay(useLargeClock ? STATUS_AREA_START_DELAY_MILLIS : 0L);
-        mStatusAreaAnim.setDuration(STATUS_AREA_MOVE_MILLIS);
-        mStatusAreaAnim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+        mStatusAreaAnim = new AnimatorSet();
+        mStatusAreaAnim.setStartDelay(STATUS_AREA_START_DELAY_MILLIS);
+        mStatusAreaAnim.setDuration(
+                useLargeClock ? STATUS_AREA_MOVE_UP_MILLIS : STATUS_AREA_MOVE_DOWN_MILLIS);
+        mStatusAreaAnim.setInterpolator(Interpolators.EMPHASIZED);
+        mStatusAreaAnim.playTogether(
+                ObjectAnimator.ofFloat(mStatusArea, TRANSLATION_Y, statusAreaYTranslation),
+                ObjectAnimator.ofFloat(mSmallClockFrame, TRANSLATION_Y, statusAreaYTranslation));
         mStatusAreaAnim.addListener(new AnimatorListenerAdapter() {
             public void onAnimationEnd(Animator animation) {
                 mStatusAreaAnim = null;
             }
         });
+
+        mClockInAnim.start();
+        mClockOutAnim.start();
         mStatusAreaAnim.start();
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 676f342..99e2574 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -86,6 +86,7 @@
 
     private int mKeyguardSmallClockTopMargin = 0;
     private int mKeyguardLargeClockTopMargin = 0;
+    private int mKeyguardDateWeatherViewInvisibility = View.INVISIBLE;
     private final ClockRegistry.ClockChangeListener mClockChangedListener;
 
     private ViewGroup mStatusArea;
@@ -179,20 +180,6 @@
     }
 
     /**
-     * Set alpha directly to mView will clip clock, so we set alpha to clock face instead
-     */
-    public void setAlpha(float alpha) {
-        ClockController clock = getClock();
-        if (clock != null) {
-            clock.getLargeClock().getView().setAlpha(alpha);
-            clock.getSmallClock().getView().setAlpha(alpha);
-        }
-        if (mStatusArea != null) {
-            mStatusArea.setAlpha(alpha);
-        }
-    }
-
-    /**
      * Attach the controller to the view it relates to.
      */
     @Override
@@ -215,6 +202,8 @@
                 mView.getResources().getDimensionPixelSize(R.dimen.keyguard_clock_top_margin);
         mKeyguardLargeClockTopMargin =
                 mView.getResources().getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin);
+        mKeyguardDateWeatherViewInvisibility =
+                mView.getResources().getInteger(R.integer.keyguard_date_weather_view_invisibility);
 
         if (mOnlyClock) {
             View ksv = mView.findViewById(R.id.keyguard_slice_view);
@@ -349,7 +338,10 @@
                 mView.getResources().getDimensionPixelSize(R.dimen.keyguard_clock_top_margin);
         mKeyguardLargeClockTopMargin =
                 mView.getResources().getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin);
+        mKeyguardDateWeatherViewInvisibility =
+                mView.getResources().getInteger(R.integer.keyguard_date_weather_view_invisibility);
         mView.updateClockTargetRegions();
+        setDateWeatherVisibility();
     }
 
 
@@ -511,8 +503,9 @@
     private void setDateWeatherVisibility() {
         if (mDateWeatherView != null) {
             mUiExecutor.execute(() -> {
-                mDateWeatherView.setVisibility(
-                        clockHasCustomWeatherDataDisplay() ? View.INVISIBLE : View.VISIBLE);
+                mDateWeatherView.setVisibility(clockHasCustomWeatherDataDisplay()
+                        ? mKeyguardDateWeatherViewInvisibility
+                        : View.VISIBLE);
             });
         }
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index ec8fa92..9f21a31 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -19,27 +19,34 @@
 import android.content.Context;
 import android.graphics.Color;
 import android.graphics.Rect;
+import android.hardware.devicestate.DeviceStateManager;
 import android.hardware.display.DisplayManager;
 import android.media.MediaRouter;
 import android.media.MediaRouter.RouteInfo;
 import android.os.Bundle;
 import android.os.Trace;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.Display;
+import android.view.DisplayAddress;
 import android.view.DisplayInfo;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.keyguard.dagger.KeyguardStatusViewComponent;
 import com.android.systemui.R;
+import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.navigationbar.NavigationBarController;
 import com.android.systemui.navigationbar.NavigationBarView;
 import com.android.systemui.settings.DisplayTracker;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import java.util.concurrent.Executor;
 
@@ -47,6 +54,7 @@
 
 import dagger.Lazy;
 
+@SysUISingleton
 public class KeyguardDisplayManager {
     protected static final String TAG = "KeyguardDisplayManager";
     private static final boolean DEBUG = KeyguardConstants.DEBUG;
@@ -61,6 +69,9 @@
     private boolean mShowing;
     private final DisplayInfo mTmpDisplayInfo = new DisplayInfo();
 
+    private final DeviceStateHelper mDeviceStateHelper;
+    private final KeyguardStateController mKeyguardStateController;
+
     private final SparseArray<Presentation> mPresentations = new SparseArray<>();
 
     private final DisplayTracker.Callback mDisplayCallback =
@@ -92,7 +103,9 @@
             KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory,
             DisplayTracker displayTracker,
             @Main Executor mainExecutor,
-            @UiBackground Executor uiBgExecutor) {
+            @UiBackground Executor uiBgExecutor,
+            DeviceStateHelper deviceStateHelper,
+            KeyguardStateController keyguardStateController) {
         mContext = context;
         mNavigationBarControllerLazy = navigationBarControllerLazy;
         mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
@@ -100,6 +113,8 @@
         mDisplayService = mContext.getSystemService(DisplayManager.class);
         mDisplayTracker = displayTracker;
         mDisplayTracker.addDisplayChangeCallback(mDisplayCallback, mainExecutor);
+        mDeviceStateHelper = deviceStateHelper;
+        mKeyguardStateController = keyguardStateController;
     }
 
     private boolean isKeyguardShowable(Display display) {
@@ -122,6 +137,18 @@
             }
             return false;
         }
+        if (mKeyguardStateController.isOccluded()
+                && mDeviceStateHelper.isConcurrentDisplayActive(display)) {
+            if (DEBUG) {
+                // When activities with FLAG_SHOW_WHEN_LOCKED are shown on top of Keyguard, the
+                // Keyguard state becomes "occluded". In this case, we should not show the
+                // KeyguardPresentation, since the activity is presenting content onto the
+                // non-default display.
+                Log.i(TAG, "Do not show KeyguardPresentation when occluded and concurrent"
+                        + " display is active");
+            }
+            return false;
+        }
 
         return true;
     }
@@ -260,6 +287,53 @@
 
     }
 
+    /**
+     * Helper used to receive device state info from {@link DeviceStateManager}.
+     */
+    static class DeviceStateHelper implements DeviceStateManager.DeviceStateCallback {
+
+        @Nullable
+        private final DisplayAddress.Physical mRearDisplayPhysicalAddress;
+
+        // TODO(b/271317597): These device states should be defined in DeviceStateManager
+        private final int mConcurrentState;
+        private boolean mIsInConcurrentDisplayState;
+
+        @Inject
+        DeviceStateHelper(Context context,
+                DeviceStateManager deviceStateManager,
+                @Main Executor mainExecutor) {
+
+            final String rearDisplayPhysicalAddress = context.getResources().getString(
+                    com.android.internal.R.string.config_rearDisplayPhysicalAddress);
+            if (TextUtils.isEmpty(rearDisplayPhysicalAddress)) {
+                mRearDisplayPhysicalAddress = null;
+            } else {
+                mRearDisplayPhysicalAddress = DisplayAddress
+                        .fromPhysicalDisplayId(Long.parseLong(rearDisplayPhysicalAddress));
+            }
+
+            mConcurrentState = context.getResources().getInteger(
+                    com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay);
+            deviceStateManager.registerCallback(mainExecutor, this);
+        }
+
+        @Override
+        public void onStateChanged(int state) {
+            // When concurrent state ends, the display also turns off. This is enforced in various
+            // ExtensionRearDisplayPresentationTest CTS tests. So, we don't need to invoke
+            // hide() since that will happen through the onDisplayRemoved callback.
+            mIsInConcurrentDisplayState = state == mConcurrentState;
+        }
+
+        boolean isConcurrentDisplayActive(Display display) {
+            return mIsInConcurrentDisplayState
+                    && mRearDisplayPhysicalAddress != null
+                    && mRearDisplayPhysicalAddress.equals(display.getAddress());
+        }
+    }
+
+
     @VisibleForTesting
     static final class KeyguardPresentation extends Presentation {
         private static final int VIDEO_SAFE_REGION = 80; // Percentage of display width & height
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java
index 7eae729..c9d9069 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputView.java
@@ -21,11 +21,14 @@
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
+import android.view.View;
 import android.widget.LinearLayout;
 
+import androidx.annotation.CallSuper;
 import androidx.annotation.Nullable;
 
 import com.android.internal.jank.InteractionJankMonitor;
+import com.android.systemui.R;
 
 /**
  * A Base class for all Keyguard password/pattern/pin related inputs.
@@ -33,6 +36,9 @@
 public abstract class KeyguardInputView extends LinearLayout {
     private Runnable mOnFinishImeAnimationRunnable;
 
+    @Nullable
+    private View mBouncerMessageView;
+
     public KeyguardInputView(Context context) {
         super(context);
     }
@@ -87,6 +93,18 @@
         mOnFinishImeAnimationRunnable = onFinishImeAnimationRunnable;
     }
 
+    @Override
+    @CallSuper
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mBouncerMessageView = findViewById(R.id.bouncer_message_view);
+    }
+
+    @Nullable
+    public final View getBouncerMessageView() {
+        return mBouncerMessageView;
+    }
+
     public void runOnFinishImeAnimationRunnable() {
         if (mOnFinishImeAnimationRunnable != null) {
             mOnFinishImeAnimationRunnable.run();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
index a0f5f34..3c05299 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
@@ -16,6 +16,7 @@
 
 package com.android.keyguard;
 
+import android.annotation.CallSuper;
 import android.annotation.Nullable;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -31,6 +32,7 @@
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.statusbar.policy.DevicePostureController;
 import com.android.systemui.util.ViewController;
 import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -53,16 +55,19 @@
     // (e.g. face unlock). This avoids unwanted asynchronous events from messing with the
     // state for the current security method.
     private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {};
+    private final FeatureFlags mFeatureFlags;
 
     protected KeyguardInputViewController(T view, SecurityMode securityMode,
             KeyguardSecurityCallback keyguardSecurityCallback,
             EmergencyButtonController emergencyButtonController,
-            @Nullable KeyguardMessageAreaController.Factory messageAreaControllerFactory) {
+            @Nullable KeyguardMessageAreaController.Factory messageAreaControllerFactory,
+            FeatureFlags featureFlags) {
         super(view);
         mSecurityMode = securityMode;
         mKeyguardSecurityCallback = keyguardSecurityCallback;
         mEmergencyButton = view == null ? null : view.findViewById(R.id.emergency_call_button);
         mEmergencyButtonController = emergencyButtonController;
+        mFeatureFlags = featureFlags;
         if (messageAreaControllerFactory != null) {
             try {
                 BouncerKeyguardMessageArea kma = view.requireViewById(R.id.bouncer_message_area);
@@ -82,9 +87,21 @@
     }
 
     @Override
+    @CallSuper
     protected void onViewAttached() {
+        updateMessageAreaVisibility();
     }
 
+    private void updateMessageAreaVisibility() {
+        if (mMessageAreaController == null) return;
+        if (mFeatureFlags.isEnabled(Flags.REVAMPED_BOUNCER_MESSAGES)) {
+            mMessageAreaController.disable();
+        } else {
+            mMessageAreaController.setIsVisible(true);
+        }
+    }
+
+
     @Override
     protected void onViewDetached() {
     }
@@ -208,14 +225,14 @@
                         mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
                         keyguardSecurityCallback, mLatencyTracker, mFalsingCollector,
                         emergencyButtonController, mMessageAreaControllerFactory,
-                        mDevicePostureController);
+                        mDevicePostureController, mFeatureFlags);
             } else if (keyguardInputView instanceof KeyguardPasswordView) {
                 return new KeyguardPasswordViewController((KeyguardPasswordView) keyguardInputView,
                         mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
                         keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
                         mInputMethodManager, emergencyButtonController, mMainExecutor, mResources,
-                        mFalsingCollector, mKeyguardViewController);
-
+                        mFalsingCollector, mKeyguardViewController,
+                        mFeatureFlags);
             } else if (keyguardInputView instanceof KeyguardPINView) {
                 return new KeyguardPinViewController((KeyguardPINView) keyguardInputView,
                         mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
@@ -227,13 +244,13 @@
                         mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
                         keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
                         mLiftToActivateListener, mTelephonyManager, mFalsingCollector,
-                        emergencyButtonController);
+                        emergencyButtonController, mFeatureFlags);
             } else if (keyguardInputView instanceof KeyguardSimPukView) {
                 return new KeyguardSimPukViewController((KeyguardSimPukView) keyguardInputView,
                         mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
                         keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
                         mLiftToActivateListener, mTelephonyManager, mFalsingCollector,
-                        emergencyButtonController);
+                        emergencyButtonController, mFeatureFlags);
             }
 
             throw new RuntimeException("Unable to find controller for " + keyguardInputView);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
index 553453d..fc66527 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
@@ -44,11 +44,18 @@
     private ViewGroup mContainer;
     private int mTopMargin;
     protected boolean mAnimate;
+    private final int mStyleResId;
+    private boolean mIsDisabled = false;
 
     public KeyguardMessageArea(Context context, AttributeSet attrs) {
         super(context, attrs);
         setLayerType(LAYER_TYPE_HARDWARE, null); // work around nested unclipped SaveLayer bug
-
+        if (attrs != null) {
+            mStyleResId = attrs.getStyleAttribute();
+        } else {
+            // Set to default reference style if the component is used without setting "style" attr
+            mStyleResId = R.style.Keyguard_TextView;
+        }
         onThemeChanged();
     }
 
@@ -82,13 +89,17 @@
     }
 
     void onDensityOrFontScaleChanged() {
-        TypedArray array = mContext.obtainStyledAttributes(R.style.Keyguard_TextView, new int[] {
+        TypedArray array = mContext.obtainStyledAttributes(getStyleResId(), new int[] {
                 android.R.attr.textSize
         });
         setTextSize(TypedValue.COMPLEX_UNIT_PX, array.getDimensionPixelSize(0, 0));
         array.recycle();
     }
 
+    protected int getStyleResId() {
+        return mStyleResId;
+    }
+
     @Override
     public void setMessage(CharSequence msg, boolean animate) {
         if (!TextUtils.isEmpty(msg)) {
@@ -118,6 +129,10 @@
     }
 
     void update() {
+        if (mIsDisabled) {
+            setVisibility(GONE);
+            return;
+        }
         CharSequence status = mMessage;
         setVisibility(TextUtils.isEmpty(status) || (!mIsVisible) ? INVISIBLE : VISIBLE);
         setText(status);
@@ -136,4 +151,17 @@
 
     /** Set the text color */
     protected abstract void updateTextColor();
+
+    /**
+     * Mark this view with {@link android.view.View#GONE} visibility to remove this from the layout
+     * of the view. Any calls to {@link #setIsVisible(boolean)} after this will be a no-op.
+     */
+    public void disable() {
+        mIsDisabled = true;
+        update();
+    }
+
+    public boolean isDisabled() {
+        return mIsDisabled;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java
index c1896fc..0332c9f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java
@@ -18,7 +18,9 @@
 
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
+import android.text.Editable;
 import android.text.TextUtils;
+import android.text.TextWatcher;
 import android.view.View;
 
 import androidx.annotation.VisibleForTesting;
@@ -45,6 +47,31 @@
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final ConfigurationController mConfigurationController;
     private final AnnounceRunnable mAnnounceRunnable;
+    private final TextWatcher mTextWatcher = new TextWatcher() {
+        @Override
+        public void afterTextChanged(Editable editable) {
+            CharSequence msg = editable;
+            if (!TextUtils.isEmpty(msg)) {
+                mView.removeCallbacks(mAnnounceRunnable);
+                mAnnounceRunnable.setTextToAnnounce(msg);
+                mView.postDelayed(() -> {
+                    if (msg == mView.getText()) {
+                        mAnnounceRunnable.run();
+                    }
+                }, ANNOUNCEMENT_DELAY);
+            }
+        }
+
+        @Override
+        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+            /* no-op */
+        }
+
+        @Override
+        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+            /* no-op */
+        }
+    };
 
     private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
         public void onFinishedGoingToSleep(int why) {
@@ -89,12 +116,14 @@
         mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
         mView.setSelected(mKeyguardUpdateMonitor.isDeviceInteractive());
         mView.onThemeChanged();
+        mView.addTextChangedListener(mTextWatcher);
     }
 
     @Override
     protected void onViewDetached() {
         mConfigurationController.removeCallback(mConfigurationListener);
         mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
+        mView.removeTextChangedListener(mTextWatcher);
     }
 
     /**
@@ -104,6 +133,14 @@
         mView.setIsVisible(isVisible);
     }
 
+    /**
+     * Mark this view with {@link View#GONE} visibility to remove this from the layout of the view.
+     * Any calls to {@link #setIsVisible(boolean)} after this will be a no-op.
+     */
+    public void disable() {
+        mView.disable();
+    }
+
     public void setMessage(CharSequence s) {
         setMessage(s, true);
     }
@@ -112,13 +149,10 @@
      * Sets a message to the underlying text view.
      */
     public void setMessage(CharSequence s, boolean animate) {
-        mView.setMessage(s, animate);
-        CharSequence msg = mView.getText();
-        if (!TextUtils.isEmpty(msg)) {
-            mView.removeCallbacks(mAnnounceRunnable);
-            mAnnounceRunnable.setTextToAnnounce(msg);
-            mView.postDelayed(mAnnounceRunnable, ANNOUNCEMENT_DELAY);
+        if (mView.isDisabled()) {
+            return;
         }
+        mView.setMessage(s, animate);
     }
 
     public void setMessage(int resId) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
index 58807e4..2377057 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -51,7 +51,7 @@
     private View[][] mViews;
     private int mYTrans;
     private int mYTransOffset;
-    private View mBouncerMessageView;
+    private View mBouncerMessageArea;
     @DevicePostureInt private int mLastDevicePosture = DEVICE_POSTURE_UNKNOWN;
     public static final long ANIMATION_DURATION = 650;
 
@@ -145,7 +145,7 @@
         super.onFinishInflate();
 
         mContainer = findViewById(R.id.pin_container);
-        mBouncerMessageView = findViewById(R.id.bouncer_message_area);
+        mBouncerMessageArea = findViewById(R.id.bouncer_message_area);
         mViews = new View[][]{
                 new View[]{
                         findViewById(R.id.row0), null, null
@@ -221,9 +221,9 @@
         Interpolator legacyDecelerate = Interpolators.LEGACY_DECELERATE;
         float standardProgress = standardDecelerate.getInterpolation(progress);
 
-        mBouncerMessageView.setTranslationY(
+        mBouncerMessageArea.setTranslationY(
                 mYTrans - mYTrans * standardProgress);
-        mBouncerMessageView.setAlpha(standardProgress);
+        mBouncerMessageArea.setAlpha(standardProgress);
 
         for (int i = 0; i < mViews.length; i++) {
             View[] row = mViews[i];
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
index d221e22..1f6b09b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
@@ -40,6 +40,7 @@
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 
 import java.util.List;
@@ -104,10 +105,11 @@
             @Main DelayableExecutor mainExecutor,
             @Main Resources resources,
             FalsingCollector falsingCollector,
-            KeyguardViewController keyguardViewController) {
+            KeyguardViewController keyguardViewController,
+            FeatureFlags featureFlags) {
         super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
                 messageAreaControllerFactory, latencyTracker, falsingCollector,
-                emergencyButtonController);
+                emergencyButtonController, featureFlags);
         mKeyguardSecurityCallback = keyguardSecurityCallback;
         mInputMethodManager = inputMethodManager;
         mMainExecutor = mainExecutor;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index afc2590..99b5d52 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -158,15 +158,18 @@
 
     public void startAppearAnimation() {
         enableClipping(false);
-        setAlpha(1f);
+        setAlpha(0f);
         setTranslationY(mAppearAnimationUtils.getStartTranslation());
         AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 500 /* duration */,
                 0, mAppearAnimationUtils.getInterpolator(),
                 getAnimationListener(InteractionJankMonitor.CUJ_LOCKSCREEN_PATTERN_APPEAR));
-        mAppearAnimationUtils.startAnimation2d(
-                mLockPatternView.getCellStates(),
-                () -> enableClipping(true),
-                this);
+        mLockPatternView.post(() -> {
+            setAlpha(1f);
+            mAppearAnimationUtils.startAnimation2d(
+                    mLockPatternView.getCellStates(),
+                    () -> enableClipping(true),
+                    KeyguardPatternView.this);
+        });
         if (!TextUtils.isEmpty(mSecurityMessageDisplay.getText())) {
             mAppearAnimationUtils.createAnimation(mSecurityMessageDisplay, 0,
                     AppearAnimationUtils.DEFAULT_APPEAR_DURATION,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index 39225fb..64b1c50 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -38,6 +38,7 @@
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingClassifier;
 import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.statusbar.policy.DevicePostureController;
 
 import java.util.HashMap;
@@ -196,9 +197,9 @@
             FalsingCollector falsingCollector,
             EmergencyButtonController emergencyButtonController,
             KeyguardMessageAreaController.Factory messageAreaControllerFactory,
-            DevicePostureController postureController) {
+            DevicePostureController postureController, FeatureFlags featureFlags) {
         super(view, securityMode, keyguardSecurityCallback, emergencyButtonController,
-                messageAreaControllerFactory);
+                messageAreaControllerFactory, featureFlags);
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mLockPatternUtils = lockPatternUtils;
         mLatencyTracker = latencyTracker;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
index b4ddc9a..5cb2c5c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -34,6 +34,8 @@
 import android.view.KeyEvent;
 import android.view.View;
 
+import androidx.annotation.CallSuper;
+
 import com.android.app.animation.Interpolators;
 import com.android.internal.widget.LockscreenCredential;
 import com.android.systemui.R;
@@ -82,9 +84,6 @@
     protected void setPasswordEntryInputEnabled(boolean enabled) {
         mPasswordEntry.setEnabled(enabled);
         mOkButton.setEnabled(enabled);
-        if (enabled && !mPasswordEntry.hasFocus()) {
-            mPasswordEntry.requestFocus();
-        }
     }
 
     @Override
@@ -150,7 +149,9 @@
     }
 
     @Override
+    @CallSuper
     protected void onFinishInflate() {
+        super.onFinishInflate();
         mPasswordEntry = findViewById(getPasswordTextViewId());
 
         // Set selected property on so the view can send accessibility events.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
index ded1238..31cbdde 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
@@ -27,6 +27,7 @@
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.flags.FeatureFlags;
 
 public abstract class KeyguardPinBasedInputViewController<T extends KeyguardPinBasedInputView>
         extends KeyguardAbsKeyInputViewController<T> {
@@ -58,10 +59,11 @@
             LatencyTracker latencyTracker,
             LiftToActivateListener liftToActivateListener,
             EmergencyButtonController emergencyButtonController,
-            FalsingCollector falsingCollector) {
+            FalsingCollector falsingCollector,
+            FeatureFlags featureFlags) {
         super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
                 messageAreaControllerFactory, latencyTracker, falsingCollector,
-                emergencyButtonController);
+                emergencyButtonController, featureFlags);
         mLiftToActivateListener = liftToActivateListener;
         mFalsingCollector = falsingCollector;
         mPasswordEntry = mView.findViewById(mView.getPasswordTextViewId());
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinFlowView.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardPinFlowView.kt
new file mode 100644
index 0000000..5c66b82
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinFlowView.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard
+
+import android.content.Context
+import android.util.AttributeSet
+import androidx.constraintlayout.helper.widget.Flow
+import androidx.constraintlayout.widget.ConstraintLayout
+
+class KeyguardPinFlowView(context: Context, attrs: AttributeSet?) : Flow(context, attrs) {
+    // Overriding this so that visibilities of child views do not get updated.
+    override fun applyLayoutFeatures(container: ConstraintLayout?) {}
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
index f23bb0a..3e16d55 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
@@ -16,8 +16,6 @@
 
 package com.android.keyguard;
 
-import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.DEFAULT_PIN_LENGTH;
-
 import android.view.View;
 
 import com.android.internal.util.LatencyTracker;
@@ -42,10 +40,9 @@
     private NumPadButton mBackspaceKey;
     private View mOkButton = mView.findViewById(R.id.key_enter);
 
-    private int mUserId;
     private long mPinLength;
 
-    private int mPasswordFailedAttempts;
+    private boolean mDisabledAutoConfirmation;
 
     protected KeyguardPinViewController(KeyguardPINView view,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
@@ -59,12 +56,13 @@
             FeatureFlags featureFlags) {
         super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
                 messageAreaControllerFactory, latencyTracker, liftToActivateListener,
-                emergencyButtonController, falsingCollector);
+                emergencyButtonController, falsingCollector, featureFlags);
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mPostureController = postureController;
         mLockPatternUtils = lockPatternUtils;
         mFeatureFlags = featureFlags;
         mBackspaceKey = view.findViewById(R.id.delete_button);
+        mPinLength = mLockPatternUtils.getPinLength(KeyguardUpdateMonitor.getCurrentUser());
     }
 
     @Override
@@ -84,9 +82,8 @@
 
     protected void onUserInput() {
         super.onUserInput();
-        if (isAutoConfirmation()) {
-            updateOKButtonVisibility();
-            updateBackSpaceVisibility();
+        if (isAutoPinConfirmEnabledInSettings()) {
+            updateAutoConfirmationState();
             if (mPasswordEntry.getText().length() == mPinLength
                     && mOkButton.getVisibility() == View.INVISIBLE) {
                 verifyPasswordAndUnlock();
@@ -103,13 +100,8 @@
     @Override
     public void startAppearAnimation() {
         if (mFeatureFlags.isEnabled(Flags.AUTO_PIN_CONFIRMATION)) {
-            mUserId = KeyguardUpdateMonitor.getCurrentUser();
-            mPinLength = mLockPatternUtils.getPinLength(mUserId);
-            mBackspaceKey.setTransparentMode(/* isTransparentMode= */ isAutoConfirmation());
-            updateOKButtonVisibility();
-            updateBackSpaceVisibility();
             mPasswordEntry.setUsePinShapes(true);
-            mPasswordEntry.setIsPinHinting(isAutoConfirmation() && isPinHinting());
+            updateAutoConfirmationState();
         }
         super.startAppearAnimation();
     }
@@ -120,13 +112,25 @@
                 mKeyguardUpdateMonitor.needsSlowUnlockTransition(), finishRunnable);
     }
 
+    @Override
+    protected void handleAttemptLockout(long elapsedRealtimeDeadline) {
+        super.handleAttemptLockout(elapsedRealtimeDeadline);
+        updateAutoConfirmationState();
+    }
+
+    private void updateAutoConfirmationState() {
+        mDisabledAutoConfirmation = mLockPatternUtils.getCurrentFailedPasswordAttempts(
+                KeyguardUpdateMonitor.getCurrentUser()) >= MIN_FAILED_PIN_ATTEMPTS;
+        updateOKButtonVisibility();
+        updateBackSpaceVisibility();
+        updatePinHinting();
+    }
 
     /**
      * Updates the visibility of the OK button for auto confirm feature
      */
     private void updateOKButtonVisibility() {
-        mPasswordFailedAttempts = mLockPatternUtils.getCurrentFailedPasswordAttempts(mUserId);
-        if (isAutoConfirmation() && mPasswordFailedAttempts < MIN_FAILED_PIN_ATTEMPTS) {
+        if (isAutoPinConfirmEnabledInSettings() && !mDisabledAutoConfirmation) {
             mOkButton.setVisibility(View.INVISIBLE);
         } else {
             mOkButton.setVisibility(View.VISIBLE);
@@ -134,33 +138,41 @@
     }
 
     /**
-     *  Updates the visibility and the enabled state of the backspace.
+     * Updates the visibility and the enabled state of the backspace.
      * Visibility changes are only for auto confirmation configuration.
      */
     private void updateBackSpaceVisibility() {
-        if (!isAutoConfirmation()) {
-            return;
+        boolean isAutoConfirmation = isAutoPinConfirmEnabledInSettings();
+        mBackspaceKey.setTransparentMode(/* isTransparentMode= */
+                isAutoConfirmation && !mDisabledAutoConfirmation);
+        if (isAutoConfirmation) {
+            if (mPasswordEntry.getText().length() > 0
+                    || mDisabledAutoConfirmation) {
+                mBackspaceKey.setVisibility(View.VISIBLE);
+            } else {
+                mBackspaceKey.setVisibility(View.INVISIBLE);
+            }
         }
-
-        if (mPasswordEntry.getText().length() > 0) {
-            mBackspaceKey.setVisibility(View.VISIBLE);
-        } else {
-            mBackspaceKey.setVisibility(View.INVISIBLE);
-        }
+    }
+    /** Updates whether to use pin hinting or not. */
+    void updatePinHinting() {
+        mPasswordEntry.setIsPinHinting(isAutoPinConfirmEnabledInSettings() && isPinHinting()
+                && !mDisabledAutoConfirmation);
     }
 
     /**
-     *   Responsible for identifying if PIN hinting is to be enabled or not
+     * Responsible for identifying if PIN hinting is to be enabled or not
      */
     private boolean isPinHinting() {
-        return mLockPatternUtils.getPinLength(mUserId) == DEFAULT_PIN_LENGTH;
+        return mLockPatternUtils.getPinLength(KeyguardUpdateMonitor.getCurrentUser())
+                == DEFAULT_PIN_LENGTH;
     }
 
     /**
-     *   Responsible for identifying if auto confirm is enabled or not in Settings
+     * Responsible for identifying if auto confirm is enabled or not in Settings
      */
-    private boolean isAutoConfirmation() {
+    private boolean isAutoPinConfirmEnabledInSettings() {
         //Checks if user has enabled the auto confirm in Settings
-        return mLockPatternUtils.isAutoPinConfirmEnabled(mUserId);
+        return mLockPatternUtils.isAutoPinConfirmEnabled(KeyguardUpdateMonitor.getCurrentUser());
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 5cc0547..4b02171 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -599,7 +599,6 @@
      */
     public void startAppearAnimation(SecurityMode securityMode) {
         setTranslationY(0f);
-        setAlpha(1f);
         updateChildren(0 /* translationY */, 1f /* alpha */);
         mViewMode.startAppearAnimation(securityMode);
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 5b1edc7..b5e5420 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -674,7 +674,6 @@
 
     public void startAppearAnimation() {
         if (mCurrentSecurityMode != SecurityMode.None) {
-            setAlpha(1f);
             mView.startAppearAnimation(mCurrentSecurityMode);
             getCurrentSecurityController(controller -> controller.startAppearAnimation());
         }
@@ -1112,7 +1111,7 @@
      */
     public void setExpansion(float fraction) {
         float scaledFraction = BouncerPanelExpansionCalculator.showBouncerProgress(fraction);
-        mView.setAlpha(MathUtils.constrain(1 - scaledFraction, 0f, 1f));
+        setAlpha(MathUtils.constrain(1 - scaledFraction, 0f, 1f));
         mView.setTranslationY(scaledFraction * mTranslationY);
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
index 3fc39af..1461dbe 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
@@ -30,6 +30,7 @@
     private var disableESimButton: KeyguardEsimArea? = null
 
     override fun onFinishInflate() {
+        super.onFinishInflate()
         simImageView = findViewById(R.id.keyguard_sim)
         disableESimButton = findViewById(R.id.keyguard_esim_area)
         super.onFinishInflate()
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
index a16f3047..61280af 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
@@ -41,6 +41,7 @@
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.flags.FeatureFlags;
 
 public class KeyguardSimPinViewController
         extends KeyguardPinBasedInputViewController<KeyguardSimPinView> {
@@ -81,10 +82,10 @@
             KeyguardMessageAreaController.Factory messageAreaControllerFactory,
             LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
             TelephonyManager telephonyManager, FalsingCollector falsingCollector,
-            EmergencyButtonController emergencyButtonController) {
+            EmergencyButtonController emergencyButtonController, FeatureFlags featureFlags) {
         super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
                 messageAreaControllerFactory, latencyTracker, liftToActivateListener,
-                emergencyButtonController, falsingCollector);
+                emergencyButtonController, falsingCollector, featureFlags);
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mTelephonyManager = telephonyManager;
         mSimImageView = mView.findViewById(R.id.keyguard_sim);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
index e9405eb..49d786f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
@@ -38,6 +38,7 @@
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.flags.FeatureFlags;
 
 public class KeyguardSimPukViewController
         extends KeyguardPinBasedInputViewController<KeyguardSimPukView> {
@@ -85,10 +86,10 @@
             KeyguardMessageAreaController.Factory messageAreaControllerFactory,
             LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
             TelephonyManager telephonyManager, FalsingCollector falsingCollector,
-            EmergencyButtonController emergencyButtonController) {
+            EmergencyButtonController emergencyButtonController, FeatureFlags featureFlags) {
         super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
                 messageAreaControllerFactory, latencyTracker, liftToActivateListener,
-                emergencyButtonController, falsingCollector);
+                emergencyButtonController, falsingCollector, featureFlags);
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mTelephonyManager = telephonyManager;
         mSimImageView = mView.findViewById(R.id.keyguard_sim);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusContainer.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusContainer.kt
new file mode 100644
index 0000000..298eff2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusContainer.kt
@@ -0,0 +1,22 @@
+package com.android.keyguard
+
+import android.content.Context
+import android.graphics.Canvas
+import android.util.AttributeSet
+import android.widget.LinearLayout
+
+class KeyguardStatusContainer(
+    context: Context,
+    attrs: AttributeSet,
+) : LinearLayout(context, attrs) {
+    private var drawAlpha: Int = 255
+
+    protected override fun onSetAlpha(alpha: Int): Boolean {
+        drawAlpha = alpha
+        return true
+    }
+
+    protected override fun dispatchDraw(canvas: Canvas) {
+        KeyguardClockFrame.saveCanvasAlpha(this, canvas, drawAlpha) { super.dispatchDraw(canvas) }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 2313609..a6252a3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -19,6 +19,7 @@
 import static java.util.Collections.emptySet;
 
 import android.content.Context;
+import android.graphics.Canvas;
 import android.os.Build;
 import android.os.Trace;
 import android.util.AttributeSet;
@@ -47,6 +48,7 @@
     private KeyguardSliceView mKeyguardSlice;
     private View mMediaHostContainer;
 
+    private int mDrawAlpha = 255;
     private float mDarkAmount = 0;
 
     public KeyguardStatusView(Context context) {
@@ -136,30 +138,19 @@
         Trace.endSection();
     }
 
-    /**
-     * Clock content will be clipped when goes beyond bounds,
-     * so we setAlpha for all views except clock
-     */
-    public void setAlpha(float alpha, boolean excludeClock) {
-        if (!excludeClock) {
-            setAlpha(alpha);
-            return;
-        }
-        if (alpha == 1 || alpha == 0) {
-            setAlpha(alpha);
-        }
-        for (int i = 0; i < getChildCount(); i++) {
-            View child = getChildAt(i);
-            if (child == mStatusViewContainer) {
-                for (int j = 0; j < mStatusViewContainer.getChildCount(); j++) {
-                    View innerChild = mStatusViewContainer.getChildAt(j);
-                    if (innerChild != mClockView) {
-                        innerChild.setAlpha(alpha);
-                    }
-                }
-            } else {
-                child.setAlpha(alpha);
-            }
-        }
+    @Override
+    protected boolean onSetAlpha(int alpha) {
+        mDrawAlpha = alpha;
+        return true;
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        KeyguardClockFrame.saveCanvasAlpha(
+                this, canvas, mDrawAlpha,
+                c -> {
+                    super.dispatchDraw(c);
+                    return kotlin.Unit.INSTANCE;
+                });
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index af47466..1db0ab6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -180,8 +180,7 @@
      */
     public void setAlpha(float alpha) {
         if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
-            mView.setAlpha(alpha, true);
-            mKeyguardClockSwitchController.setAlpha(alpha);
+            mView.setAlpha(alpha);
         }
     }
 
@@ -316,6 +315,14 @@
     }
 
     /**
+     * Returns true if the large clock will block the notification shelf in AOD
+     */
+    public boolean isLargeClockBlockingNotificationShelf() {
+        ClockController clock = mKeyguardClockSwitchController.getClock();
+        return clock != null && clock.getLargeClock().getConfig().getHasCustomWeatherDataDisplay();
+    }
+
+    /**
      * Updates the alignment of the KeyguardStatusView and animates the transition if requested.
      */
     public void updateAlignment(
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 95e97ff..e8046dc0 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -29,6 +29,7 @@
 import static android.hardware.biometrics.BiometricSourceType.FACE;
 import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
 import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
+import static android.os.BatteryManager.CHARGING_POLICY_DEFAULT;
 import static android.os.PowerManager.WAKE_REASON_UNKNOWN;
 
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
@@ -1235,7 +1236,6 @@
      */
     private void handleFaceAcquired(int acquireInfo) {
         Assert.isMainThread();
-        mLogger.logFaceAcquired(acquireInfo);
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -1288,7 +1288,6 @@
             return;
         }
         Assert.isMainThread();
-        mLogger.logFaceAuthHelpMsg(msgId, helpString);
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -1462,6 +1461,14 @@
                         ErrorAuthenticationStatus error = (ErrorAuthenticationStatus) status;
                         handleFaceError(error.getMsgId(), error.getMsg());
                     } else if (status instanceof FailedAuthenticationStatus) {
+                        if (isFaceLockedOut()) {
+                            // TODO b/270090188: remove this hack when biometrics fixes this issue.
+                            // FailedAuthenticationStatus is emitted after ErrorAuthenticationStatus
+                            // for lockout error is received
+                            mLogger.d("onAuthenticationFailed called after"
+                                    + " face has been locked out");
+                            return;
+                        }
                         handleFaceAuthFailed();
                     } else if (status instanceof HelpAuthenticationStatus) {
                         HelpAuthenticationStatus helpMsg = (HelpAuthenticationStatus) status;
@@ -1970,6 +1977,13 @@
 
                 @Override
                 public void onAuthenticationFailed() {
+                    if (isFaceLockedOut()) {
+                        // TODO b/270090188: remove this hack when biometrics fixes this issue.
+                        // onAuthenticationFailed is called after onAuthenticationError
+                        // for lockout error is received
+                        mLogger.d("onAuthenticationFailed called after face has been locked out");
+                        return;
+                    }
                     handleFaceAuthFailed();
                 }
 
@@ -2444,7 +2458,8 @@
         }
 
         // Take a guess at initial SIM state, battery status and PLMN until we get an update
-        mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0, true);
+        mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, /* level= */ 100, /* plugged= */
+                0, CHARGING_POLICY_DEFAULT, /* maxChargingWattage= */0, /* present= */true);
 
         // Watch for interesting updates
         final IntentFilter filter = new IntentFilter();
@@ -2623,6 +2638,14 @@
     }
 
     /**
+     * @return true if the FP sensor is non-UDFPS and the device can be unlocked using fingerprint
+     * at this moment.
+     */
+    public boolean isFingerprintAllowedInBouncer() {
+        return !isUdfpsSupported() && isUnlockingWithFingerprintAllowed();
+    }
+
+    /**
      * @return true if there's at least one sfps enrollment for the current user.
      */
     public boolean isSfpsEnrolled() {
@@ -3860,8 +3883,8 @@
             return true;
         }
 
-        // change in battery overheat
-        return current.health != old.health;
+        // change in charging status
+        return current.chargingStatus != old.chargingStatus;
     }
 
     /**
@@ -4395,7 +4418,8 @@
                     mFingerprintListenBuffer.toList()
             ).printTableData(pw);
         }
-
+        pw.println("ActiveUnlockRunning="
+                + mTrustManager.isActiveUnlockRunning(KeyguardUpdateMonitor.getCurrentUser()));
         new DumpsysTableLogger(
                 "KeyguardActiveUnlockTriggers",
                 KeyguardActiveUnlockModel.TABLE_HEADERS,
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
index 6ae80a6..ebd234f 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
@@ -116,7 +116,12 @@
      * @param isTransparentMode
      */
     public void setTransparentMode(boolean isTransparentMode) {
+        if (mIsTransparentMode == isTransparentMode) {
+            return;
+        }
+
         mIsTransparentMode = isTransparentMode;
+
         if (isTransparentMode) {
             setBackgroundColor(getResources().getColor(android.R.color.transparent));
         } else {
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
index 5400011..8e8ee48 100644
--- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
@@ -101,6 +101,7 @@
     private Interpolator mFastOutSlowInInterpolator;
     private boolean mShowPassword = true;
     private UserActivityListener mUserActivityListener;
+    private boolean mIsPinHinting;
     private PinShapeInput mPinShapeInput;
     private boolean mUsePinShapes = false;
 
@@ -419,10 +420,15 @@
     /**
      * Determines whether AutoConfirmation feature is on.
      *
-     * @param usePinShapes
      * @param isPinHinting
      */
     public void setIsPinHinting(boolean isPinHinting) {
+        // Do not reinflate the view if we are using the same one.
+        if (mPinShapeInput != null && mIsPinHinting == isPinHinting) {
+            return;
+        }
+        mIsPinHinting = isPinHinting;
+
         if (mPinShapeInput != null) {
             removeView(mPinShapeInput.getView());
             mPinShapeInput = null;
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/CarrierTextManagerLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/CarrierTextManagerLogger.kt
new file mode 100644
index 0000000..1978715
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/logging/CarrierTextManagerLogger.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard.logging
+
+import androidx.annotation.IntDef
+import com.android.keyguard.CarrierTextManager.CarrierTextCallbackInfo
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel
+import com.android.systemui.log.dagger.CarrierTextManagerLog
+import javax.inject.Inject
+
+/** Logger adapter for [CarrierTextManager] to add detailed messages in a [LogBuffer] */
+class CarrierTextManagerLogger @Inject constructor(@CarrierTextManagerLog val buffer: LogBuffer) {
+    /**
+     * To help disambiguate carrier text manager instances, set a location string here which will
+     * propagate to [logUpdate] and [logUpdateCarrierTextForReason]
+     */
+    var location: String? = null
+
+    /**
+     * This method and the methods below trace the execution of CarrierTextManager.updateCarrierText
+     */
+    fun logUpdate(numSubs: Int) {
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            { int1 = numSubs },
+            { "updateCarrierText: location=${location ?: "(unknown)"} numSubs=$int1" },
+        )
+    }
+
+    fun logUpdateLoopStart(sub: Int, simState: Int, carrierName: String) {
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                int1 = sub
+                int2 = simState
+                str1 = carrierName
+            },
+            { "┣ updateCarrierText: updating sub=$int1 simState=$int2 carrierName=$str1" },
+        )
+    }
+
+    fun logUpdateWfcCheck() {
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {},
+            { "┣ updateCarrierText: found WFC state" },
+        )
+    }
+
+    fun logUpdateFromStickyBroadcast(plmn: String?, spn: String?) {
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                str1 = plmn
+                str2 = spn
+            },
+            { "┣ updateCarrierText: getting PLMN/SPN sticky brdcst. plmn=$str1, spn=$str1" },
+        )
+    }
+
+    /** De-structures the info object so that we don't have to generate new strings */
+    fun logCallbackSentFromUpdate(info: CarrierTextCallbackInfo) {
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                str1 = "${info.carrierText}"
+                bool1 = info.anySimReady
+                bool2 = info.airplaneMode
+            },
+            {
+                "┗ updateCarrierText: " +
+                    "result=(carrierText=$str1, anySimReady=$bool1, airplaneMode=$bool2)"
+            },
+        )
+    }
+
+    /**
+     * Used to log the starting point for _why_ the carrier text is updating. In order to keep us
+     * from holding on to too many objects, we'll just use simple ints for reasons here
+     */
+    fun logUpdateCarrierTextForReason(@CarrierTextRefreshReason reason: Int) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            { int1 = reason },
+            {
+                "refreshing carrier info for reason: ${reason.reasonMessage()}" +
+                    " location=${location ?: "(unknown)"}"
+            }
+        )
+    }
+
+    companion object {
+        const val REASON_REFRESH_CARRIER_INFO = 1
+        const val REASON_ON_TELEPHONY_CAPABLE = 2
+        const val REASON_ON_SIM_STATE_CHANGED = 3
+        const val REASON_ACTIVE_DATA_SUB_CHANGED = 4
+
+        @Retention(AnnotationRetention.SOURCE)
+        @IntDef(
+            value =
+                [
+                    REASON_REFRESH_CARRIER_INFO,
+                    REASON_ON_TELEPHONY_CAPABLE,
+                    REASON_ON_SIM_STATE_CHANGED,
+                    REASON_ACTIVE_DATA_SUB_CHANGED,
+                ]
+        )
+        annotation class CarrierTextRefreshReason
+
+        private fun @receiver:CarrierTextRefreshReason Int.reasonMessage() =
+            when (this) {
+                REASON_REFRESH_CARRIER_INFO -> "REFRESH_CARRIER_INFO"
+                REASON_ON_TELEPHONY_CAPABLE -> "ON_TELEPHONY_CAPABLE"
+                REASON_ON_SIM_STATE_CHANGED -> "SIM_STATE_CHANGED"
+                REASON_ACTIVE_DATA_SUB_CHANGED -> "ACTIVE_DATA_SUB_CHANGED"
+                else -> "unknown"
+            }
+    }
+}
+
+private const val TAG = "CarrierTextManagerLog"
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index c2d22c3..17cc236 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -95,10 +95,6 @@
         logBuffer.log(TAG, ERROR, {}, { logMsg }, exception = ex)
     }
 
-    fun logFaceAcquired(acquireInfo: Int) {
-        logBuffer.log(TAG, DEBUG, { int1 = acquireInfo }, { "Face acquired acquireInfo=$int1" })
-    }
-
     fun logFaceAuthDisabledForUser(userId: Int) {
         logBuffer.log(
             TAG,
@@ -128,18 +124,6 @@
         )
     }
 
-    fun logFaceAuthHelpMsg(msgId: Int, helpMsg: String?) {
-        logBuffer.log(
-            TAG,
-            DEBUG,
-            {
-                int1 = msgId
-                str1 = helpMsg
-            },
-            { "Face help received, msgId: $int1 msg: $str1" }
-        )
-    }
-
     fun logFaceAuthRequested(reason: String?) {
         logBuffer.log(TAG, DEBUG, { str1 = reason }, { "requestFaceAuth() reason=$str1" })
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/TrustRepositoryLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/TrustRepositoryLogger.kt
index f05152a..cb764a8 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/TrustRepositoryLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/TrustRepositoryLogger.kt
@@ -17,6 +17,7 @@
 package com.android.keyguard.logging
 
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.shared.model.ActiveUnlockModel
 import com.android.systemui.keyguard.shared.model.TrustManagedModel
 import com.android.systemui.keyguard.shared.model.TrustModel
 import com.android.systemui.log.LogBuffer
@@ -76,6 +77,18 @@
         )
     }
 
+    fun activeUnlockModelEmitted(value: ActiveUnlockModel) {
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                int1 = value.userId
+                bool1 = value.isRunning
+            },
+            { "activeUnlockModel emitted: userId: $int1 isRunning: $bool1" }
+        )
+    }
+
     fun isCurrentUserTrusted(isCurrentUserTrusted: Boolean) {
         logBuffer.log(
             TAG,
@@ -85,6 +98,15 @@
         )
     }
 
+    fun isCurrentUserActiveUnlockRunning(isCurrentUserActiveUnlockRunning: Boolean) {
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            { bool1 = isCurrentUserActiveUnlockRunning },
+            { "isCurrentUserActiveUnlockRunning emitted: $bool1" }
+        )
+    }
+
     fun isCurrentUserTrustManaged(isTrustManaged: Boolean) {
         logBuffer.log(TAG, DEBUG, { bool1 = isTrustManaged }, { "isTrustManaged emitted: $bool1" })
     }
diff --git a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
deleted file mode 100644
index bf84f8a..0000000
--- a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui;
-
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.os.UserHandle;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-import com.android.systemui.animation.ActivityLaunchAnimator;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
-
-import dagger.Lazy;
-
-import java.util.Optional;
-
-import javax.inject.Inject;
-
-/**
- * Single common instance of ActivityStarter that can be gotten and referenced from anywhere, but
- * delegates to an actual implementation (CentralSurfaces).
- *
- * @deprecated Migrating to ActivityStarterImpl
- */
-@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
-@SysUISingleton
-public class ActivityStarterDelegate implements ActivityStarter {
-
-    private Lazy<Optional<CentralSurfaces>> mActualStarterOptionalLazy;
-
-    @Inject
-    public ActivityStarterDelegate(Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy) {
-        mActualStarterOptionalLazy = centralSurfacesOptionalLazy;
-    }
-
-    @Override
-    public void startPendingIntentDismissingKeyguard(PendingIntent intent) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.startPendingIntentDismissingKeyguard(intent));
-    }
-
-    @Override
-    public void startPendingIntentDismissingKeyguard(PendingIntent intent,
-            Runnable intentSentUiThreadCallback) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.startPendingIntentDismissingKeyguard(
-                        intent, intentSentUiThreadCallback));
-    }
-
-    @Override
-    public void startPendingIntentDismissingKeyguard(PendingIntent intent,
-            Runnable intentSentUiThreadCallback, View associatedView) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.startPendingIntentDismissingKeyguard(
-                        intent, intentSentUiThreadCallback, associatedView));
-    }
-
-    @Override
-    public void startPendingIntentDismissingKeyguard(PendingIntent intent,
-            Runnable intentSentUiThreadCallback,
-            ActivityLaunchAnimator.Controller animationController) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.startPendingIntentDismissingKeyguard(
-                        intent, intentSentUiThreadCallback, animationController));
-    }
-
-    @Override
-    public void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade,
-            int flags) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.startActivity(intent, onlyProvisioned, dismissShade, flags));
-    }
-
-    @Override
-    public void startActivity(Intent intent, boolean dismissShade) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.startActivity(intent, dismissShade));
-    }
-
-    @Override
-    public void startActivity(Intent intent,
-            boolean dismissShade,
-            @Nullable ActivityLaunchAnimator.Controller animationController) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.startActivity(intent, dismissShade, animationController));
-    }
-
-    @Override
-    public void startActivity(Intent intent, boolean dismissShade,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            boolean showOverLockscreenWhenLocked) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.startActivity(intent, dismissShade, animationController,
-                    showOverLockscreenWhenLocked));
-    }
-
-    @Override
-    public void startActivity(Intent intent, boolean dismissShade,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            boolean showOverLockscreenWhenLocked, UserHandle userHandle) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.startActivity(intent, dismissShade, animationController,
-                    showOverLockscreenWhenLocked, userHandle));
-    }
-
-    @Override
-    public void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.startActivity(intent, onlyProvisioned, dismissShade));
-    }
-
-    @Override
-    public void startActivity(Intent intent, boolean dismissShade, Callback callback) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.startActivity(intent, dismissShade, callback));
-    }
-
-    @Override
-    public void postStartActivityDismissingKeyguard(Intent intent, int delay) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.postStartActivityDismissingKeyguard(intent, delay));
-    }
-
-    @Override
-    public void postStartActivityDismissingKeyguard(Intent intent, int delay,
-            @Nullable ActivityLaunchAnimator.Controller animationController) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.postStartActivityDismissingKeyguard(
-                        intent, delay, animationController));
-    }
-
-    @Override
-    public void postStartActivityDismissingKeyguard(PendingIntent intent) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.postStartActivityDismissingKeyguard(intent));
-    }
-
-    @Override
-    public void postStartActivityDismissingKeyguard(Intent intent, int delay,
-            @Nullable ActivityLaunchAnimator.Controller animationController, String customMessage) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.postStartActivityDismissingKeyguard(intent, delay,
-                        animationController, customMessage));
-    }
-
-    @Override
-    public void postStartActivityDismissingKeyguard(PendingIntent intent,
-            ActivityLaunchAnimator.Controller animationController) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.postStartActivityDismissingKeyguard(
-                        intent, animationController));
-    }
-
-    @Override
-    public void postQSRunnableDismissingKeyguard(Runnable runnable) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.postQSRunnableDismissingKeyguard(runnable));
-    }
-
-    @Override
-    public void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancel,
-            boolean afterKeyguardGone) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.dismissKeyguardThenExecute(action, cancel, afterKeyguardGone));
-    }
-
-    @Override
-    public void dismissKeyguardThenExecute(OnDismissAction action, @Nullable Runnable cancel,
-            boolean afterKeyguardGone, String customMessage) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.dismissKeyguardThenExecute(action, cancel, afterKeyguardGone,
-                        customMessage));
-    }
-
-    @Override
-    public void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
-            boolean dismissShade, boolean disallowEnterPictureInPictureWhileLaunching,
-            Callback callback, int flags,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            UserHandle userHandle) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.startActivityDismissingKeyguard(intent, onlyProvisioned,
-                        dismissShade, disallowEnterPictureInPictureWhileLaunching, callback,
-                        flags, animationController, userHandle));
-    }
-
-    @Override
-    public void executeRunnableDismissingKeyguard(Runnable runnable,
-            Runnable cancelAction, boolean dismissShade,
-            boolean afterKeyguardGone, boolean deferred) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.executeRunnableDismissingKeyguard(runnable, cancelAction,
-                        dismissShade, afterKeyguardGone, deferred));
-    }
-
-    @Override
-    public void executeRunnableDismissingKeyguard(Runnable runnable, Runnable cancelAction,
-            boolean dismissShade, boolean afterKeyguardGone, boolean deferred,
-            boolean willAnimateOnKeyguard, @Nullable String customMessage) {
-        mActualStarterOptionalLazy.get().ifPresent(
-                starter -> starter.executeRunnableDismissingKeyguard(runnable, cancelAction,
-                        dismissShade, afterKeyguardGone, deferred, willAnimateOnKeyguard,
-                        customMessage));
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt b/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt
deleted file mode 100644
index 227f0ace..0000000
--- a/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.android.systemui
-
-import android.content.ComponentName
-import android.content.Context
-import android.content.pm.PackageManager
-import android.util.Log
-import com.android.internal.R
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.FlagListenable
-import com.android.systemui.flags.Flags
-import com.android.systemui.settings.UserTracker
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.suspendCancellableCoroutine
-import kotlinx.coroutines.withContext
-import javax.inject.Inject
-
-@SysUISingleton
-class ChooserSelector @Inject constructor(
-        private val context: Context,
-        private val userTracker: UserTracker,
-        private val featureFlags: FeatureFlags,
-        @Application private val coroutineScope: CoroutineScope,
-        @Background private val bgDispatcher: CoroutineDispatcher,
-) : CoreStartable {
-
-    private val chooserComponent = ComponentName.unflattenFromString(
-            context.resources.getString(R.string.config_chooserActivity))
-
-    override fun start() {
-        coroutineScope.launch {
-            val listener = FlagListenable.Listener { event ->
-                if (event.flagName == Flags.CHOOSER_UNBUNDLED.name) {
-                    launch { updateUnbundledChooserEnabled() }
-                    event.requestNoRestart()
-                }
-            }
-            featureFlags.addListener(Flags.CHOOSER_UNBUNDLED, listener)
-            updateUnbundledChooserEnabled()
-
-            awaitCancellationAndThen { featureFlags.removeListener(listener) }
-        }
-    }
-
-    private suspend fun updateUnbundledChooserEnabled() {
-        setUnbundledChooserEnabled(withContext(bgDispatcher) {
-            featureFlags.isEnabled(Flags.CHOOSER_UNBUNDLED)
-        })
-    }
-
-    private fun setUnbundledChooserEnabled(enabled: Boolean) {
-        val newState = if (enabled) {
-            PackageManager.COMPONENT_ENABLED_STATE_ENABLED
-        } else {
-            PackageManager.COMPONENT_ENABLED_STATE_DISABLED
-        }
-        userTracker.userProfiles.forEach {
-            try {
-                context.createContextAsUser(it.userHandle, /* flags = */ 0).packageManager
-                        .setComponentEnabledSetting(chooserComponent, newState, /* flags = */ 0)
-            } catch (e: IllegalArgumentException) {
-                Log.w(
-                        "ChooserSelector",
-                        "Unable to set IntentResolver enabled=$enabled for user ${it.id}",
-                        e,
-                )
-            }
-        }
-    }
-
-    suspend inline fun awaitCancellation(): Nothing = suspendCancellableCoroutine { }
-    suspend inline fun awaitCancellationAndThen(block: () -> Unit): Nothing = try {
-        awaitCancellation()
-    } finally {
-        block()
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
index 76086df..403c809 100644
--- a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
@@ -31,10 +31,10 @@
 import android.hardware.biometrics.BiometricSourceType
 import android.view.View
 import androidx.core.graphics.ColorUtils
+import com.android.app.animation.Interpolators
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.settingslib.Utils
-import com.android.app.animation.Interpolators
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.log.ScreenDecorationsLogger
 import com.android.systemui.plugins.statusbar.StatusBarStateController
@@ -63,7 +63,7 @@
     private var cameraProtectionColor = Color.BLACK
 
     var faceScanningAnimColor = Utils.getColorAttrDefaultColor(context,
-            R.attr.wallpaperTextColorAccent)
+        com.android.internal.R.attr.materialColorPrimaryFixed)
     private var cameraProtectionAnimator: ValueAnimator? = null
     var hideOverlayRunnable: Runnable? = null
     var faceAuthSucceeded = false
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
index 632fcdc..2b468cf 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
@@ -27,6 +27,7 @@
 import com.android.systemui.dagger.WMComponent;
 import com.android.systemui.util.InitializationChecker;
 import com.android.wm.shell.dagger.WMShellConcurrencyModule;
+import com.android.wm.shell.keyguard.KeyguardTransitions;
 import com.android.wm.shell.sysui.ShellInterface;
 import com.android.wm.shell.transition.ShellTransitions;
 
@@ -93,6 +94,7 @@
                     .setBubbles(mWMComponent.getBubbles())
                     .setTaskViewFactory(mWMComponent.getTaskViewFactory())
                     .setTransitions(mWMComponent.getTransitions())
+                    .setKeyguardTransitions(mWMComponent.getKeyguardTransitions())
                     .setStartingSurface(mWMComponent.getStartingSurface())
                     .setDisplayAreaHelper(mWMComponent.getDisplayAreaHelper())
                     .setRecentTasks(mWMComponent.getRecentTasks())
@@ -113,6 +115,7 @@
                     .setBubbles(Optional.ofNullable(null))
                     .setTaskViewFactory(Optional.ofNullable(null))
                     .setTransitions(new ShellTransitions() {})
+                    .setKeyguardTransitions(new KeyguardTransitions() {})
                     .setDisplayAreaHelper(Optional.ofNullable(null))
                     .setStartingSurface(Optional.ofNullable(null))
                     .setRecentTasks(Optional.ofNullable(null))
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityLogger.kt b/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityLogger.kt
new file mode 100644
index 0000000..7b91596
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityLogger.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility
+
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+import javax.inject.Inject
+
+/**
+ * Handles logging UiEvent stats for simple UI interactions.
+ *
+ * See go/uievent
+ */
+class AccessibilityLogger @Inject constructor(private val uiEventLogger: UiEventLogger) {
+    /** Logs the given event */
+    fun log(event: UiEventLogger.UiEventEnum) {
+        uiEventLogger.log(event)
+    }
+
+    /** Events regarding interaction with the magnifier settings panel */
+    enum class MagnificationSettingsEvent constructor(private val id: Int) :
+        UiEventLogger.UiEventEnum {
+        @UiEvent(doc = "Magnification settings panel opened.")
+        MAGNIFICATION_SETTINGS_PANEL_OPENED(1381),
+
+        @UiEvent(doc = "Magnification settings panel closed")
+        MAGNIFICATION_SETTINGS_PANEL_CLOSED(1382),
+
+        @UiEvent(doc = "Magnification settings panel edit size button clicked")
+        MAGNIFICATION_SETTINGS_SIZE_EDITING_ACTIVATED(1383),
+
+        @UiEvent(doc = "Magnification settings panel edit size save button clicked")
+        MAGNIFICATION_SETTINGS_SIZE_EDITING_DEACTIVATED(1384),
+
+        @UiEvent(doc = "Magnification settings panel window size selected")
+        MAGNIFICATION_SETTINGS_WINDOW_SIZE_SELECTED(1386);
+
+        override fun getId(): Int = this.id
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java
index 3349fe5..c3bb423 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationSettingsController.java
@@ -87,19 +87,14 @@
     }
 
     /**
-     * Shows magnification settings panel {@link WindowMagnificationSettings}. The panel ui would be
-     * various for different magnification mode.
-     *
-     * @param mode      The magnification mode
-     * @see android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
-     * @see android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
+     * Shows magnification settings panel {@link WindowMagnificationSettings}.
      */
-    void showMagnificationSettings(int mode) {
+    void showMagnificationSettings() {
         if (!mWindowMagnificationSettings.isSettingPanelShowing()) {
             onConfigurationChanged(mContext.getResources().getConfiguration());
             mContext.registerComponentCallbacks(this);
         }
-        mWindowMagnificationSettings.showSettingPanel(mode);
+        mWindowMagnificationSettings.showSettingPanel();
     }
 
     void closeMagnificationSettings() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
index 1c030da..e2b85fa 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
@@ -16,10 +16,10 @@
 
 package com.android.systemui.accessibility;
 
-import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
 
+import static com.android.systemui.accessibility.AccessibilityLogger.MagnificationSettingsEvent;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_MAGNIFICATION_OVERLAP;
 
 import android.annotation.MainThread;
@@ -67,6 +67,7 @@
     private final CommandQueue mCommandQueue;
     private final OverviewProxyService mOverviewProxyService;
     private final DisplayTracker mDisplayTracker;
+    private final AccessibilityLogger mA11yLogger;
 
     private WindowMagnificationConnectionImpl mWindowMagnificationConnectionImpl;
     private SysUiState mSysUiState;
@@ -152,7 +153,7 @@
             CommandQueue commandQueue, ModeSwitchesController modeSwitchesController,
             SysUiState sysUiState, OverviewProxyService overviewProxyService,
             SecureSettings secureSettings, DisplayTracker displayTracker,
-            DisplayManager displayManager) {
+            DisplayManager displayManager, AccessibilityLogger a11yLogger) {
         mContext = context;
         mHandler = mainHandler;
         mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
@@ -161,6 +162,7 @@
         mSysUiState = sysUiState;
         mOverviewProxyService = overviewProxyService;
         mDisplayTracker = displayTracker;
+        mA11yLogger = a11yLogger;
         mMagnificationControllerSupplier = new ControllerSupplier(context,
                 mHandler, mWindowMagnifierCallback,
                 displayManager, sysUiState, secureSettings);
@@ -169,8 +171,7 @@
 
         mModeSwitchesController.setClickListenerDelegate(
                 displayId -> mHandler.post(() -> {
-                    showMagnificationSettingsPanel(displayId,
-                            ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+                    showMagnificationSettingsPanel(displayId);
                 }));
     }
 
@@ -253,11 +254,11 @@
     }
 
     @MainThread
-    void showMagnificationSettingsPanel(int displayId, int mode) {
+    void showMagnificationSettingsPanel(int displayId) {
         final MagnificationSettingsController magnificationSettingsController =
                 mMagnificationSettingsSupplier.get(displayId);
         if (magnificationSettingsController != null) {
-            magnificationSettingsController.showMagnificationSettings(mode);
+            magnificationSettingsController.showMagnificationSettings();
         }
     }
 
@@ -334,7 +335,7 @@
         @Override
         public void onClickSettingsButton(int displayId) {
             mHandler.post(() -> {
-                showMagnificationSettingsPanel(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+                showMagnificationSettingsPanel(displayId);
             });
         }
     };
@@ -345,6 +346,7 @@
         @Override
         public void onSetMagnifierSize(int displayId, int index) {
             mHandler.post(() -> onSetMagnifierSizeInternal(displayId, index));
+            mA11yLogger.log(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_WINDOW_SIZE_SELECTED);
         }
 
         @Override
@@ -355,6 +357,9 @@
         @Override
         public void onEditMagnifierSizeMode(int displayId, boolean enable) {
             mHandler.post(() -> onEditMagnifierSizeModeInternal(displayId, enable));
+            mA11yLogger.log(enable
+                    ? MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_SIZE_EDITING_ACTIVATED
+                    : MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_SIZE_EDITING_DEACTIVATED);
         }
 
         @Override
@@ -372,6 +377,9 @@
         @Override
         public void onSettingsPanelVisibilityChanged(int displayId, boolean shown) {
             mHandler.post(() -> onSettingsPanelVisibilityChangedInternal(displayId, shown));
+            mA11yLogger.log(shown
+                    ? MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_OPENED
+                    : MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_CLOSED);
         }
     };
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
index 155c26d..3b1d695 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.accessibility;
 
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
@@ -27,6 +28,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
+import android.database.ContentObserver;
 import android.graphics.Insets;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
@@ -51,6 +53,7 @@
 import android.widget.LinearLayout;
 import android.widget.SeekBar;
 import android.widget.Switch;
+import android.widget.TextView;
 
 import com.android.internal.accessibility.common.MagnificationConstants;
 import com.android.internal.annotations.VisibleForTesting;
@@ -85,6 +88,7 @@
 
     private SeekBarWithIconButtonsView mZoomSeekbar;
     private LinearLayout mAllowDiagonalScrollingView;
+    private TextView mAllowDiagonalScrollingTitle;
     private Switch mAllowDiagonalScrollingSwitch;
     private LinearLayout mPanelView;
     private LinearLayout mSettingView;
@@ -101,8 +105,7 @@
     private static final float A11Y_SCALE_MIN_VALUE = 1.0f;
     private WindowMagnificationSettingsCallback mCallback;
 
-    // the magnification mode that triggers showing the panel
-    private int mTriggeringMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
+    private ContentObserver mMagnificationCapabilityObserver;
 
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({
@@ -142,6 +145,16 @@
 
         mGestureDetector = new MagnificationGestureDetector(context,
                 context.getMainThreadHandler(), this);
+
+        mMagnificationCapabilityObserver = new ContentObserver(
+                mContext.getMainThreadHandler()) {
+            @Override
+            public void onChange(boolean selfChange) {
+                mSettingView.post(() -> {
+                    updateUIControlsIfNeeded();
+                });
+            }
+        };
     }
 
     private class ZoomSeekbarChangeListener implements SeekBar.OnSeekBarChangeListener {
@@ -257,7 +270,7 @@
     @Override
     public boolean onFinish(float xOffset, float yOffset) {
         if (!mSingleTapDetected) {
-            showSettingPanel(mTriggeringMode);
+            showSettingPanel();
         }
         mSingleTapDetected = false;
         return true;
@@ -285,7 +298,8 @@
             return;
         }
 
-        // Reset button status.
+        // Unregister observer before removing view
+        mSecureSettings.unregisterContentObserver(mMagnificationCapabilityObserver);
         mWindowManager.removeView(mSettingView);
         mIsVisible = false;
         if (resetPosition) {
@@ -297,16 +311,8 @@
         mCallback.onSettingsPanelVisibilityChanged(/* shown= */ false);
     }
 
-    /**
-     * Shows magnification settings panel. The panel ui would be various for
-     * different magnification mode.
-     *
-     * @param mode      The magnification mode
-     * @see android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
-     * @see android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
-     */
-    public void showSettingPanel(int mode) {
-        showSettingPanel(mode, true);
+    public void showSettingPanel() {
+        showSettingPanel(true);
     }
 
     public boolean isSettingPanelShowing() {
@@ -322,18 +328,15 @@
     }
 
     /**
-     * Shows magnification panel for set magnification.
+     * Shows the panel for magnification settings.
      * When the panel is going to be visible by calling this method, the layout position can be
      * reset depending on the flag.
      *
-     * @param mode The magnification mode
-     * @param resetPosition if the button position needs be reset
+     * @param resetPosition if the panel position needs to be reset
      */
-    private void showSettingPanel(int mode, boolean resetPosition) {
+    private void showSettingPanel(boolean resetPosition) {
         if (!mIsVisible) {
-            updateUIControlsIfNeed(mode);
-            mTriggeringMode = mode;
-
+            updateUIControlsIfNeeded();
             if (resetPosition) {
                 mDraggableWindowBounds.set(getDraggableWindowBounds());
                 mParams.x = mDraggableWindowBounds.right;
@@ -342,6 +345,11 @@
 
             mWindowManager.addView(mSettingView, mParams);
 
+            mSecureSettings.registerContentObserverForUser(
+                    Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY,
+                    mMagnificationCapabilityObserver,
+                    UserHandle.USER_CURRENT);
+
             // Exclude magnification switch button from system gesture area.
             setSystemGestureExclusion();
             mIsVisible = true;
@@ -359,35 +367,74 @@
         mContext.registerReceiver(mScreenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
     }
 
-    private void updateUIControlsIfNeed(int mode) {
-        if (mode == mTriggeringMode) {
-            return;
-        }
+    private int getMagnificationMode() {
+        return mSecureSettings.getIntForUser(
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
+                ACCESSIBILITY_MAGNIFICATION_MODE_NONE,
+                UserHandle.USER_CURRENT);
+    }
+
+    private int getMagnificationCapability() {
+        return mSecureSettings.getIntForUser(
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY,
+                ACCESSIBILITY_MAGNIFICATION_MODE_NONE,
+                UserHandle.USER_CURRENT);
+    }
+
+    private void updateUIControlsIfNeeded() {
+        int capability = getMagnificationCapability();
 
         int selectedButtonIndex = mLastSelectedButtonIndex;
-        switch (mode) {
+        switch (capability) {
+            case ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW:
+                mEditButton.setVisibility(View.VISIBLE);
+                mAllowDiagonalScrollingView.setVisibility(View.VISIBLE);
+                mFullScreenButton.setVisibility(View.GONE);
+                if (selectedButtonIndex == MagnificationSize.FULLSCREEN) {
+                    selectedButtonIndex = MagnificationSize.NONE;
+                }
+                break;
+
+            case ACCESSIBILITY_MAGNIFICATION_MODE_ALL:
+                int mode = getMagnificationMode();
+                mFullScreenButton.setVisibility(View.VISIBLE);
+                if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) {
+                    // set the edit button visibility to View.INVISIBLE to keep the height, to
+                    // prevent the size title from too close to the size buttons
+                    mEditButton.setVisibility(View.INVISIBLE);
+                    mAllowDiagonalScrollingView.setVisibility(View.GONE);
+                    // force the fullscreen button showing
+                    selectedButtonIndex = MagnificationSize.FULLSCREEN;
+                } else { // mode = ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
+                    mEditButton.setVisibility(View.VISIBLE);
+                    mAllowDiagonalScrollingView.setVisibility(View.VISIBLE);
+                }
+                break;
+
             case ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN:
-                // set the edit button visibility to View.INVISIBLE to keep the height, to prevent
-                // the size title from too close to the size buttons
+                // We will never fall into this case since we never show settings panel when
+                // capability equals to ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN.
+                // Currently, the case follows the UI controls when capability equals to
+                // ACCESSIBILITY_MAGNIFICATION_MODE_ALL and mode equals to
+                // ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN, but we could also consider to
+                // remove the whole icon button selections int the future since they are no use
+                // for fullscreen only capability.
+
+                mFullScreenButton.setVisibility(View.VISIBLE);
+                // set the edit button visibility to View.INVISIBLE to keep the height, to
+                // prevent the size title from too close to the size buttons
                 mEditButton.setVisibility(View.INVISIBLE);
                 mAllowDiagonalScrollingView.setVisibility(View.GONE);
                 // force the fullscreen button showing
                 selectedButtonIndex = MagnificationSize.FULLSCREEN;
                 break;
 
-            case ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW:
-                mEditButton.setVisibility(View.VISIBLE);
-                mAllowDiagonalScrollingView.setVisibility(View.VISIBLE);
-                if (selectedButtonIndex == MagnificationSize.FULLSCREEN) {
-                    selectedButtonIndex = MagnificationSize.NONE;
-                }
-                break;
-
             default:
                 break;
         }
 
         updateSelectedButton(selectedButtonIndex);
+        mSettingView.requestLayout();
     }
 
     private final BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
@@ -422,6 +469,8 @@
         mDoneButton = mSettingView.findViewById(R.id.magnifier_done_button);
         mEditButton = mSettingView.findViewById(R.id.magnifier_edit_button);
         mFullScreenButton = mSettingView.findViewById(R.id.magnifier_full_button);
+        mAllowDiagonalScrollingTitle =
+                mSettingView.findViewById(R.id.magnifier_horizontal_lock_title);
 
         mZoomSeekbar = mSettingView.findViewById(R.id.magnifier_zoom_slider);
         float scale = mSecureSettings.getFloatForUser(
@@ -445,6 +494,7 @@
         mDoneButton.setOnClickListener(mButtonClickListener);
         mFullScreenButton.setOnClickListener(mButtonClickListener);
         mEditButton.setOnClickListener(mButtonClickListener);
+        mAllowDiagonalScrollingTitle.setSelected(true);
 
         mSettingView.setOnApplyWindowInsetsListener((v, insets) -> {
             // Adds a pending post check to avoiding redundant calculation because this callback
@@ -474,11 +524,11 @@
 
             mParams.accessibilityTitle = getAccessibilityWindowTitle(mContext);
 
-            boolean showSettingPanelAfterThemeChange = mIsVisible;
+            boolean showSettingPanelAfterConfigChange = mIsVisible;
             hideSettingPanel(/* resetPosition= */ false);
             inflateView();
-            if (showSettingPanelAfterThemeChange) {
-                showSettingPanel(mTriggeringMode, /* resetPosition= */ false);
+            if (showSettingPanelAfterConfigChange) {
+                showSettingPanel(/* resetPosition= */ false);
             }
             return;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
index cd195f6..c684dc5 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
@@ -33,7 +33,7 @@
      * A device that is not yet unlocked requires unlocking by completing an authentication
      * challenge according to the current authentication method.
      *
-     * Note that this state has no real bearing on whether the lock screen is showing or dismissed.
+     * Note that this state has no real bearing on whether the lockscreen is showing or dismissed.
      */
     val isUnlocked: StateFlow<Boolean>
 
@@ -51,6 +51,12 @@
      */
     val isBypassEnabled: StateFlow<Boolean>
 
+    /**
+     * Number of consecutively failed authentication attempts. This resets to `0` when
+     * authentication succeeds.
+     */
+    val failedAuthenticationAttempts: StateFlow<Int>
+
     /** See [isUnlocked]. */
     fun setUnlocked(isUnlocked: Boolean)
 
@@ -59,6 +65,9 @@
 
     /** See [isBypassEnabled]. */
     fun setBypassEnabled(isBypassEnabled: Boolean)
+
+    /** See [failedAuthenticationAttempts]. */
+    fun setFailedAuthenticationAttempts(failedAuthenticationAttempts: Int)
 }
 
 class AuthenticationRepositoryImpl @Inject constructor() : AuthenticationRepository {
@@ -75,6 +84,10 @@
     private val _isBypassEnabled = MutableStateFlow(false)
     override val isBypassEnabled: StateFlow<Boolean> = _isBypassEnabled.asStateFlow()
 
+    private val _failedAuthenticationAttempts = MutableStateFlow(0)
+    override val failedAuthenticationAttempts: StateFlow<Int> =
+        _failedAuthenticationAttempts.asStateFlow()
+
     override fun setUnlocked(isUnlocked: Boolean) {
         _isUnlocked.value = isUnlocked
     }
@@ -86,6 +99,10 @@
     override fun setAuthenticationMethod(authenticationMethod: AuthenticationMethodModel) {
         _authenticationMethod.value = authenticationMethod
     }
+
+    override fun setFailedAuthenticationAttempts(failedAuthenticationAttempts: Int) {
+        _failedAuthenticationAttempts.value = failedAuthenticationAttempts
+    }
 }
 
 @Module
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
index 5aea930..3984627 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
@@ -75,6 +75,12 @@
      */
     val isBypassEnabled: StateFlow<Boolean> = repository.isBypassEnabled
 
+    /**
+     * Number of consecutively failed authentication attempts. This resets to `0` when
+     * authentication succeeds.
+     */
+    val failedAuthenticationAttempts: StateFlow<Int> = repository.failedAuthenticationAttempts
+
     init {
         // UNLOCKS WHEN AUTH METHOD REMOVED.
         //
@@ -130,7 +136,12 @@
             }
 
         if (isSuccessful) {
+            repository.setFailedAuthenticationAttempts(0)
             repository.setUnlocked(true)
+        } else {
+            repository.setFailedAuthenticationAttempts(
+                repository.failedAuthenticationAttempts.value + 1
+            )
         }
 
         return isSuccessful
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt
index 83250b6..6f008c3 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt
@@ -36,8 +36,10 @@
 
     data class Password(val password: String) : AuthenticationMethodModel(isSecure = true)
 
-    data class Pattern(val coordinates: List<PatternCoordinate>) :
-        AuthenticationMethodModel(isSecure = true) {
+    data class Pattern(
+        val coordinates: List<PatternCoordinate>,
+        val isPatternVisible: Boolean = true,
+    ) : AuthenticationMethodModel(isSecure = true) {
 
         data class PatternCoordinate(
             val x: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
index 2aac056..263df33 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
@@ -78,7 +78,7 @@
     private boolean mShowPercentAvailable;
     private String mEstimateText = null;
     private boolean mCharging;
-    private boolean mIsOverheated;
+    private boolean mIsBatteryDefender;
     private boolean mDisplayShieldEnabled;
     // Error state where we know nothing about the current battery state
     private boolean mBatteryStateUnknown;
@@ -213,9 +213,9 @@
         mDrawable.setPowerSaveEnabled(isPowerSave);
     }
 
-    void onIsOverheatedChanged(boolean isOverheated) {
-        boolean valueChanged = mIsOverheated != isOverheated;
-        mIsOverheated = isOverheated;
+    void onIsBatteryDefenderChanged(boolean isBatteryDefender) {
+        boolean valueChanged = mIsBatteryDefender != isBatteryDefender;
+        mIsBatteryDefender = isBatteryDefender;
         if (valueChanged) {
             updateContentDescription();
             // The battery drawable is a different size depending on whether it's currently
@@ -308,12 +308,12 @@
             contentDescription = context.getString(R.string.accessibility_battery_unknown);
         } else if (mShowPercentMode == MODE_ESTIMATE && !TextUtils.isEmpty(mEstimateText)) {
             contentDescription = context.getString(
-                    mIsOverheated
+                    mIsBatteryDefender
                             ? R.string.accessibility_battery_level_charging_paused_with_estimate
                             : R.string.accessibility_battery_level_with_estimate,
                     mLevel,
                     mEstimateText);
-        } else if (mIsOverheated) {
+        } else if (mIsBatteryDefender) {
             contentDescription =
                     context.getString(R.string.accessibility_battery_level_charging_paused, mLevel);
         } else if (mCharging) {
@@ -399,9 +399,7 @@
         float mainBatteryWidth =
                 res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_width) * iconScaleFactor;
 
-        // If the battery is marked as overheated, we should display a shield indicating that the
-        // battery is being "defended".
-        boolean displayShield = mDisplayShieldEnabled && mIsOverheated;
+        boolean displayShield = mDisplayShieldEnabled && mIsBatteryDefender;
         float fullBatteryIconHeight =
                 BatterySpecs.getFullBatteryHeight(mainBatteryHeight, displayShield);
         float fullBatteryIconWidth =
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java
index f4ec33a..f6a10bd 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterViewController.java
@@ -91,8 +91,8 @@
                 }
 
                 @Override
-                public void onIsOverheatedChanged(boolean isOverheated) {
-                    mView.onIsOverheatedChanged(isOverheated);
+                public void onIsBatteryDefenderChanged(boolean isBatteryDefender) {
+                    mView.onIsBatteryDefenderChanged(isBatteryDefender);
                 }
             };
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
index 1404053..682888f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
@@ -21,42 +21,43 @@
 import com.airbnb.lottie.LottieAnimationView
 import com.android.systemui.R
 import com.android.systemui.biometrics.AuthBiometricView.BiometricState
-import com.android.systemui.biometrics.AuthBiometricView.STATE_AUTHENTICATED
 import com.android.systemui.biometrics.AuthBiometricView.STATE_ERROR
 import com.android.systemui.biometrics.AuthBiometricView.STATE_HELP
 import com.android.systemui.biometrics.AuthBiometricView.STATE_PENDING_CONFIRMATION
 
 /** Face/Fingerprint combined icon animator for BiometricPrompt. */
-class AuthBiometricFingerprintAndFaceIconController(
-        context: Context,
-        iconView: LottieAnimationView,
-        iconViewOverlay: LottieAnimationView
+open class AuthBiometricFingerprintAndFaceIconController(
+    context: Context,
+    iconView: LottieAnimationView,
+    iconViewOverlay: LottieAnimationView,
 ) : AuthBiometricFingerprintIconController(context, iconView, iconViewOverlay) {
 
     override val actsAsConfirmButton: Boolean = true
 
     override fun shouldAnimateIconViewForTransition(
-            @BiometricState oldState: Int,
-            @BiometricState newState: Int
+        @BiometricState oldState: Int,
+        @BiometricState newState: Int
     ): Boolean = when (newState) {
         STATE_PENDING_CONFIRMATION -> true
-        STATE_AUTHENTICATED -> false
         else -> super.shouldAnimateIconViewForTransition(oldState, newState)
     }
 
     @RawRes
     override fun getAnimationForTransition(
-            @BiometricState oldState: Int,
-            @BiometricState newState: Int
+        @BiometricState oldState: Int,
+        @BiometricState newState: Int
     ): Int? = when (newState) {
         STATE_PENDING_CONFIRMATION -> {
             if (oldState == STATE_ERROR || oldState == STATE_HELP) {
                 R.raw.fingerprint_dialogue_error_to_unlock_lottie
+            } else if (oldState == STATE_PENDING_CONFIRMATION) {
+                // TODO(jbolinger): missing asset for this transition
+                // (unlocked icon to success checkmark)
+                R.raw.fingerprint_dialogue_fingerprint_to_unlock_lottie
             } else {
                 R.raw.fingerprint_dialogue_fingerprint_to_unlock_lottie
             }
         }
-        STATE_AUTHENTICATED -> null
         else -> super.getAnimationForTransition(oldState, newState)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceView.kt
index 57ffd24..7ce74db 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceView.kt
@@ -40,11 +40,11 @@
     override fun ignoreUnsuccessfulEventsFrom(@Modality modality: Int, unsuccessfulReason: String) =
         modality == TYPE_FACE && !(isFaceClass3 && isLockoutErrorString(unsuccessfulReason))
 
-    override fun onPointerDown(failedModalities: Set<Int>) = failedModalities.contains(TYPE_FACE)
-
     override fun createIconController(): AuthIconController =
         AuthBiometricFingerprintAndFaceIconController(mContext, mIconView, mIconViewOverlay)
 
+    override fun isCoex() = true
+
     private fun isLockoutErrorString(unsuccessfulReason: String) =
         unsuccessfulReason == FaceManager.getErrorString(
             mContext,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
index f04fdfff..9807b9e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
@@ -122,7 +122,9 @@
         if (shouldAnimateIconViewForTransition(lastState, newState)) {
             iconView.playAnimation()
         }
-        LottieColorUtils.applyDynamicColors(context, iconView)
+        if (isSideFps) {
+            LottieColorUtils.applyDynamicColors(context, iconView)
+        }
     }
 
     override fun updateIcon(@BiometricState lastState: Int, @BiometricState newState: Int) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index e089fd3..fb160f2 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -28,6 +28,7 @@
 import android.annotation.StringRes;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.graphics.Insets;
 import android.hardware.biometrics.BiometricAuthenticator.Modality;
 import android.hardware.biometrics.BiometricPrompt;
 import android.hardware.biometrics.PromptInfo;
@@ -55,43 +56,42 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
 
 /**
  * Contains the Biometric views (title, subtitle, icon, buttons, etc.) and its controllers.
  */
-public abstract class AuthBiometricView extends LinearLayout {
+public abstract class AuthBiometricView extends LinearLayout implements AuthBiometricViewAdapter {
 
     private static final String TAG = "AuthBiometricView";
 
     /**
      * Authentication hardware idle.
      */
-    protected static final int STATE_IDLE = 0;
+    public static final int STATE_IDLE = 0;
     /**
      * UI animating in, authentication hardware active.
      */
-    protected static final int STATE_AUTHENTICATING_ANIMATING_IN = 1;
+    public static final int STATE_AUTHENTICATING_ANIMATING_IN = 1;
     /**
      * UI animated in, authentication hardware active.
      */
-    protected static final int STATE_AUTHENTICATING = 2;
+    public static final int STATE_AUTHENTICATING = 2;
     /**
      * UI animated in, authentication hardware active.
      */
-    protected static final int STATE_HELP = 3;
+    public static final int STATE_HELP = 3;
     /**
      * Hard error, e.g. ERROR_TIMEOUT. Authentication hardware idle.
      */
-    protected static final int STATE_ERROR = 4;
+    public static final int STATE_ERROR = 4;
     /**
      * Authenticated, waiting for user confirmation. Authentication hardware idle.
      */
-    protected static final int STATE_PENDING_CONFIRMATION = 5;
+    public static final int STATE_PENDING_CONFIRMATION = 5;
     /**
      * Authenticated, dialog animating away soon.
      */
-    protected static final int STATE_AUTHENTICATED = 6;
+    public static final int STATE_AUTHENTICATED = 6;
 
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({STATE_IDLE, STATE_AUTHENTICATING_ANIMATING_IN, STATE_AUTHENTICATING, STATE_HELP,
@@ -101,13 +101,14 @@
     /**
      * Callback to the parent when a user action has occurred.
      */
-    interface Callback {
+    public interface Callback {
         int ACTION_AUTHENTICATED = 1;
         int ACTION_USER_CANCELED = 2;
         int ACTION_BUTTON_NEGATIVE = 3;
         int ACTION_BUTTON_TRY_AGAIN = 4;
         int ACTION_ERROR = 5;
         int ACTION_USE_DEVICE_CREDENTIAL = 6;
+        int ACTION_START_DELAYED_FINGERPRINT_SENSOR = 7;
 
         /**
          * When an action has occurred. The caller will only invoke this when the callback should
@@ -267,6 +268,27 @@
     /** Create the controller for managing the icons transitions during the prompt.*/
     @NonNull
     protected abstract AuthIconController createIconController();
+
+    @Override
+    public AuthIconController getLegacyIconController() {
+        return mIconController;
+    }
+
+    @Override
+    public void cancelAnimation() {
+        animate().cancel();
+    }
+
+    @Override
+    public View asView() {
+        return this;
+    }
+
+    @Override
+    public boolean isCoex() {
+        return false;
+    }
+
     void setPanelController(AuthPanelController panelController) {
         mPanelController = panelController;
     }
@@ -298,9 +320,25 @@
         mJankListener = jankListener;
     }
 
+    private void updatePaddings(int size) {
+        final Insets navBarInsets = Utils.getNavbarInsets(mContext);
+        if (size != AuthDialog.SIZE_LARGE) {
+            if (mPanelController.getPosition() == AuthPanelController.POSITION_LEFT) {
+                setPadding(navBarInsets.left, 0, 0, 0);
+            } else if (mPanelController.getPosition() == AuthPanelController.POSITION_RIGHT) {
+                setPadding(0, 0, navBarInsets.right, 0);
+            } else {
+                setPadding(0, 0, 0, navBarInsets.bottom);
+            }
+        } else {
+            setPadding(0, 0, 0, 0);
+        }
+    }
+
     @VisibleForTesting
     final void updateSize(@AuthDialog.DialogSize int newSize) {
         Log.v(TAG, "Current size: " + mSize + " New size: " + newSize);
+        updatePaddings(newSize);
         if (newSize == AuthDialog.SIZE_SMALL) {
             mTitleView.setVisibility(View.GONE);
             mSubtitleView.setVisibility(View.GONE);
@@ -527,7 +565,12 @@
         mState = newState;
     }
 
-    public void onDialogAnimatedIn() {
+    public void onOrientationChanged() {
+        // Update padding and AuthPanel outline by calling updateSize when the orientation changed.
+        updateSize(mSize);
+    }
+
+    public void onDialogAnimatedIn(boolean fingerprintWasStarted) {
         updateState(STATE_AUTHENTICATING);
     }
 
@@ -575,18 +618,6 @@
     }
 
     /**
-     * Fingerprint pointer down event. This does nothing by default and will not be called if the
-     * device does not have an appropriate sensor (UDFPS), but it may be used as an alternative
-     * to the "retry" button when fingerprint is used with other modalities.
-     *
-     * @param failedModalities the set of modalities that have failed
-     * @return true if a retry was initiated as a result of this event
-     */
-    public boolean onPointerDown(Set<Integer> failedModalities) {
-        return false;
-    }
-
-    /**
      * Show a help message to the user.
      *
      * @param modality sensor modality
@@ -730,7 +761,8 @@
     /**
      * Kicks off the animation process and invokes the callback.
      */
-    void startTransitionToCredentialUI() {
+    @Override
+    public void startTransitionToCredentialUI() {
         updateSize(AuthDialog.SIZE_LARGE);
         mCallback.onAction(Callback.ACTION_USE_DEVICE_CREDENTIAL);
     }
@@ -868,6 +900,25 @@
         }
 
         mLayoutParams = onMeasureInternal(width, height);
+
+        final Insets navBarInsets = Utils.getNavbarInsets(mContext);
+        final int navBarHeight = navBarInsets.bottom;
+        final int navBarWidth;
+        if (mPanelController.getPosition() == AuthPanelController.POSITION_LEFT) {
+            navBarWidth = navBarInsets.left;
+        } else if (mPanelController.getPosition() == AuthPanelController.POSITION_RIGHT) {
+            navBarWidth = navBarInsets.right;
+        } else {
+            navBarWidth = 0;
+        }
+
+        // The actual auth dialog w/h should include navigation bar size.
+        if (navBarWidth != 0 || navBarHeight != 0) {
+            mLayoutParams = new AuthDialog.LayoutParams(
+                    mLayoutParams.mMediumWidth + navBarWidth,
+                    mLayoutParams.mMediumHeight + navBarInsets.bottom);
+        }
+
         setMeasuredDimension(mLayoutParams.mMediumWidth, mLayoutParams.mMediumHeight);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricViewAdapter.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricViewAdapter.kt
new file mode 100644
index 0000000..631511c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricViewAdapter.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics
+
+import android.hardware.biometrics.BiometricAuthenticator
+import android.os.Bundle
+import android.view.View
+
+/** TODO(b/251476085): Temporary interface while legacy biometric prompt is around. */
+@Deprecated("temporary adapter while migrating biometric prompt - do not expand")
+interface AuthBiometricViewAdapter {
+    val legacyIconController: AuthIconController?
+
+    fun onDialogAnimatedIn(fingerprintWasStarted: Boolean)
+
+    fun onAuthenticationSucceeded(@BiometricAuthenticator.Modality modality: Int)
+
+    fun onAuthenticationFailed(
+        @BiometricAuthenticator.Modality modality: Int,
+        failureReason: String
+    )
+
+    fun onError(@BiometricAuthenticator.Modality modality: Int, error: String)
+
+    fun onHelp(@BiometricAuthenticator.Modality modality: Int, help: String)
+
+    fun startTransitionToCredentialUI()
+
+    fun requestLayout()
+
+    fun onSaveState(bundle: Bundle?)
+
+    fun restoreState(bundle: Bundle?)
+
+    fun onOrientationChanged()
+
+    fun cancelAnimation()
+
+    fun isCoex(): Boolean
+
+    fun asView(): View
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index ce85124..49ac264 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -16,14 +16,13 @@
 
 package com.android.systemui.biometrics;
 
-import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_DEFAULT;
-import static android.hardware.biometrics.BiometricManager.BiometricMultiSensorMode;
+import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
 import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_BIOMETRIC_PROMPT_TRANSITION;
 
 import android.animation.Animator;
-import android.annotation.DurationMillisLong;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -65,12 +64,19 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.R;
 import com.android.systemui.biometrics.AuthController.ScaleFactorProvider;
-import com.android.systemui.biometrics.domain.interactor.BiometricPromptCredentialInteractor;
+import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor;
+import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor;
+import com.android.systemui.biometrics.domain.model.BiometricModalities;
+import com.android.systemui.biometrics.ui.BiometricPromptLayout;
 import com.android.systemui.biometrics.ui.CredentialView;
 import com.android.systemui.biometrics.ui.binder.AuthBiometricFingerprintViewBinder;
+import com.android.systemui.biometrics.ui.binder.BiometricViewBinder;
 import com.android.systemui.biometrics.ui.viewmodel.AuthBiometricFingerprintViewModel;
 import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel;
+import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel;
 import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 
@@ -83,6 +89,8 @@
 
 import javax.inject.Provider;
 
+import kotlinx.coroutines.CoroutineScope;
+
 /**
  * Top level container/controller for the BiometricPrompt UI.
  */
@@ -125,16 +133,20 @@
     private final WakefulnessLifecycle mWakefulnessLifecycle;
     private final AuthDialogPanelInteractionDetector mPanelInteractionDetector;
     private final InteractionJankMonitor mInteractionJankMonitor;
+    private final CoroutineScope mApplicationCoroutineScope;
 
     // TODO: these should be migrated out once ready
-    private final Provider<BiometricPromptCredentialInteractor> mBiometricPromptInteractor;
+    private final Provider<PromptCredentialInteractor> mPromptCredentialInteractor;
     private final Provider<AuthBiometricFingerprintViewModel>
             mAuthBiometricFingerprintViewModelProvider;
+    private final @NonNull Provider<PromptSelectorInteractor> mPromptSelectorInteractorProvider;
+    // TODO(b/251476085): these should be migrated out of the view
     private final Provider<CredentialViewModel> mCredentialViewModelProvider;
+    private final PromptViewModel mPromptViewModel;
 
     @VisibleForTesting final BiometricCallback mBiometricCallback;
 
-    @Nullable private AuthBiometricView mBiometricView;
+    @Nullable private AuthBiometricViewAdapter mBiometricView;
     @Nullable private View mCredentialView;
     private final AuthPanelController mPanelController;
     private final FrameLayout mFrameLayout;
@@ -153,7 +165,8 @@
     // HAT received from LockSettingsService when credential is verified.
     @Nullable private byte[] mCredentialAttestation;
 
-    @VisibleForTesting
+    // TODO(b/251476085): remove when legacy prompt is replaced
+    @Deprecated
     static class Config {
         Context mContext;
         AuthDialogCallback mCallback;
@@ -166,96 +179,9 @@
         long mOperationId;
         long mRequestId = -1;
         boolean mSkipAnimation = false;
-        @BiometricMultiSensorMode int mMultiSensorConfig = BIOMETRIC_MULTI_SENSOR_DEFAULT;
         ScaleFactorProvider mScaleProvider;
     }
 
-    public static class Builder {
-        Config mConfig;
-
-        public Builder(Context context) {
-            mConfig = new Config();
-            mConfig.mContext = context;
-        }
-
-        public Builder setCallback(AuthDialogCallback callback) {
-            mConfig.mCallback = callback;
-            return this;
-        }
-
-        public Builder setPromptInfo(PromptInfo promptInfo) {
-            mConfig.mPromptInfo = promptInfo;
-            return this;
-        }
-
-        public Builder setRequireConfirmation(boolean requireConfirmation) {
-            mConfig.mRequireConfirmation = requireConfirmation;
-            return this;
-        }
-
-        public Builder setUserId(int userId) {
-            mConfig.mUserId = userId;
-            return this;
-        }
-
-        public Builder setOpPackageName(String opPackageName) {
-            mConfig.mOpPackageName = opPackageName;
-            return this;
-        }
-
-        public Builder setSkipIntro(boolean skip) {
-            mConfig.mSkipIntro = skip;
-            return this;
-        }
-
-        public Builder setOperationId(@DurationMillisLong long operationId) {
-            mConfig.mOperationId = operationId;
-            return this;
-        }
-
-        /** Unique id for this request. */
-        public Builder setRequestId(long requestId) {
-            mConfig.mRequestId = requestId;
-            return this;
-        }
-
-        @VisibleForTesting
-        public Builder setSkipAnimationDuration(boolean skip) {
-            mConfig.mSkipAnimation = skip;
-            return this;
-        }
-
-        /** The multi-sensor mode. */
-        public Builder setMultiSensorConfig(@BiometricMultiSensorMode int multiSensorConfig) {
-            mConfig.mMultiSensorConfig = multiSensorConfig;
-            return this;
-        }
-
-        public Builder setScaleFactorProvider(ScaleFactorProvider scaleProvider) {
-            mConfig.mScaleProvider = scaleProvider;
-            return this;
-        }
-
-        public AuthContainerView build(@Background DelayableExecutor bgExecutor, int[] sensorIds,
-                @Nullable List<FingerprintSensorPropertiesInternal> fpProps,
-                @Nullable List<FaceSensorPropertiesInternal> faceProps,
-                @NonNull WakefulnessLifecycle wakefulnessLifecycle,
-                @NonNull AuthDialogPanelInteractionDetector panelInteractionDetector,
-                @NonNull UserManager userManager,
-                @NonNull LockPatternUtils lockPatternUtils,
-                @NonNull InteractionJankMonitor jankMonitor,
-                @NonNull Provider<BiometricPromptCredentialInteractor> biometricPromptInteractor,
-                @NonNull Provider<AuthBiometricFingerprintViewModel>
-                        authBiometricFingerprintViewModelProvider,
-                @NonNull Provider<CredentialViewModel> credentialViewModelProvider) {
-            mConfig.mSensorIds = sensorIds;
-            return new AuthContainerView(mConfig, fpProps, faceProps, wakefulnessLifecycle,
-                    panelInteractionDetector, userManager, lockPatternUtils, jankMonitor,
-                    biometricPromptInteractor, authBiometricFingerprintViewModelProvider,
-                    credentialViewModelProvider, new Handler(Looper.getMainLooper()), bgExecutor);
-        }
-    }
-
     @VisibleForTesting
     final class BiometricCallback implements AuthBiometricView.Callback {
         @Override
@@ -284,6 +210,9 @@
                         addCredentialView(false /* animatePanel */, true /* animateContents */);
                     }, mConfig.mSkipAnimation ? 0 : AuthDialog.ANIMATE_CREDENTIAL_START_DELAY_MS);
                     break;
+                case AuthBiometricView.Callback.ACTION_START_DELAYED_FINGERPRINT_SENSOR:
+                    mConfig.mCallback.onStartFingerprintNow(getRequestId());
+                    break;
                 default:
                     Log.e(TAG, "Unhandled action: " + action);
             }
@@ -335,8 +264,10 @@
         alertDialog.show();
     }
 
-    @VisibleForTesting
-    AuthContainerView(Config config,
+    // TODO(b/251476085): remove Config and further decompose these properties out of view classes
+    AuthContainerView(@NonNull Config config,
+            @NonNull FeatureFlags featureFlags,
+            @NonNull CoroutineScope applicationCoroutineScope,
             @Nullable List<FingerprintSensorPropertiesInternal> fpProps,
             @Nullable List<FaceSensorPropertiesInternal> faceProps,
             @NonNull WakefulnessLifecycle wakefulnessLifecycle,
@@ -344,9 +275,36 @@
             @NonNull UserManager userManager,
             @NonNull LockPatternUtils lockPatternUtils,
             @NonNull InteractionJankMonitor jankMonitor,
-            @NonNull Provider<BiometricPromptCredentialInteractor> biometricPromptInteractor,
             @NonNull Provider<AuthBiometricFingerprintViewModel>
                     authBiometricFingerprintViewModelProvider,
+            @NonNull Provider<PromptCredentialInteractor> promptCredentialInteractor,
+            @NonNull Provider<PromptSelectorInteractor> promptSelectorInteractor,
+            @NonNull PromptViewModel promptViewModel,
+            @NonNull Provider<CredentialViewModel> credentialViewModelProvider,
+            @NonNull @Background DelayableExecutor bgExecutor) {
+        this(config, featureFlags, applicationCoroutineScope, fpProps, faceProps,
+                wakefulnessLifecycle, panelInteractionDetector, userManager, lockPatternUtils,
+                jankMonitor, authBiometricFingerprintViewModelProvider, promptSelectorInteractor,
+                promptCredentialInteractor, promptViewModel, credentialViewModelProvider,
+                new Handler(Looper.getMainLooper()), bgExecutor);
+    }
+
+    @VisibleForTesting
+    AuthContainerView(@NonNull Config config,
+            @NonNull FeatureFlags featureFlags,
+            @NonNull CoroutineScope applicationCoroutineScope,
+            @Nullable List<FingerprintSensorPropertiesInternal> fpProps,
+            @Nullable List<FaceSensorPropertiesInternal> faceProps,
+            @NonNull WakefulnessLifecycle wakefulnessLifecycle,
+            @NonNull AuthDialogPanelInteractionDetector panelInteractionDetector,
+            @NonNull UserManager userManager,
+            @NonNull LockPatternUtils lockPatternUtils,
+            @NonNull InteractionJankMonitor jankMonitor,
+            @NonNull Provider<AuthBiometricFingerprintViewModel>
+                    authBiometricFingerprintViewModelProvider,
+            @NonNull Provider<PromptSelectorInteractor> promptSelectorInteractorProvider,
+            @NonNull Provider<PromptCredentialInteractor> credentialInteractor,
+            @NonNull PromptViewModel promptViewModel,
             @NonNull Provider<CredentialViewModel> credentialViewModelProvider,
             @NonNull Handler mainHandler,
             @NonNull @Background DelayableExecutor bgExecutor) {
@@ -359,6 +317,7 @@
         mWindowManager = mContext.getSystemService(WindowManager.class);
         mWakefulnessLifecycle = wakefulnessLifecycle;
         mPanelInteractionDetector = panelInteractionDetector;
+        mApplicationCoroutineScope = applicationCoroutineScope;
 
         mTranslationY = getResources()
                 .getDimension(R.dimen.biometric_dialog_animation_translation_offset);
@@ -375,10 +334,70 @@
         mPanelController = new AuthPanelController(mContext, mPanelView);
         mBackgroundExecutor = bgExecutor;
         mInteractionJankMonitor = jankMonitor;
-        mBiometricPromptInteractor = biometricPromptInteractor;
+        mPromptCredentialInteractor = credentialInteractor;
         mAuthBiometricFingerprintViewModelProvider = authBiometricFingerprintViewModelProvider;
+        mPromptSelectorInteractorProvider = promptSelectorInteractorProvider;
         mCredentialViewModelProvider = credentialViewModelProvider;
+        mPromptViewModel = promptViewModel;
 
+        if (featureFlags.isEnabled(Flags.BIOMETRIC_BP_STRONG)) {
+            showPrompt(config, layoutInflater, promptViewModel,
+                    Utils.findFirstSensorProperties(fpProps, mConfig.mSensorIds),
+                    Utils.findFirstSensorProperties(faceProps, mConfig.mSensorIds));
+        } else {
+            showLegacyPrompt(config, layoutInflater, fpProps, faceProps);
+        }
+
+        // TODO: De-dupe the logic with AuthCredentialPasswordView
+        setOnKeyListener((v, keyCode, event) -> {
+            if (keyCode != KeyEvent.KEYCODE_BACK) {
+                return false;
+            }
+            if (event.getAction() == KeyEvent.ACTION_UP) {
+                onBackInvoked();
+            }
+            return true;
+        });
+
+        setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
+        setFocusableInTouchMode(true);
+        requestFocus();
+    }
+
+    private void showPrompt(@NonNull Config config, @NonNull LayoutInflater layoutInflater,
+            @NonNull PromptViewModel viewModel,
+            @Nullable FingerprintSensorPropertiesInternal fpProps,
+            @Nullable FaceSensorPropertiesInternal faceProps) {
+        if (Utils.isBiometricAllowed(config.mPromptInfo)) {
+            mPromptSelectorInteractorProvider.get().useBiometricsForAuthentication(
+                    config.mPromptInfo,
+                    config.mRequireConfirmation,
+                    config.mUserId,
+                    config.mOperationId,
+                    new BiometricModalities(fpProps, faceProps));
+
+            final BiometricPromptLayout view = (BiometricPromptLayout) layoutInflater.inflate(
+                    R.layout.biometric_prompt_layout, null, false);
+            mBiometricView = BiometricViewBinder.bind(view, viewModel, mPanelController,
+                    // TODO(b/201510778): This uses the wrong timeout in some cases
+                    getJankListener(view, TRANSIT, AuthDialog.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS),
+                    mBackgroundView, mBiometricCallback, mApplicationCoroutineScope);
+
+            // TODO(b/251476085): migrate these dependencies
+            if (fpProps != null && fpProps.isAnyUdfpsType()) {
+                view.setUdfpsAdapter(new UdfpsDialogMeasureAdapter(view, fpProps),
+                        config.mScaleProvider);
+            }
+        } else {
+            mPromptSelectorInteractorProvider.get().resetPrompt();
+        }
+    }
+
+    // TODO(b/251476085): remove entirely
+    private void showLegacyPrompt(@NonNull Config config, @NonNull LayoutInflater layoutInflater,
+            @Nullable List<FingerprintSensorPropertiesInternal> fpProps,
+            @Nullable List<FaceSensorPropertiesInternal> faceProps
+    ) {
         // Inflate biometric view only if necessary.
         if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) {
             final FingerprintSensorPropertiesInternal fpProperties =
@@ -420,31 +439,18 @@
 
         // init view before showing
         if (mBiometricView != null) {
-            mBiometricView.setRequireConfirmation(mConfig.mRequireConfirmation);
-            mBiometricView.setPanelController(mPanelController);
-            mBiometricView.setPromptInfo(mConfig.mPromptInfo);
-            mBiometricView.setCallback(mBiometricCallback);
-            mBiometricView.setBackgroundView(mBackgroundView);
-            mBiometricView.setUserId(mConfig.mUserId);
-            mBiometricView.setEffectiveUserId(mEffectiveUserId);
-            mBiometricView.setJankListener(getJankListener(mBiometricView, TRANSIT,
+            final AuthBiometricView view = (AuthBiometricView) mBiometricView;
+            view.setRequireConfirmation(mConfig.mRequireConfirmation);
+            view.setPanelController(mPanelController);
+            view.setPromptInfo(mConfig.mPromptInfo);
+            view.setCallback(mBiometricCallback);
+            view.setBackgroundView(mBackgroundView);
+            view.setUserId(mConfig.mUserId);
+            view.setEffectiveUserId(mEffectiveUserId);
+            // TODO(b/201510778): This uses the wrong timeout in some cases (remove w/ above)
+            view.setJankListener(getJankListener(view, TRANSIT,
                     AuthDialog.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS));
         }
-
-        // TODO: De-dupe the logic with AuthCredentialPasswordView
-        setOnKeyListener((v, keyCode, event) -> {
-            if (keyCode != KeyEvent.KEYCODE_BACK) {
-                return false;
-            }
-            if (event.getAction() == KeyEvent.ACTION_UP) {
-                onBackInvoked();
-            }
-            return true;
-        });
-
-        setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
-        setFocusableInTouchMode(true);
-        requestFocus();
     }
 
     private void onBackInvoked() {
@@ -494,7 +500,7 @@
         mBackgroundView.setOnClickListener(null);
         mBackgroundView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
 
-        mBiometricPromptInteractor.get().useCredentialsForAuthentication(
+        mPromptSelectorInteractorProvider.get().useCredentialsForAuthentication(
                 mConfig.mPromptInfo, credentialType, mConfig.mUserId, mConfig.mOperationId);
         final CredentialViewModel vm = mCredentialViewModelProvider.get();
         vm.setAnimateContents(animateContents);
@@ -512,6 +518,9 @@
     @Override
     public void onOrientationChanged() {
         maybeUpdatePositionForUdfps(true /* invalidate */);
+        if (mBiometricView != null) {
+            mBiometricView.onOrientationChanged();
+        }
     }
 
     @Override
@@ -523,7 +532,7 @@
                 () -> animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED));
 
         if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) {
-            mBiometricScrollView.addView(mBiometricView);
+            mBiometricScrollView.addView(mBiometricView.asView());
         } else if (Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo)) {
             addCredentialView(true /* animatePanel */, false /* animateContents */);
         } else {
@@ -597,9 +606,13 @@
     }
 
     private static boolean shouldUpdatePositionForUdfps(@NonNull View view) {
+        // TODO(b/251476085): legacy view (delete when removed)
         if (view instanceof AuthBiometricFingerprintView) {
             return ((AuthBiometricFingerprintView) view).isUdfps();
         }
+        if (view instanceof BiometricPromptLayout) {
+            return ((BiometricPromptLayout) view).isUdfps();
+        }
 
         return false;
     }
@@ -609,7 +622,7 @@
         if (display == null) {
             return false;
         }
-        if (!shouldUpdatePositionForUdfps(mBiometricView)) {
+        if (mBiometricView == null || !shouldUpdatePositionForUdfps(mBiometricView.asView())) {
             return false;
         }
 
@@ -622,12 +635,12 @@
 
             case Surface.ROTATION_90:
                 mPanelController.setPosition(AuthPanelController.POSITION_RIGHT);
-                setScrollViewGravity(Gravity.CENTER_VERTICAL | Gravity.RIGHT);
+                setScrollViewGravity(Gravity.BOTTOM | Gravity.RIGHT);
                 break;
 
             case Surface.ROTATION_270:
                 mPanelController.setPosition(AuthPanelController.POSITION_LEFT);
-                setScrollViewGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
+                setScrollViewGravity(Gravity.BOTTOM | Gravity.LEFT);
                 break;
 
             case Surface.ROTATION_180:
@@ -685,7 +698,7 @@
                 mCredentialView.animate().cancel();
             }
             mPanelView.animate().cancel();
-            mBiometricView.animate().cancel();
+            mBiometricView.cancelAnimation();
             animate().cancel();
             onDialogAnimatedIn();
         }
@@ -746,8 +759,9 @@
     @Override
     public void onPointerDown() {
         if (mBiometricView != null) {
-            if (mBiometricView.onPointerDown(mFailedModalities)) {
+            if (mFailedModalities.contains(TYPE_FACE)) {
                 Log.d(TAG, "retrying failed modalities (pointer down)");
+                mFailedModalities.remove(TYPE_FACE);
                 mBiometricCallback.onAction(AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN);
             }
         } else {
@@ -881,11 +895,17 @@
         }
         mContainerState = STATE_SHOWING;
         if (mBiometricView != null) {
-            mConfig.mCallback.onDialogAnimatedIn(getRequestId());
-            mBiometricView.onDialogAnimatedIn();
+            final boolean delayFingerprint = mBiometricView.isCoex() && !mConfig.mRequireConfirmation;
+            mConfig.mCallback.onDialogAnimatedIn(getRequestId(), !delayFingerprint);
+            mBiometricView.onDialogAnimatedIn(!delayFingerprint);
         }
     }
 
+    @Override
+    public PromptViewModel getViewModel() {
+        return mPromptViewModel;
+    }
+
     @VisibleForTesting
     static WindowManager.LayoutParams getLayoutParams(IBinder windowToken, CharSequence title) {
         final int windowFlags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
@@ -899,7 +919,9 @@
                 windowFlags,
                 PixelFormat.TRANSLUCENT);
         lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
-        lp.setFitInsetsTypes(lp.getFitInsetsTypes() & ~WindowInsets.Type.ime());
+        lp.setFitInsetsTypes(lp.getFitInsetsTypes() & ~WindowInsets.Type.ime()
+                & ~WindowInsets.Type.systemBars());
+        lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
         lp.setTitle("BiometricPrompt");
         lp.accessibilityTitle = title;
         lp.dimAmount = BACKGROUND_DIM_AMOUNT;
@@ -916,26 +938,5 @@
         if (mConfig != null) {
             pw.println("    config.sensorIds exist=" + (mConfig.mSensorIds != null));
         }
-        final AuthBiometricView biometricView = mBiometricView;
-        pw.println("    scrollView=" + findViewById(R.id.biometric_scrollview));
-        pw.println("      biometricView=" + biometricView);
-        if (biometricView != null) {
-            int[] ids = {
-                    R.id.title,
-                    R.id.subtitle,
-                    R.id.description,
-                    R.id.biometric_icon_frame,
-                    R.id.biometric_icon,
-                    R.id.indicator,
-                    R.id.button_bar,
-                    R.id.button_negative,
-                    R.id.button_use_credential,
-                    R.id.button_confirm,
-                    R.id.button_try_again
-            };
-            for (final int id: ids) {
-                pw.println("        " + biometricView.findViewById(id));
-            }
-        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index fd9cee0..57f1928 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -37,7 +37,6 @@
 import android.hardware.biometrics.BiometricAuthenticator.Modality;
 import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricManager.Authenticators;
-import android.hardware.biometrics.BiometricManager.BiometricMultiSensorMode;
 import android.hardware.biometrics.BiometricPrompt;
 import android.hardware.biometrics.BiometricStateListener;
 import android.hardware.biometrics.IBiometricContextListener;
@@ -71,14 +70,18 @@
 import com.android.settingslib.udfps.UdfpsOverlayParams;
 import com.android.settingslib.udfps.UdfpsUtils;
 import com.android.systemui.CoreStartable;
-import com.android.systemui.biometrics.domain.interactor.BiometricPromptCredentialInteractor;
 import com.android.systemui.biometrics.domain.interactor.LogContextInteractor;
+import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor;
+import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor;
 import com.android.systemui.biometrics.ui.viewmodel.AuthBiometricFingerprintViewModel;
 import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel;
+import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Application;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.doze.DozeReceiver;
+import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.keyguard.data.repository.BiometricType;
 import com.android.systemui.statusbar.CommandQueue;
@@ -86,8 +89,6 @@
 import com.android.systemui.util.concurrency.DelayableExecutor;
 import com.android.systemui.util.concurrency.Execution;
 
-import kotlin.Unit;
-
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -101,6 +102,9 @@
 import javax.inject.Inject;
 import javax.inject.Provider;
 
+import kotlin.Unit;
+import kotlinx.coroutines.CoroutineScope;
+
 /**
  * Receives messages sent from {@link com.android.server.biometrics.BiometricService} and shows the
  * appropriate biometric UI (e.g. BiometricDialogView).
@@ -109,7 +113,7 @@
  * {@link com.android.keyguard.KeyguardUpdateMonitor}
  */
 @SysUISingleton
-public class AuthController implements CoreStartable,  CommandQueue.Callbacks,
+public class AuthController implements CoreStartable, CommandQueue.Callbacks,
         AuthDialogCallback, DozeReceiver {
 
     private static final String TAG = "AuthController";
@@ -118,6 +122,7 @@
 
     private final Handler mHandler;
     private final Context mContext;
+    private final FeatureFlags mFeatureFlags;
     private final Execution mExecution;
     private final CommandQueue mCommandQueue;
     private final ActivityTaskManager mActivityTaskManager;
@@ -125,13 +130,15 @@
     @Nullable private final FaceManager mFaceManager;
     private final Provider<UdfpsController> mUdfpsControllerFactory;
     private final Provider<SideFpsController> mSidefpsControllerFactory;
+    private final CoroutineScope mApplicationCoroutineScope;
 
     // TODO: these should be migrated out once ready
-    @NonNull private final Provider<BiometricPromptCredentialInteractor> mBiometricPromptInteractor;
-
     @NonNull private final Provider<AuthBiometricFingerprintViewModel>
             mAuthBiometricFingerprintViewModelProvider;
+    @NonNull private final Provider<PromptCredentialInteractor> mPromptCredentialInteractor;
+    @NonNull private final Provider<PromptSelectorInteractor> mPromptSelectorInteractor;
     @NonNull private final Provider<CredentialViewModel> mCredentialViewModelProvider;
+    @NonNull private final Provider<PromptViewModel> mPromptViewModelProvider;
     @NonNull private final LogContextInteractor mLogContextInteractor;
 
     private final Display mDisplay;
@@ -461,7 +468,7 @@
     }
 
     @Override
-    public void onDialogAnimatedIn(long requestId) {
+    public void onDialogAnimatedIn(long requestId, boolean startFingerprintNow) {
         final IBiometricSysuiReceiver receiver = getCurrentReceiver(requestId);
         if (receiver == null) {
             Log.w(TAG, "Skip onDialogAnimatedIn");
@@ -469,7 +476,22 @@
         }
 
         try {
-            receiver.onDialogAnimatedIn();
+            receiver.onDialogAnimatedIn(startFingerprintNow);
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException when sending onDialogAnimatedIn", e);
+        }
+    }
+
+    @Override
+    public void onStartFingerprintNow(long requestId) {
+        final IBiometricSysuiReceiver receiver = getCurrentReceiver(requestId);
+        if (receiver == null) {
+            Log.e(TAG, "onStartUdfpsNow: Receiver is null");
+            return;
+        }
+
+        try {
+            receiver.onStartFingerprintNow();
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException when sending onDialogAnimatedIn", e);
         }
@@ -728,6 +750,8 @@
     }
     @Inject
     public AuthController(Context context,
+            @NonNull FeatureFlags featureFlags,
+            @Application CoroutineScope applicationCoroutineScope,
             Execution execution,
             CommandQueue commandQueue,
             ActivityTaskManager activityTaskManager,
@@ -743,16 +767,19 @@
             @NonNull LockPatternUtils lockPatternUtils,
             @NonNull UdfpsLogger udfpsLogger,
             @NonNull LogContextInteractor logContextInteractor,
-            @NonNull Provider<BiometricPromptCredentialInteractor> biometricPromptInteractor,
             @NonNull Provider<AuthBiometricFingerprintViewModel>
                     authBiometricFingerprintViewModelProvider,
+            @NonNull Provider<PromptCredentialInteractor> promptCredentialInteractorProvider,
+            @NonNull Provider<PromptSelectorInteractor> promptSelectorInteractorProvider,
             @NonNull Provider<CredentialViewModel> credentialViewModelProvider,
+            @NonNull Provider<PromptViewModel> promptViewModelProvider,
             @NonNull InteractionJankMonitor jankMonitor,
             @Main Handler handler,
             @Background DelayableExecutor bgExecutor,
             @NonNull VibratorHelper vibrator,
             @NonNull UdfpsUtils udfpsUtils) {
         mContext = context;
+        mFeatureFlags = featureFlags;
         mExecution = execution;
         mUserManager = userManager;
         mLockPatternUtils = lockPatternUtils;
@@ -773,10 +800,13 @@
         mFaceEnrolledForUser = new SparseBooleanArray();
         mVibratorHelper = vibrator;
         mUdfpsUtils = udfpsUtils;
+        mApplicationCoroutineScope = applicationCoroutineScope;
 
         mLogContextInteractor = logContextInteractor;
-        mBiometricPromptInteractor = biometricPromptInteractor;
         mAuthBiometricFingerprintViewModelProvider = authBiometricFingerprintViewModelProvider;
+        mPromptSelectorInteractor = promptSelectorInteractorProvider;
+        mPromptCredentialInteractor = promptCredentialInteractorProvider;
+        mPromptViewModelProvider = promptViewModelProvider;
         mCredentialViewModelProvider = credentialViewModelProvider;
 
         mOrientationListener = new BiometricDisplayListener(
@@ -913,8 +943,7 @@
     @Override
     public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver,
             int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
-            int userId, long operationId, String opPackageName, long requestId,
-            @BiometricMultiSensorMode int multiSensorConfig) {
+            int userId, long operationId, String opPackageName, long requestId) {
         @Authenticators.Types final int authenticators = promptInfo.getAuthenticators();
 
         if (DEBUG) {
@@ -927,8 +956,7 @@
                     + ", credentialAllowed: " + credentialAllowed
                     + ", requireConfirmation: " + requireConfirmation
                     + ", operationId: " + operationId
-                    + ", requestId: " + requestId
-                    + ", multiSensorConfig: " + multiSensorConfig);
+                    + ", requestId: " + requestId);
         }
         SomeArgs args = SomeArgs.obtain();
         args.arg1 = promptInfo;
@@ -940,7 +968,6 @@
         args.arg6 = opPackageName;
         args.argl1 = operationId;
         args.argl2 = requestId;
-        args.argi2 = multiSensorConfig;
 
         boolean skipAnimation = false;
         if (mCurrentDialog != null) {
@@ -948,7 +975,7 @@
             skipAnimation = true;
         }
 
-        showDialog(args, skipAnimation, null /* savedState */);
+        showDialog(args, skipAnimation, null /* savedState */, mPromptViewModelProvider.get());
     }
 
     /**
@@ -1171,7 +1198,8 @@
         return mFpEnrolledForUser.getOrDefault(userId, false);
     }
 
-    private void showDialog(SomeArgs args, boolean skipAnimation, Bundle savedState) {
+    private void showDialog(SomeArgs args, boolean skipAnimation, Bundle savedState,
+            @Nullable PromptViewModel viewModel) {
         mCurrentDialogArgs = args;
 
         final PromptInfo promptInfo = (PromptInfo) args.arg1;
@@ -1182,7 +1210,6 @@
         final String opPackageName = (String) args.arg6;
         final long operationId = args.argl1;
         final long requestId = args.argl2;
-        @BiometricMultiSensorMode final int multiSensorConfig = args.argi2;
 
         // Create a new dialog but do not replace the current one yet.
         final AuthDialog newDialog = buildDialog(
@@ -1195,11 +1222,11 @@
                 skipAnimation,
                 operationId,
                 requestId,
-                multiSensorConfig,
                 mWakefulnessLifecycle,
                 mPanelInteractionDetector,
                 mUserManager,
-                mLockPatternUtils);
+                mLockPatternUtils,
+                viewModel);
 
         if (newDialog == null) {
             Log.e(TAG, "Unsupported type configuration");
@@ -1253,6 +1280,7 @@
 
         // Save the state of the current dialog (buttons showing, etc)
         if (mCurrentDialog != null) {
+            final PromptViewModel viewModel = mCurrentDialog.getViewModel();
             final Bundle savedState = new Bundle();
             mCurrentDialog.onSaveState(savedState);
             mCurrentDialog.dismissWithoutCallback(false /* animate */);
@@ -1271,7 +1299,7 @@
                     promptInfo.setAuthenticators(Authenticators.DEVICE_CREDENTIAL);
                 }
 
-                showDialog(mCurrentDialogArgs, true /* skipAnimation */, savedState);
+                showDialog(mCurrentDialogArgs, true /* skipAnimation */, savedState, viewModel);
             }
         }
     }
@@ -1286,26 +1314,28 @@
     protected AuthDialog buildDialog(@Background DelayableExecutor bgExecutor,
             PromptInfo promptInfo, boolean requireConfirmation, int userId, int[] sensorIds,
             String opPackageName, boolean skipIntro, long operationId, long requestId,
-            @BiometricMultiSensorMode int multiSensorConfig,
             @NonNull WakefulnessLifecycle wakefulnessLifecycle,
             @NonNull AuthDialogPanelInteractionDetector panelInteractionDetector,
             @NonNull UserManager userManager,
-            @NonNull LockPatternUtils lockPatternUtils) {
-        return new AuthContainerView.Builder(mContext)
-                .setCallback(this)
-                .setPromptInfo(promptInfo)
-                .setRequireConfirmation(requireConfirmation)
-                .setUserId(userId)
-                .setOpPackageName(opPackageName)
-                .setSkipIntro(skipIntro)
-                .setOperationId(operationId)
-                .setRequestId(requestId)
-                .setMultiSensorConfig(multiSensorConfig)
-                .setScaleFactorProvider(() -> getScaleFactor())
-                .build(bgExecutor, sensorIds, mFpProps, mFaceProps, wakefulnessLifecycle,
-                        panelInteractionDetector, userManager, lockPatternUtils,
-                        mInteractionJankMonitor, mBiometricPromptInteractor,
-                        mAuthBiometricFingerprintViewModelProvider, mCredentialViewModelProvider);
+            @NonNull LockPatternUtils lockPatternUtils,
+            @NonNull PromptViewModel viewModel) {
+        final AuthContainerView.Config config = new AuthContainerView.Config();
+        config.mContext = mContext;
+        config.mCallback = this;
+        config.mPromptInfo = promptInfo;
+        config.mRequireConfirmation = requireConfirmation;
+        config.mUserId = userId;
+        config.mOpPackageName = opPackageName;
+        config.mSkipIntro = skipIntro;
+        config.mOperationId = operationId;
+        config.mRequestId = requestId;
+        config.mSensorIds = sensorIds;
+        config.mScaleProvider = this::getScaleFactor;
+        return new AuthContainerView(config, mFeatureFlags, mApplicationCoroutineScope, mFpProps, mFaceProps,
+                wakefulnessLifecycle, panelInteractionDetector, userManager, lockPatternUtils,
+                mInteractionJankMonitor, mAuthBiometricFingerprintViewModelProvider,
+                mPromptCredentialInteractor, mPromptSelectorInteractor, viewModel,
+                mCredentialViewModelProvider, bgExecutor);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
index 51f39b3..b6eabfa 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
@@ -24,13 +24,17 @@
 import android.view.WindowManager;
 
 import com.android.systemui.Dumpable;
+import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
 /**
  * Interface for the biometric dialog UI.
+ *
+ * TODO(b/251476085): remove along with legacy controller once flag is removed
  */
+@Deprecated
 public interface AuthDialog extends Dumpable {
 
     String KEY_CONTAINER_GOING_AWAY = "container_going_away";
@@ -70,10 +74,10 @@
      * {@link AuthPanelController}.
      */
     class LayoutParams {
-        final int mMediumHeight;
-        final int mMediumWidth;
+        public final int mMediumHeight;
+        public final int mMediumWidth;
 
-        LayoutParams(int mediumWidth, int mediumHeight) {
+        public LayoutParams(int mediumWidth, int mediumHeight) {
             mMediumWidth = mediumWidth;
             mMediumHeight = mediumHeight;
         }
@@ -172,4 +176,6 @@
      * must remain fixed on the physical sensor location.
      */
     void onOrientationChanged();
+
+    PromptViewModel getViewModel();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
index bbe461a..9a21940 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
@@ -70,5 +70,10 @@
     /**
      * Notifies when the dialog has finished animating.
      */
-    void onDialogAnimatedIn(long requestId);
+    void onDialogAnimatedIn(long requestId, boolean startFingerprintNow);
+
+    /**
+     * Notifies that the fingerprint sensor should be started now.
+     */
+    void onStartFingerprintNow(long requestId);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt
index 8edccf166..b72801d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt
@@ -21,7 +21,7 @@
     fun enable(onPanelInteraction: Runnable) {
         if (action == null) {
             action = Action(onPanelInteraction)
-            shadeExpansionStateManager.addShadeExpansionListener(this::onPanelExpansionChanged)
+            shadeExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged)
         } else {
             Log.e(TAG, "Already enabled")
         }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthIconController.kt
index f5f4640..f56bb88 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthIconController.kt
@@ -84,9 +84,6 @@
         }
     }
 
-    /** If the icon should act as a "retry" button in the [currentState]. */
-    fun iconTapSendsRetryWhen(@BiometricState currentState: Int): Boolean = false
-
     /** Call during [updateState] if the controller is not [deactivated]. */
     abstract fun updateIcon(@BiometricState lastState: Int, @BiometricState newState: Int)
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
index 5c616f0..acdde34 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
@@ -20,6 +20,7 @@
 import android.animation.ValueAnimator;
 import android.annotation.IntDef;
 import android.content.Context;
+import android.graphics.Insets;
 import android.graphics.Outline;
 import android.util.Log;
 import android.view.View;
@@ -64,13 +65,12 @@
     @Override
     public void getOutline(View view, Outline outline) {
         final int left = getLeftBound(mPosition);
-        final int right = left + mContentWidth;
+        final int right = getRightBound(mPosition, left);
 
         // If the content fits in the container, shrink the height to wrap it. Otherwise, expand to
         // fill the display (minus the margin), since the content is scrollable.
         final int top = getTopBound(mPosition);
-        final int bottom = Math.min(top + mContentHeight, mContainerHeight - mMargin);
-
+        final int bottom = getBottomBound(top);
         outline.setRoundRect(left, top, right, bottom, mCornerRadius);
     }
 
@@ -79,6 +79,10 @@
             case POSITION_BOTTOM:
                 return (mContainerWidth - mContentWidth) / 2;
             case POSITION_LEFT:
+                if (!mUseFullScreen) {
+                    final Insets navBarInsets = Utils.getNavbarInsets(mContext);
+                    return mMargin + navBarInsets.left;
+                }
                 return mMargin;
             case POSITION_RIGHT:
                 return mContainerWidth - mContentWidth - mMargin;
@@ -88,17 +92,29 @@
         }
     }
 
-    private int getTopBound(@Position int position) {
-        switch (position) {
-            case POSITION_BOTTOM:
-                return Math.max(mContainerHeight - mContentHeight - mMargin, mMargin);
-            case POSITION_LEFT:
-            case POSITION_RIGHT:
-                return Math.max((mContainerHeight - mContentHeight) / 2, mMargin);
-            default:
-                Log.e(TAG, "Unrecognized position: " + position);
-                return getTopBound(POSITION_BOTTOM);
+    private int getRightBound(@Position int position, int left) {
+        if (!mUseFullScreen) {
+            final Insets navBarInsets = Utils.getNavbarInsets(mContext);
+            if (position == POSITION_RIGHT) {
+                return left + mContentWidth - navBarInsets.right;
+            } else if (position == POSITION_LEFT) {
+                return left + mContentWidth - navBarInsets.left;
+            }
         }
+        return left + mContentWidth;
+    }
+
+    private int getBottomBound(int top) {
+        if (!mUseFullScreen) {
+            final Insets navBarInsets = Utils.getNavbarInsets(mContext);
+            return Math.min(top + mContentHeight - navBarInsets.bottom,
+                    mContainerHeight - mMargin - navBarInsets.bottom);
+        }
+        return Math.min(top + mContentHeight, mContainerHeight - mMargin);
+    }
+
+    private int getTopBound(@Position int position) {
+        return Math.max(mContainerHeight - mContentHeight - mMargin, mMargin);
     }
 
     public void setContainerDimensions(int containerWidth, int containerHeight) {
@@ -113,6 +129,10 @@
         mPosition = position;
     }
 
+    public @Position int getPosition() {
+        return mPosition;
+    }
+
     public void setUseFullScreen(boolean fullScreen) {
         mUseFullScreen = fullScreen;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
index 962140f..0782537 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
@@ -436,25 +436,36 @@
     fun update() {
         val isKeyguard = reason == REASON_AUTH_KEYGUARD
         if (isKeyguard) {
-            val color = context.getColor(R.color.numpad_key_color_secondary) // match bouncer color
+            val color =
+                com.android.settingslib.Utils.getColorAttrDefaultColor(
+                    context,
+                    com.android.internal.R.attr.materialColorPrimaryFixed
+                )
+            val outerRimColor =
+                com.android.settingslib.Utils.getColorAttrDefaultColor(
+                    context,
+                    com.android.internal.R.attr.materialColorPrimaryFixedDim
+                )
             val chevronFill =
                 com.android.settingslib.Utils.getColorAttrDefaultColor(
                     context,
-                    android.R.attr.textColorPrimaryInverse
+                    com.android.internal.R.attr.materialColorOnPrimaryFixed
                 )
-            for (key in listOf(".blue600", ".blue400")) {
-                addValueCallback(KeyPath(key, "**"), LottieProperty.COLOR_FILTER) {
-                    PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP)
-                }
+            addValueCallback(KeyPath(".blue600", "**"), LottieProperty.COLOR_FILTER) {
+                PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP)
+            }
+            addValueCallback(KeyPath(".blue400", "**"), LottieProperty.COLOR_FILTER) {
+                PorterDuffColorFilter(outerRimColor, PorterDuff.Mode.SRC_ATOP)
             }
             addValueCallback(KeyPath(".black", "**"), LottieProperty.COLOR_FILTER) {
                 PorterDuffColorFilter(chevronFill, PorterDuff.Mode.SRC_ATOP)
             }
-        } else if (!isDarkMode(context)) {
-            addValueCallback(KeyPath(".black", "**"), LottieProperty.COLOR_FILTER) {
-                PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP)
+        } else {
+            if (!isDarkMode(context)) {
+                addValueCallback(KeyPath(".black", "**"), LottieProperty.COLOR_FILTER) {
+                    PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP)
+                }
             }
-        } else if (isDarkMode(context)) {
             for (key in listOf(".blue600", ".blue400")) {
                 addValueCallback(KeyPath(key, "**"), LottieProperty.COLOR_FILTER) {
                     PorterDuffColorFilter(
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
index 1dbafc6..94b5fb2 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
@@ -108,7 +108,9 @@
     }
 
     override fun onViewAttached() {
-        shadeExpansionStateManager.addExpansionListener(shadeExpansionListener)
+        val currentState =
+            shadeExpansionStateManager.addExpansionListener(shadeExpansionListener)
+        shadeExpansionListener.onPanelExpansionChanged(currentState)
         dialogManager.registerListener(dialogListener)
         dumpManager.registerDumpable(dumpTag, this)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 3add8c8..cabe900 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -115,7 +115,7 @@
     private var overlayTouchListener: TouchExplorationStateChangeListener? = null
 
     private val coreLayoutParams = WindowManager.LayoutParams(
-        WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
+        WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
         0 /* flags set in computeLayoutParams() */,
         PixelFormat.TRANSLUCENT
     ).apply {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
index 43745bf..16dc42a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java
@@ -63,7 +63,7 @@
     }
 
     @NonNull
-    AuthDialog.LayoutParams onMeasureInternal(
+    public AuthDialog.LayoutParams onMeasureInternal(
             int width, int height, @NonNull AuthDialog.LayoutParams layoutParams,
             float scaleFactor) {
 
@@ -86,7 +86,7 @@
      * too cleanly support this case. So, let's have the onLayout code translate the sensor location
      * instead.
      */
-    int getBottomSpacerHeight() {
+    public int getBottomSpacerHeight() {
         return mBottomSpacerHeight;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt
index 5c88c9e..3fc3e82 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt
@@ -290,7 +290,8 @@
         qsExpansion = keyguardViewManager.qsExpansion
         keyguardViewManager.addCallback(statusBarKeyguardViewManagerCallback)
         configurationController.addCallback(configurationListener)
-        shadeExpansionStateManager.addExpansionListener(shadeExpansionListener)
+        val currentState = shadeExpansionStateManager.addExpansionListener(shadeExpansionListener)
+        shadeExpansionListener.onPanelExpansionChanged(currentState)
         updateScaleFactor()
         view.updatePadding()
         updateAlpha()
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacy.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacy.java
index 63f0e9d..a2840fc 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacy.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacy.java
@@ -176,9 +176,9 @@
         }
 
         mTextColorPrimary = Utils.getColorAttrDefaultColor(mContext,
-            android.R.attr.textColorPrimary);
+                com.android.internal.R.attr.materialColorOnSurface);
         final int backgroundColor = Utils.getColorAttrDefaultColor(getContext(),
-                com.android.internal.R.attr.colorSurface);
+                com.android.internal.R.attr.materialColorSurfaceContainerHigh);
         mBgProtection.setImageTintList(ColorStateList.valueOf(backgroundColor));
         mLockScreenFp.invalidate(); // updated with a valueCallback
     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
index d0d6f4c..b538085 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
@@ -26,13 +26,16 @@
 import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
 import android.content.Context
 import android.content.pm.PackageManager
+import android.graphics.Insets
 import android.hardware.biometrics.BiometricManager.Authenticators
 import android.hardware.biometrics.PromptInfo
 import android.hardware.biometrics.SensorPropertiesInternal
 import android.os.UserManager
 import android.util.DisplayMetrics
 import android.view.ViewGroup
+import android.view.WindowInsets
 import android.view.WindowManager
+import android.view.WindowMetrics
 import android.view.accessibility.AccessibilityEvent
 import android.view.accessibility.AccessibilityManager
 import com.android.internal.widget.LockPatternUtils
@@ -114,6 +117,14 @@
         return hasPermission && "android" == clientPackage
     }
 
+    @JvmStatic
+    fun getNavbarInsets(context: Context): Insets {
+        val windowManager: WindowManager? = context.getSystemService(WindowManager::class.java)
+        val windowMetrics: WindowMetrics? = windowManager?.maximumWindowMetrics
+        return windowMetrics?.windowInsets?.getInsets(WindowInsets.Type.navigationBars())
+            ?: Insets.NONE
+    }
+
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(CREDENTIAL_PIN, CREDENTIAL_PATTERN, CREDENTIAL_PASSWORD)
     internal annotation class CredentialType
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
index 096d941..ddf1457 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
@@ -31,6 +31,8 @@
 import com.android.systemui.biometrics.domain.interactor.LogContextInteractorImpl
 import com.android.systemui.biometrics.domain.interactor.SideFpsOverlayInteractor
 import com.android.systemui.biometrics.domain.interactor.SideFpsOverlayInteractorImpl
+import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor
+import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractorImpl
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.util.concurrency.ThreadFactory
 import dagger.Binds
@@ -57,6 +59,11 @@
 
     @Binds
     @SysUISingleton
+    fun providesPromptSelectorInteractor(impl: PromptSelectorInteractorImpl):
+            PromptSelectorInteractor
+
+    @Binds
+    @SysUISingleton
     fun providesCredentialInteractor(impl: CredentialInteractorImpl): CredentialInteractor
 
     @Binds
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt
index 92a13cf..b4dc272 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt
@@ -2,7 +2,7 @@
 
 import android.hardware.biometrics.PromptInfo
 import com.android.systemui.biometrics.AuthController
-import com.android.systemui.biometrics.data.model.PromptKind
+import com.android.systemui.biometrics.shared.model.PromptKind
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
@@ -35,12 +35,20 @@
     /** The kind of credential to use (biometric, pin, pattern, etc.). */
     val kind: StateFlow<PromptKind>
 
+    /**
+     * If explicit confirmation is required.
+     *
+     * Note: overlaps/conflicts with [PromptInfo.isConfirmationRequested], which needs clean up.
+     */
+    val isConfirmationRequired: StateFlow<Boolean>
+
     /** Update the prompt configuration, which should be set before [isShowing]. */
     fun setPrompt(
         promptInfo: PromptInfo,
         userId: Int,
         gatekeeperChallenge: Long?,
-        kind: PromptKind = PromptKind.ANY_BIOMETRIC,
+        kind: PromptKind,
+        requireConfirmation: Boolean = false,
     )
 
     /** Unset the prompt info. */
@@ -74,29 +82,35 @@
     private val _userId: MutableStateFlow<Int?> = MutableStateFlow(null)
     override val userId = _userId.asStateFlow()
 
-    private val _kind: MutableStateFlow<PromptKind> = MutableStateFlow(PromptKind.ANY_BIOMETRIC)
+    private val _kind: MutableStateFlow<PromptKind> = MutableStateFlow(PromptKind.Biometric())
     override val kind = _kind.asStateFlow()
 
+    private val _isConfirmationRequired: MutableStateFlow<Boolean> = MutableStateFlow(false)
+    override val isConfirmationRequired = _isConfirmationRequired.asStateFlow()
+
     override fun setPrompt(
         promptInfo: PromptInfo,
         userId: Int,
         gatekeeperChallenge: Long?,
         kind: PromptKind,
+        requireConfirmation: Boolean,
     ) {
         _kind.value = kind
         _userId.value = userId
         _challenge.value = gatekeeperChallenge
         _promptInfo.value = promptInfo
+        _isConfirmationRequired.value = requireConfirmation
     }
 
     override fun unsetPrompt() {
         _promptInfo.value = null
         _userId.value = null
         _challenge.value = null
-        _kind.value = PromptKind.ANY_BIOMETRIC
+        _kind.value = PromptKind.Biometric()
+        _isConfirmationRequired.value = false
     }
 
     companion object {
-        private const val TAG = "BiometricPromptRepository"
+        private const val TAG = "PromptRepositoryImpl"
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt
index 6362c2f..d92c217 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt
@@ -1,14 +1,30 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.android.systemui.biometrics.domain.interactor
 
 import android.hardware.biometrics.PromptInfo
 import com.android.internal.widget.LockPatternView
 import com.android.internal.widget.LockscreenCredential
 import com.android.systemui.biometrics.Utils
-import com.android.systemui.biometrics.data.model.PromptKind
 import com.android.systemui.biometrics.data.repository.PromptRepository
 import com.android.systemui.biometrics.domain.model.BiometricOperationInfo
 import com.android.systemui.biometrics.domain.model.BiometricPromptRequest
 import com.android.systemui.biometrics.domain.model.BiometricUserInfo
+import com.android.systemui.biometrics.shared.model.PromptKind
 import com.android.systemui.dagger.qualifiers.Background
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
@@ -24,8 +40,16 @@
 /**
  * Business logic for BiometricPrompt's CredentialViews, which primarily includes checking a users
  * PIN, pattern, or password credential instead of a biometric.
+ *
+ * This is used to cache the calling app's options that were given to the underlying authenticate
+ * APIs and should be set before any UI is shown to the user.
+ *
+ * There can be at most one request active at a given time. Use [resetPrompt] when no request is
+ * active to clear the cache.
+ *
+ * Views that use any biometric should use [PromptSelectorInteractor] instead.
  */
-class BiometricPromptCredentialInteractor
+class PromptCredentialInteractor
 @Inject
 constructor(
     @Background private val bgDispatcher: CoroutineDispatcher,
@@ -36,7 +60,7 @@
     val isShowing: Flow<Boolean> = biometricPromptRepository.isShowing
 
     /** Metadata about the current credential prompt, including app-supplied preferences. */
-    val prompt: Flow<BiometricPromptRequest?> =
+    val prompt: Flow<BiometricPromptRequest.Credential?> =
         combine(
                 biometricPromptRepository.promptInfo,
                 biometricPromptRepository.challenge,
@@ -48,20 +72,20 @@
                 }
 
                 when (kind) {
-                    PromptKind.PIN ->
+                    PromptKind.Pin ->
                         BiometricPromptRequest.Credential.Pin(
                             info = promptInfo,
                             userInfo = userInfo(userId),
                             operationInfo = operationInfo(challenge)
                         )
-                    PromptKind.PATTERN ->
+                    PromptKind.Pattern ->
                         BiometricPromptRequest.Credential.Pattern(
                             info = promptInfo,
                             userInfo = userInfo(userId),
                             operationInfo = operationInfo(challenge),
                             stealthMode = credentialInteractor.isStealthModeActive(userId)
                         )
-                    PromptKind.PASSWORD ->
+                    PromptKind.Password ->
                         BiometricPromptRequest.Credential.Password(
                             info = promptInfo,
                             userInfo = userInfo(userId),
@@ -182,8 +206,8 @@
 /** Convert a [Utils.CredentialType] to the corresponding [PromptKind]. */
 private fun @receiver:Utils.CredentialType Int.asBiometricPromptCredential(): PromptKind =
     when (this) {
-        Utils.CREDENTIAL_PIN -> PromptKind.PIN
-        Utils.CREDENTIAL_PASSWORD -> PromptKind.PASSWORD
-        Utils.CREDENTIAL_PATTERN -> PromptKind.PATTERN
-        else -> PromptKind.ANY_BIOMETRIC
+        Utils.CREDENTIAL_PIN -> PromptKind.Pin
+        Utils.CREDENTIAL_PASSWORD -> PromptKind.Password
+        Utils.CREDENTIAL_PATTERN -> PromptKind.Pattern
+        else -> PromptKind.Biometric()
     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
new file mode 100644
index 0000000..e6e07f9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.domain.interactor
+
+import android.hardware.biometrics.PromptInfo
+import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.biometrics.Utils
+import com.android.systemui.biometrics.Utils.getCredentialType
+import com.android.systemui.biometrics.Utils.isDeviceCredentialAllowed
+import com.android.systemui.biometrics.data.repository.PromptRepository
+import com.android.systemui.biometrics.domain.model.BiometricModalities
+import com.android.systemui.biometrics.domain.model.BiometricOperationInfo
+import com.android.systemui.biometrics.domain.model.BiometricPromptRequest
+import com.android.systemui.biometrics.domain.model.BiometricUserInfo
+import com.android.systemui.biometrics.shared.model.PromptKind
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+
+/**
+ * Business logic for BiometricPrompt's biometric view variants (face, fingerprint, coex, etc.).
+ *
+ * This is used to cache the calling app's options that were given to the underlying authenticate
+ * APIs and should be set before any UI is shown to the user.
+ *
+ * There can be at most one request active at a given time. Use [resetPrompt] when no request is
+ * active to clear the cache.
+ *
+ * Views that use credential fallback should use [PromptCredentialInteractor] instead.
+ */
+interface PromptSelectorInteractor {
+
+    /** Static metadata about the current prompt. */
+    val prompt: Flow<BiometricPromptRequest.Biometric?>
+
+    /** If using a credential is allowed. */
+    val isCredentialAllowed: Flow<Boolean>
+
+    /**
+     * The kind of credential the user may use as a fallback or [PromptKind.Biometric] if unknown or
+     * not [isCredentialAllowed].
+     */
+    val credentialKind: Flow<PromptKind>
+
+    /** If the API caller requested explicit confirmation after successful authentication. */
+    val isConfirmationRequested: Flow<Boolean>
+
+    /** Use biometrics for authentication. */
+    fun useBiometricsForAuthentication(
+        promptInfo: PromptInfo,
+        requireConfirmation: Boolean,
+        userId: Int,
+        challenge: Long,
+        modalities: BiometricModalities,
+    )
+
+    /** Use credential-based authentication instead of biometrics. */
+    fun useCredentialsForAuthentication(
+        promptInfo: PromptInfo,
+        @Utils.CredentialType kind: Int,
+        userId: Int,
+        challenge: Long,
+    )
+
+    /** Unset the current authentication request. */
+    fun resetPrompt()
+}
+
+@SysUISingleton
+class PromptSelectorInteractorImpl
+@Inject
+constructor(
+    private val promptRepository: PromptRepository,
+    lockPatternUtils: LockPatternUtils,
+) : PromptSelectorInteractor {
+
+    override val prompt: Flow<BiometricPromptRequest.Biometric?> =
+        combine(
+            promptRepository.promptInfo,
+            promptRepository.challenge,
+            promptRepository.userId,
+            promptRepository.kind
+        ) { promptInfo, challenge, userId, kind ->
+            if (promptInfo == null || userId == null || challenge == null) {
+                return@combine null
+            }
+
+            when (kind) {
+                is PromptKind.Biometric ->
+                    BiometricPromptRequest.Biometric(
+                        info = promptInfo,
+                        userInfo = BiometricUserInfo(userId = userId),
+                        operationInfo = BiometricOperationInfo(gatekeeperChallenge = challenge),
+                        modalities = kind.activeModalities,
+                    )
+                else -> null
+            }
+        }
+
+    override val isConfirmationRequested: Flow<Boolean> =
+        promptRepository.promptInfo
+            .map { info -> info?.isConfirmationRequested ?: false }
+            .distinctUntilChanged()
+
+    override val isCredentialAllowed: Flow<Boolean> =
+        promptRepository.promptInfo
+            .map { info -> if (info != null) isDeviceCredentialAllowed(info) else false }
+            .distinctUntilChanged()
+
+    override val credentialKind: Flow<PromptKind> =
+        combine(prompt, isCredentialAllowed) { prompt, isAllowed ->
+            if (prompt != null && isAllowed) {
+                when (
+                    getCredentialType(lockPatternUtils, prompt.userInfo.deviceCredentialOwnerId)
+                ) {
+                    Utils.CREDENTIAL_PIN -> PromptKind.Pin
+                    Utils.CREDENTIAL_PASSWORD -> PromptKind.Password
+                    Utils.CREDENTIAL_PATTERN -> PromptKind.Pattern
+                    else -> PromptKind.Biometric()
+                }
+            } else {
+                PromptKind.Biometric()
+            }
+        }
+
+    override fun useBiometricsForAuthentication(
+        promptInfo: PromptInfo,
+        requireConfirmation: Boolean,
+        userId: Int,
+        challenge: Long,
+        modalities: BiometricModalities
+    ) {
+        promptRepository.setPrompt(
+            promptInfo = promptInfo,
+            userId = userId,
+            gatekeeperChallenge = challenge,
+            kind = PromptKind.Biometric(modalities),
+            requireConfirmation = requireConfirmation,
+        )
+    }
+
+    override fun useCredentialsForAuthentication(
+        promptInfo: PromptInfo,
+        @Utils.CredentialType kind: Int,
+        userId: Int,
+        challenge: Long,
+    ) {
+        promptRepository.setPrompt(
+            promptInfo = promptInfo,
+            userId = userId,
+            gatekeeperChallenge = challenge,
+            kind = kind.asBiometricPromptCredential(),
+        )
+    }
+
+    override fun resetPrompt() {
+        promptRepository.unsetPrompt()
+    }
+}
+
+// TODO(b/251476085): remove along with Utils.CredentialType
+/** Convert a [Utils.CredentialType] to the corresponding [PromptKind]. */
+private fun @receiver:Utils.CredentialType Int.asBiometricPromptCredential(): PromptKind =
+    when (this) {
+        Utils.CREDENTIAL_PIN -> PromptKind.Pin
+        Utils.CREDENTIAL_PASSWORD -> PromptKind.Password
+        Utils.CREDENTIAL_PATTERN -> PromptKind.Pattern
+        else -> PromptKind.Biometric()
+    }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricModalities.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricModalities.kt
new file mode 100644
index 0000000..274f58a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricModalities.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.domain.model
+
+import android.hardware.biometrics.SensorProperties
+import android.hardware.face.FaceSensorPropertiesInternal
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+
+/** The available modalities for an operation. */
+data class BiometricModalities(
+    val fingerprintProperties: FingerprintSensorPropertiesInternal? = null,
+    val faceProperties: FaceSensorPropertiesInternal? = null,
+) {
+    /** If there are no available modalities. */
+    val isEmpty: Boolean
+        get() = !hasFingerprint && !hasFace
+
+    /** If fingerprint authentication is available (and [fingerprintProperties] is non-null). */
+    val hasFingerprint: Boolean
+        get() = fingerprintProperties != null
+
+    /** If fingerprint authentication is available (and [faceProperties] is non-null). */
+    val hasFace: Boolean
+        get() = faceProperties != null
+
+    /** If only face authentication is enabled. */
+    val hasFaceOnly: Boolean
+        get() = hasFace && !hasFingerprint
+
+    /** If only fingerprint authentication is enabled. */
+    val hasFingerprintOnly: Boolean
+        get() = hasFingerprint && !hasFace
+
+    /** If face & fingerprint authentication is enabled (coex). */
+    val hasFaceAndFingerprint: Boolean
+        get() = hasFingerprint && hasFace
+
+    /** If [hasFace] and it is configured as a STRONG class 3 biometric. */
+    val isFaceStrong: Boolean
+        get() = faceProperties?.sensorStrength == SensorProperties.STRENGTH_STRONG
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricModality.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricModality.kt
new file mode 100644
index 0000000..3197c09
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricModality.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.domain.model
+
+import android.hardware.biometrics.BiometricAuthenticator
+
+/** Shadows [BiometricAuthenticator.Modality] for Kotlin use within SysUI. */
+enum class BiometricModality {
+    None,
+    Fingerprint,
+    Face,
+}
+
+/** Convert a framework [BiometricAuthenticator.Modality] to a SysUI [BiometricModality]. */
+@BiometricAuthenticator.Modality
+fun Int.asBiometricModality(): BiometricModality =
+    when (this) {
+        BiometricAuthenticator.TYPE_FINGERPRINT -> BiometricModality.Fingerprint
+        BiometricAuthenticator.TYPE_FACE -> BiometricModality.Face
+        else -> BiometricModality.None
+    }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt
index 5ee0381..75de47d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequest.kt
@@ -21,6 +21,7 @@
         info: PromptInfo,
         userInfo: BiometricUserInfo,
         operationInfo: BiometricOperationInfo,
+        val modalities: BiometricModalities,
     ) :
         BiometricPromptRequest(
             title = info.title?.toString() ?: "",
@@ -28,7 +29,9 @@
             description = info.description?.toString() ?: "",
             userInfo = userInfo,
             operationInfo = operationInfo
-        )
+        ) {
+        val negativeButtonText: String = info.negativeButtonText?.toString() ?: ""
+    }
 
     /** Prompt using a credential (pin, pattern, password). */
     sealed class Credential(
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/model/PromptKind.kt b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/PromptKind.kt
similarity index 64%
rename from packages/SystemUI/src/com/android/systemui/biometrics/data/model/PromptKind.kt
rename to packages/SystemUI/src/com/android/systemui/biometrics/shared/model/PromptKind.kt
index e82646f..416fc64 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/data/model/PromptKind.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/PromptKind.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,15 +14,19 @@
  * limitations under the License.
  */
 
-package com.android.systemui.biometrics.data.model
+package com.android.systemui.biometrics.shared.model
 
 import com.android.systemui.biometrics.Utils
+import com.android.systemui.biometrics.domain.model.BiometricModalities
 
 // TODO(b/251476085): this should eventually replace Utils.CredentialType
 /** Credential options for biometric prompt. Shadows [Utils.CredentialType]. */
-enum class PromptKind {
-    ANY_BIOMETRIC,
-    PIN,
-    PATTERN,
-    PASSWORD,
+sealed interface PromptKind {
+    data class Biometric(
+        val activeModalities: BiometricModalities = BiometricModalities(),
+    ) : PromptKind
+
+    object Pin : PromptKind
+    object Pattern : PromptKind
+    object Password : PromptKind
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricPromptLayout.java b/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricPromptLayout.java
new file mode 100644
index 0000000..fb246cd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricPromptLayout.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.ui;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.Insets;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.view.WindowInsets;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.biometrics.AuthBiometricFingerprintIconController;
+import com.android.systemui.biometrics.AuthController;
+import com.android.systemui.biometrics.AuthDialog;
+import com.android.systemui.biometrics.UdfpsDialogMeasureAdapter;
+
+import kotlin.Pair;
+
+/**
+ * Contains the Biometric views (title, subtitle, icon, buttons, etc.).
+ *
+ * TODO(b/251476085): get the udfps junk out of here, at a minimum. Likely can be replaced with a
+ * normal LinearLayout.
+ */
+public class BiometricPromptLayout extends LinearLayout {
+
+    private static final String TAG = "BiometricPromptLayout";
+
+    @NonNull
+    private final WindowManager mWindowManager;
+    @Nullable
+    private AuthController.ScaleFactorProvider mScaleFactorProvider;
+    @Nullable
+    private UdfpsDialogMeasureAdapter mUdfpsAdapter;
+
+    private final boolean mUseCustomBpSize;
+    private final int mCustomBpWidth;
+    private final int mCustomBpHeight;
+
+    public BiometricPromptLayout(Context context) {
+        this(context, null);
+    }
+
+    public BiometricPromptLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        mWindowManager = context.getSystemService(WindowManager.class);
+
+        mUseCustomBpSize = getResources().getBoolean(R.bool.use_custom_bp_size);
+        mCustomBpWidth = getResources().getDimensionPixelSize(R.dimen.biometric_dialog_width);
+        mCustomBpHeight = getResources().getDimensionPixelSize(R.dimen.biometric_dialog_height);
+    }
+
+    @Deprecated
+    public void setUdfpsAdapter(@NonNull UdfpsDialogMeasureAdapter adapter,
+            @NonNull AuthController.ScaleFactorProvider scaleProvider) {
+        mUdfpsAdapter = adapter;
+        mScaleFactorProvider = scaleProvider != null ? scaleProvider : () -> 1.0f;
+    }
+
+    @Deprecated
+    public boolean isUdfps() {
+        return mUdfpsAdapter != null;
+    }
+
+    @Deprecated
+    public void updateFingerprintAffordanceSize(
+            @NonNull AuthBiometricFingerprintIconController iconController) {
+        if (mUdfpsAdapter != null) {
+            final int sensorDiameter = mUdfpsAdapter.getSensorDiameter(
+                    mScaleFactorProvider.provide());
+            iconController.setIconLayoutParamSize(new Pair(sensorDiameter, sensorDiameter));
+        }
+    }
+
+    @NonNull
+    private AuthDialog.LayoutParams onMeasureInternal(int width, int height) {
+        int totalHeight = 0;
+        final int numChildren = getChildCount();
+        for (int i = 0; i < numChildren; i++) {
+            final View child = getChildAt(i);
+
+            if (child.getId() == R.id.space_above_icon
+                    || child.getId() == R.id.space_below_icon
+                    || child.getId() == R.id.button_bar) {
+                child.measure(
+                        MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+                        MeasureSpec.makeMeasureSpec(child.getLayoutParams().height,
+                                MeasureSpec.EXACTLY));
+            } else if (child.getId() == R.id.biometric_icon_frame) {
+                final View iconView = findViewById(R.id.biometric_icon);
+                child.measure(
+                        MeasureSpec.makeMeasureSpec(iconView.getLayoutParams().width,
+                                MeasureSpec.EXACTLY),
+                        MeasureSpec.makeMeasureSpec(iconView.getLayoutParams().height,
+                                MeasureSpec.EXACTLY));
+            } else if (child.getId() == R.id.biometric_icon) {
+                child.measure(
+                        MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
+                        MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
+            } else {
+                child.measure(
+                        MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+                        MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
+            }
+
+            if (child.getVisibility() != View.GONE) {
+                totalHeight += child.getMeasuredHeight();
+            }
+        }
+
+        final AuthDialog.LayoutParams params = new AuthDialog.LayoutParams(width, totalHeight);
+        if (mUdfpsAdapter != null) {
+            return mUdfpsAdapter.onMeasureInternal(width, height, params,
+                    (mScaleFactorProvider != null) ? mScaleFactorProvider.provide() : 1.0f);
+        } else {
+            return params;
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int width = MeasureSpec.getSize(widthMeasureSpec);
+        int height = MeasureSpec.getSize(heightMeasureSpec);
+
+        if (mUseCustomBpSize) {
+            width = mCustomBpWidth;
+            height = mCustomBpHeight;
+        } else {
+            width = Math.min(width, height);
+        }
+
+        // add nav bar insets since the parent AuthContainerView
+        // uses LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+        final Insets insets = mWindowManager.getMaximumWindowMetrics().getWindowInsets()
+                .getInsets(WindowInsets.Type.navigationBars());
+        final AuthDialog.LayoutParams params = onMeasureInternal(width, height);
+        setMeasuredDimension(params.mMediumWidth + insets.left + insets.right,
+                params.mMediumHeight + insets.bottom);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+
+        if (mUdfpsAdapter != null) {
+            // Move the UDFPS icon and indicator text if necessary. This probably only needs to
+            // happen for devices where the UDFPS sensor is too low.
+            // TODO(b/201510778): Update this logic to support cases where the sensor or text
+            // overlap the button bar area.
+            final float bottomSpacerHeight = mUdfpsAdapter.getBottomSpacerHeight();
+            Log.w(TAG, "bottomSpacerHeight: " + bottomSpacerHeight);
+            if (bottomSpacerHeight < 0) {
+                final FrameLayout iconFrame = findViewById(R.id.biometric_icon_frame);
+                iconFrame.setTranslationY(-bottomSpacerHeight);
+                final TextView indicator = findViewById(R.id.indicator);
+                indicator.setTranslationY(-bottomSpacerHeight);
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
index ede62ac..a3f34ce 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/CredentialPasswordView.kt
@@ -68,15 +68,15 @@
         var inputTopBound: Int
         var headerRightBound = right
         var headerTopBounds = top
+        var headerBottomBounds = bottom
         val subTitleBottom: Int = if (subtitleView.isGone) titleView.bottom else subtitleView.bottom
         val descBottom = if (descriptionView.isGone) subTitleBottom else descriptionView.bottom
         if (resources.configuration.orientation == ORIENTATION_LANDSCAPE) {
             inputTopBound = (bottom - credentialInput.height) / 2
             inputLeftBound = (right - left) / 2
             headerRightBound = inputLeftBound
-            headerTopBounds -= iconView.bottom.coerceAtMost(bottomInset)
-
-            if (descriptionView.bottom > bottomInset) {
+            if (descriptionView.bottom > headerBottomBounds) {
+                headerTopBounds -= iconView.bottom.coerceAtMost(bottomInset)
                 credentialHeader.layout(left, headerTopBounds, headerRightBound, bottom)
             }
         } else {
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
new file mode 100644
index 0000000..8486c3f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -0,0 +1,622 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.ui.binder
+
+import android.animation.Animator
+import android.content.Context
+import android.hardware.biometrics.BiometricAuthenticator
+import android.hardware.biometrics.BiometricConstants
+import android.hardware.biometrics.BiometricPrompt
+import android.hardware.face.FaceManager
+import android.os.Bundle
+import android.text.method.ScrollingMovementMethod
+import android.util.Log
+import android.view.View
+import android.view.accessibility.AccessibilityManager
+import android.widget.Button
+import android.widget.TextView
+import androidx.lifecycle.DefaultLifecycleObserver
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import com.airbnb.lottie.LottieAnimationView
+import com.android.systemui.R
+import com.android.systemui.biometrics.AuthBiometricFaceIconController
+import com.android.systemui.biometrics.AuthBiometricFingerprintAndFaceIconController
+import com.android.systemui.biometrics.AuthBiometricFingerprintIconController
+import com.android.systemui.biometrics.AuthBiometricView
+import com.android.systemui.biometrics.AuthBiometricView.Callback
+import com.android.systemui.biometrics.AuthBiometricViewAdapter
+import com.android.systemui.biometrics.AuthIconController
+import com.android.systemui.biometrics.AuthPanelController
+import com.android.systemui.biometrics.Utils
+import com.android.systemui.biometrics.domain.model.BiometricModalities
+import com.android.systemui.biometrics.domain.model.BiometricModality
+import com.android.systemui.biometrics.domain.model.asBiometricModality
+import com.android.systemui.biometrics.shared.model.PromptKind
+import com.android.systemui.biometrics.ui.BiometricPromptLayout
+import com.android.systemui.biometrics.ui.viewmodel.FingerprintStartMode
+import com.android.systemui.biometrics.ui.viewmodel.PromptMessage
+import com.android.systemui.biometrics.ui.viewmodel.PromptSize
+import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel
+import com.android.systemui.lifecycle.repeatWhenAttached
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+private const val TAG = "BiometricViewBinder"
+
+/** Top-most view binder for BiometricPrompt views. */
+object BiometricViewBinder {
+
+    /** Binds a [BiometricPromptLayout] to a [PromptViewModel]. */
+    @JvmStatic
+    fun bind(
+        view: BiometricPromptLayout,
+        viewModel: PromptViewModel,
+        panelViewController: AuthPanelController,
+        jankListener: BiometricJankListener,
+        backgroundView: View,
+        legacyCallback: Callback,
+        applicationScope: CoroutineScope,
+    ): AuthBiometricViewAdapter {
+        val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!!
+        fun notifyAccessibilityChanged() {
+            Utils.notifyAccessibilityContentChanged(accessibilityManager, view)
+        }
+
+        val textColorError =
+            view.resources.getColor(R.color.biometric_dialog_error, view.context.theme)
+        val textColorHint =
+            view.resources.getColor(R.color.biometric_dialog_gray, view.context.theme)
+
+        val titleView = view.findViewById<TextView>(R.id.title)
+        val subtitleView = view.findViewById<TextView>(R.id.subtitle)
+        val descriptionView = view.findViewById<TextView>(R.id.description)
+
+        // set selected for marquee
+        titleView.isSelected = true
+        subtitleView.isSelected = true
+        descriptionView.movementMethod = ScrollingMovementMethod()
+
+        val iconViewOverlay = view.findViewById<LottieAnimationView>(R.id.biometric_icon_overlay)
+        val iconView = view.findViewById<LottieAnimationView>(R.id.biometric_icon)
+        val indicatorMessageView = view.findViewById<TextView>(R.id.indicator)
+
+        // Negative-side (left) buttons
+        val negativeButton = view.findViewById<Button>(R.id.button_negative)
+        val cancelButton = view.findViewById<Button>(R.id.button_cancel)
+        val credentialFallbackButton = view.findViewById<Button>(R.id.button_use_credential)
+
+        // Positive-side (right) buttons
+        val confirmationButton = view.findViewById<Button>(R.id.button_confirm)
+        val retryButton = view.findViewById<Button>(R.id.button_try_again)
+
+        // TODO(b/251476085): temporary workaround for the unsafe callbacks & legacy controllers
+        val adapter =
+            Spaghetti(
+                view = view,
+                viewModel = viewModel,
+                applicationContext = view.context.applicationContext,
+                applicationScope = applicationScope,
+            )
+
+        // bind to prompt
+        var boundSize = false
+        view.repeatWhenAttached {
+            // these do not change and need to be set before any size transitions
+            val modalities = viewModel.modalities.first()
+            titleView.text = viewModel.title.first()
+            descriptionView.text = viewModel.description.first()
+            subtitleView.text = viewModel.subtitle.first()
+
+            // set button listeners
+            negativeButton.setOnClickListener {
+                legacyCallback.onAction(Callback.ACTION_BUTTON_NEGATIVE)
+            }
+            cancelButton.setOnClickListener {
+                legacyCallback.onAction(Callback.ACTION_USER_CANCELED)
+            }
+            credentialFallbackButton.setOnClickListener {
+                viewModel.onSwitchToCredential()
+                legacyCallback.onAction(Callback.ACTION_USE_DEVICE_CREDENTIAL)
+            }
+            confirmationButton.setOnClickListener { viewModel.confirmAuthenticated() }
+            retryButton.setOnClickListener {
+                viewModel.showAuthenticating(isRetry = true)
+                legacyCallback.onAction(Callback.ACTION_BUTTON_TRY_AGAIN)
+            }
+
+            // TODO(b/251476085): migrate legacy icon controllers and remove
+            var legacyState: Int = viewModel.legacyState.value
+            val iconController =
+                modalities.asIconController(
+                    view.context,
+                    iconView,
+                    iconViewOverlay,
+                )
+            adapter.attach(this, iconController, modalities, legacyCallback)
+            if (iconController is AuthBiometricFingerprintIconController) {
+                view.updateFingerprintAffordanceSize(iconController)
+            }
+            if (iconController is HackyCoexIconController) {
+                iconController.faceMode = !viewModel.isConfirmationRequested.first()
+            }
+
+            // the icon controller must be created before this happens for the legacy
+            // sizing code in BiometricPromptLayout to work correctly. Simplify this
+            // when those are also migrated. (otherwise the icon size may not be set to
+            // a pixel value before the view is measured and WRAP_CONTENT will be incorrectly
+            // used as part of the measure spec)
+            if (!boundSize) {
+                boundSize = true
+                BiometricViewSizeBinder.bind(
+                    view = view,
+                    viewModel = viewModel,
+                    viewsToHideWhenSmall =
+                        listOf(
+                            titleView,
+                            subtitleView,
+                            descriptionView,
+                        ),
+                    viewsToFadeInOnSizeChange =
+                        listOf(
+                            titleView,
+                            subtitleView,
+                            descriptionView,
+                            indicatorMessageView,
+                            negativeButton,
+                            cancelButton,
+                            retryButton,
+                            confirmationButton,
+                            credentialFallbackButton,
+                        ),
+                    panelViewController = panelViewController,
+                    jankListener = jankListener,
+                )
+            }
+
+            // TODO(b/251476085): migrate legacy icon controllers and remove
+            // The fingerprint sensor is started by the legacy
+            // AuthContainerView#onDialogAnimatedIn in all cases but the implicit coex flow
+            // (delayed mode). In that case, start it on the first transition to delayed
+            // which will be triggered by any auth failure.
+            lifecycleScope.launch {
+                val oldMode = viewModel.fingerprintStartMode.first()
+                viewModel.fingerprintStartMode.collect { newMode ->
+                    // trigger sensor to start
+                    if (
+                        oldMode == FingerprintStartMode.Pending &&
+                            newMode == FingerprintStartMode.Delayed
+                    ) {
+                        legacyCallback.onAction(Callback.ACTION_START_DELAYED_FINGERPRINT_SENSOR)
+                    }
+
+                    if (newMode.isStarted) {
+                        // do wonky switch from implicit to explicit flow
+                        (iconController as? HackyCoexIconController)?.faceMode = false
+                        viewModel.showAuthenticating(
+                            modalities.asDefaultHelpMessage(view.context),
+                        )
+                    }
+                }
+            }
+
+            repeatOnLifecycle(Lifecycle.State.STARTED) {
+                // handle background clicks
+                launch {
+                    combine(viewModel.isAuthenticated, viewModel.size) { (authenticated, _), size ->
+                            when {
+                                authenticated -> false
+                                size == PromptSize.SMALL -> false
+                                size == PromptSize.LARGE -> false
+                                else -> true
+                            }
+                        }
+                        .collect { dismissOnClick ->
+                            backgroundView.setOnClickListener {
+                                if (dismissOnClick) {
+                                    legacyCallback.onAction(Callback.ACTION_USER_CANCELED)
+                                } else {
+                                    Log.w(TAG, "Ignoring background click")
+                                }
+                            }
+                        }
+                }
+
+                // set messages
+                launch {
+                    viewModel.isIndicatorMessageVisible.collect { show ->
+                        indicatorMessageView.visibility = show.asVisibleOrHidden()
+                    }
+                }
+
+                // configure & hide/disable buttons
+                launch {
+                    viewModel.credentialKind
+                        .map { kind ->
+                            when (kind) {
+                                PromptKind.Pin ->
+                                    view.resources.getString(R.string.biometric_dialog_use_pin)
+                                PromptKind.Password ->
+                                    view.resources.getString(R.string.biometric_dialog_use_password)
+                                PromptKind.Pattern ->
+                                    view.resources.getString(R.string.biometric_dialog_use_pattern)
+                                else -> ""
+                            }
+                        }
+                        .collect { credentialFallbackButton.text = it }
+                }
+                launch { viewModel.negativeButtonText.collect { negativeButton.text = it } }
+                launch {
+                    viewModel.isConfirmButtonVisible.collect { show ->
+                        confirmationButton.visibility = show.asVisibleOrGone()
+                    }
+                }
+                launch {
+                    viewModel.isCancelButtonVisible.collect { show ->
+                        cancelButton.visibility = show.asVisibleOrGone()
+                    }
+                }
+                launch {
+                    viewModel.isNegativeButtonVisible.collect { show ->
+                        negativeButton.visibility = show.asVisibleOrGone()
+                    }
+                }
+                launch {
+                    viewModel.isTryAgainButtonVisible.collect { show ->
+                        retryButton.visibility = show.asVisibleOrGone()
+                    }
+                }
+                launch {
+                    viewModel.isCredentialButtonVisible.collect { show ->
+                        credentialFallbackButton.visibility = show.asVisibleOrGone()
+                    }
+                }
+
+                // reuse the icon as a confirm button
+                launch {
+                    viewModel.isConfirmButtonVisible
+                        .map { isPending ->
+                            when {
+                                isPending && iconController.actsAsConfirmButton ->
+                                    View.OnClickListener { viewModel.confirmAuthenticated() }
+                                else -> null
+                            }
+                        }
+                        .collect { onClick ->
+                            iconViewOverlay.setOnClickListener(onClick)
+                            iconView.setOnClickListener(onClick)
+                        }
+                }
+
+                // TODO(b/251476085): remove w/ legacy icon controllers
+                // set icon affordance using legacy states
+                // like the old code, this causes animations to repeat on config changes :(
+                // but keep behavior for now as no one has complained...
+                launch {
+                    viewModel.legacyState.collect { newState ->
+                        iconController.updateState(legacyState, newState)
+                        legacyState = newState
+                    }
+                }
+
+                // not sure why this is here, but the legacy code did it probably needed?
+                launch {
+                    viewModel.isAuthenticating.collect { isAuthenticating ->
+                        if (isAuthenticating) {
+                            notifyAccessibilityChanged()
+                        }
+                    }
+                }
+
+                // dismiss prompt when authenticated and confirmed
+                launch {
+                    viewModel.isAuthenticated.collect { authState ->
+                        if (authState.isAuthenticatedAndConfirmed) {
+                            view.announceForAccessibility(
+                                view.resources.getString(R.string.biometric_dialog_authenticated)
+                            )
+                            notifyAccessibilityChanged()
+
+                            launch {
+                                delay(authState.delay)
+                                legacyCallback.onAction(Callback.ACTION_AUTHENTICATED)
+                            }
+                        }
+                    }
+                }
+
+                // show error & help messages
+                launch {
+                    viewModel.message.collect { promptMessage ->
+                        val isError = promptMessage is PromptMessage.Error
+
+                        indicatorMessageView.text = promptMessage.message
+                        indicatorMessageView.setTextColor(
+                            if (isError) textColorError else textColorHint
+                        )
+
+                        // select to enable marquee unless a screen reader is enabled
+                        // TODO(wenhuiy): this may have recently changed per UX - verify and remove
+                        indicatorMessageView.isSelected =
+                            !accessibilityManager.isEnabled ||
+                                !accessibilityManager.isTouchExplorationEnabled
+
+                        notifyAccessibilityChanged()
+                    }
+                }
+            }
+        }
+
+        return adapter
+    }
+}
+
+/**
+ * Adapter for legacy events. Remove once legacy controller can be replaced by flagged code.
+ *
+ * These events can be dispatched when the view is being recreated so they need to be delivered to
+ * the view model (which will be retained) via the application scope.
+ *
+ * Do not reference the [view] for anything other than [asView].
+ *
+ * TODO(b/251476085): remove after replacing AuthContainerView
+ */
+private class Spaghetti(
+    private val view: View,
+    private val viewModel: PromptViewModel,
+    private val applicationContext: Context,
+    private val applicationScope: CoroutineScope,
+) : AuthBiometricViewAdapter {
+
+    private var lifecycleScope: CoroutineScope? = null
+    private var modalities: BiometricModalities = BiometricModalities()
+    private var faceFailedAtLeastOnce = false
+    private var legacyCallback: Callback? = null
+
+    override var legacyIconController: AuthIconController? = null
+        private set
+
+    // hacky way to suppress lockout errors
+    private val lockoutErrorStrings =
+        listOf(
+                BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
+                BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT,
+            )
+            .map { FaceManager.getErrorString(applicationContext, it, 0 /* vendorCode */) }
+
+    fun attach(
+        lifecycleOwner: LifecycleOwner,
+        iconController: AuthIconController,
+        activeModalities: BiometricModalities,
+        callback: Callback,
+    ) {
+        modalities = activeModalities
+        legacyIconController = iconController
+        legacyCallback = callback
+
+        lifecycleOwner.lifecycle.addObserver(
+            object : DefaultLifecycleObserver {
+                override fun onCreate(owner: LifecycleOwner) {
+                    lifecycleScope = owner.lifecycleScope
+                    iconController.deactivated = false
+                }
+
+                override fun onDestroy(owner: LifecycleOwner) {
+                    lifecycleScope = null
+                    iconController.deactivated = true
+                }
+            }
+        )
+    }
+
+    override fun onDialogAnimatedIn(fingerprintWasStarted: Boolean) {
+        if (fingerprintWasStarted) {
+            viewModel.ensureFingerprintHasStarted(isDelayed = false)
+            viewModel.showAuthenticating(modalities.asDefaultHelpMessage(applicationContext))
+        } else {
+            viewModel.showAuthenticating()
+        }
+    }
+
+    override fun onAuthenticationSucceeded(@BiometricAuthenticator.Modality modality: Int) {
+        applicationScope.launch {
+            val authenticatedModality = modality.asBiometricModality()
+            val msgId = getHelpForSuccessfulAuthentication(authenticatedModality)
+            viewModel.showAuthenticated(
+                modality = authenticatedModality,
+                dismissAfterDelay = 500,
+                helpMessage = if (msgId != null) applicationContext.getString(msgId) else ""
+            )
+        }
+    }
+
+    private suspend fun getHelpForSuccessfulAuthentication(
+        authenticatedModality: BiometricModality,
+    ): Int? =
+        when {
+            // for coex, show a message when face succeeds after fingerprint has also started
+            modalities.hasFaceAndFingerprint &&
+                (viewModel.fingerprintStartMode.first() != FingerprintStartMode.Pending) &&
+                (authenticatedModality == BiometricModality.Face) ->
+                R.string.biometric_dialog_tap_confirm_with_face
+            else -> null
+        }
+
+    override fun onAuthenticationFailed(
+        @BiometricAuthenticator.Modality modality: Int,
+        failureReason: String,
+    ) {
+        val failedModality = modality.asBiometricModality()
+        viewModel.ensureFingerprintHasStarted(isDelayed = true)
+
+        applicationScope.launch {
+            val suppress =
+                modalities.hasFaceAndFingerprint &&
+                    (failedModality == BiometricModality.Face) &&
+                    faceFailedAtLeastOnce
+            if (failedModality == BiometricModality.Face) {
+                faceFailedAtLeastOnce = true
+            }
+
+            viewModel.showTemporaryError(
+                failureReason,
+                messageAfterError = modalities.asDefaultHelpMessage(applicationContext),
+                authenticateAfterError = modalities.hasFingerprint,
+                suppressIfErrorShowing = suppress,
+                failedModality = failedModality,
+            )
+        }
+    }
+
+    override fun onError(modality: Int, error: String) {
+        val errorModality = modality.asBiometricModality()
+        if (ignoreUnsuccessfulEventsFrom(errorModality, error)) {
+            return
+        }
+
+        applicationScope.launch {
+            val suppress =
+                modalities.hasFaceAndFingerprint && (errorModality == BiometricModality.Face)
+            viewModel.showTemporaryError(
+                error,
+                suppressIfErrorShowing = suppress,
+            )
+            delay(BiometricPrompt.HIDE_DIALOG_DELAY.toLong())
+            legacyCallback?.onAction(Callback.ACTION_ERROR)
+        }
+    }
+
+    override fun onHelp(modality: Int, help: String) {
+        if (ignoreUnsuccessfulEventsFrom(modality.asBiometricModality(), "")) {
+            return
+        }
+
+        applicationScope.launch {
+            viewModel.showTemporaryHelp(
+                help,
+                messageAfterHelp = modalities.asDefaultHelpMessage(applicationContext),
+            )
+        }
+    }
+
+    private fun ignoreUnsuccessfulEventsFrom(modality: BiometricModality, message: String) =
+        when {
+            modalities.hasFaceAndFingerprint ->
+                (modality == BiometricModality.Face) &&
+                    !(modalities.isFaceStrong && lockoutErrorStrings.contains(message))
+            else -> false
+        }
+
+    override fun startTransitionToCredentialUI() {
+        applicationScope.launch {
+            viewModel.onSwitchToCredential()
+            legacyCallback?.onAction(Callback.ACTION_USE_DEVICE_CREDENTIAL)
+        }
+    }
+
+    override fun requestLayout() {
+        // nothing, for legacy view...
+    }
+
+    override fun restoreState(bundle: Bundle?) {
+        // nothing, for legacy view...
+    }
+
+    override fun onSaveState(bundle: Bundle?) {
+        // nothing, for legacy view...
+    }
+
+    override fun onOrientationChanged() {
+        // nothing, for legacy view...
+    }
+
+    override fun cancelAnimation() {
+        view.animate()?.cancel()
+    }
+
+    override fun isCoex() = modalities.hasFaceAndFingerprint
+
+    override fun asView() = view
+}
+
+private fun BiometricModalities.asDefaultHelpMessage(context: Context): String =
+    when {
+        hasFingerprint -> context.getString(R.string.fingerprint_dialog_touch_sensor)
+        else -> ""
+    }
+
+private fun BiometricModalities.asIconController(
+    context: Context,
+    iconView: LottieAnimationView,
+    iconViewOverlay: LottieAnimationView,
+): AuthIconController =
+    when {
+        hasFaceAndFingerprint -> HackyCoexIconController(context, iconView, iconViewOverlay)
+        hasFingerprint -> AuthBiometricFingerprintIconController(context, iconView, iconViewOverlay)
+        hasFace -> AuthBiometricFaceIconController(context, iconView)
+        else -> throw IllegalStateException("unexpected view type :$this")
+    }
+
+private fun Boolean.asVisibleOrGone(): Int = if (this) View.VISIBLE else View.GONE
+
+private fun Boolean.asVisibleOrHidden(): Int = if (this) View.VISIBLE else View.INVISIBLE
+
+// TODO(b/251476085): proper type?
+typealias BiometricJankListener = Animator.AnimatorListener
+
+// TODO(b/251476085): delete - temporary until the legacy icon controllers are replaced
+private class HackyCoexIconController(
+    context: Context,
+    iconView: LottieAnimationView,
+    iconViewOverlay: LottieAnimationView,
+) : AuthBiometricFingerprintAndFaceIconController(context, iconView, iconViewOverlay) {
+
+    private var state: Int? = null
+    private val faceController = AuthBiometricFaceIconController(context, iconView)
+
+    var faceMode: Boolean = true
+        set(value) {
+            if (field != value) {
+                field = value
+
+                faceController.deactivated = !value
+                iconView.setImageIcon(null)
+                iconViewOverlay.setImageIcon(null)
+                state?.let { updateIcon(AuthBiometricView.STATE_IDLE, it) }
+            }
+        }
+
+    override fun updateIcon(lastState: Int, newState: Int) {
+        if (deactivated) {
+            return
+        }
+
+        if (faceMode) {
+            faceController.updateIcon(lastState, newState)
+        } else {
+            super.updateIcon(lastState, newState)
+        }
+
+        state = newState
+    }
+}
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
new file mode 100644
index 0000000..e4c4e9a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.ui.binder
+
+import android.animation.Animator
+import android.animation.AnimatorSet
+import android.animation.ValueAnimator
+import android.view.View
+import android.view.ViewGroup
+import android.view.accessibility.AccessibilityManager
+import android.widget.TextView
+import androidx.core.animation.addListener
+import androidx.core.view.doOnLayout
+import androidx.lifecycle.lifecycleScope
+import com.android.systemui.R
+import com.android.systemui.biometrics.AuthDialog
+import com.android.systemui.biometrics.AuthPanelController
+import com.android.systemui.biometrics.Utils
+import com.android.systemui.biometrics.ui.BiometricPromptLayout
+import com.android.systemui.biometrics.ui.viewmodel.PromptSize
+import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel
+import com.android.systemui.biometrics.ui.viewmodel.isLarge
+import com.android.systemui.biometrics.ui.viewmodel.isMedium
+import com.android.systemui.biometrics.ui.viewmodel.isNullOrNotSmall
+import com.android.systemui.biometrics.ui.viewmodel.isSmall
+import com.android.systemui.lifecycle.repeatWhenAttached
+import kotlinx.coroutines.launch
+
+/** Helper for [BiometricViewBinder] to handle resize transitions. */
+object BiometricViewSizeBinder {
+
+    /** Resizes [BiometricPromptLayout] and the [panelViewController] via the [PromptViewModel]. */
+    fun bind(
+        view: BiometricPromptLayout,
+        viewModel: PromptViewModel,
+        viewsToHideWhenSmall: List<TextView>,
+        viewsToFadeInOnSizeChange: List<View>,
+        panelViewController: AuthPanelController,
+        jankListener: BiometricJankListener,
+    ) {
+        val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!!
+        fun notifyAccessibilityChanged() {
+            Utils.notifyAccessibilityContentChanged(accessibilityManager, view)
+        }
+
+        fun startMonitoredAnimation(animators: List<Animator>) {
+            with(AnimatorSet()) {
+                addListener(jankListener)
+                addListener(onEnd = { notifyAccessibilityChanged() })
+                play(animators.first()).apply { animators.drop(1).forEach { next -> with(next) } }
+                start()
+            }
+        }
+
+        val iconHolderView = view.findViewById<View>(R.id.biometric_icon_frame)
+        val iconPadding = view.resources.getDimension(R.dimen.biometric_dialog_icon_padding)
+        val fullSizeYOffset =
+            view.resources.getDimension(R.dimen.biometric_dialog_medium_to_large_translation_offset)
+
+        // cache the original position of the icon view (as done in legacy view)
+        // this must happen before any size changes can be made
+        var iconHolderOriginalY = 0f
+        view.doOnLayout {
+            iconHolderOriginalY = iconHolderView.y
+
+            // bind to prompt
+            // TODO(b/251476085): migrate the legacy panel controller and simplify this
+            view.repeatWhenAttached {
+                var currentSize: PromptSize? = null
+                lifecycleScope.launch {
+                    viewModel.size.collect { size ->
+                        // prepare for animated size transitions
+                        for (v in viewsToHideWhenSmall) {
+                            v.showTextOrHide(forceHide = size.isSmall)
+                        }
+                        if (currentSize == null && size.isSmall) {
+                            iconHolderView.alpha = 0f
+                        }
+                        if ((currentSize.isSmall && size.isMedium) || size.isSmall) {
+                            viewsToFadeInOnSizeChange.forEach { it.alpha = 0f }
+                        }
+
+                        // propagate size changes to legacy panel controller and animate transitions
+                        view.doOnLayout {
+                            val width = view.measuredWidth
+                            val height = view.measuredHeight
+
+                            when {
+                                size.isSmall -> {
+                                    iconHolderView.alpha = 1f
+                                    iconHolderView.y =
+                                        view.height - iconHolderView.height - iconPadding
+                                    val newHeight =
+                                        iconHolderView.height + 2 * iconPadding.toInt() -
+                                            iconHolderView.paddingTop -
+                                            iconHolderView.paddingBottom
+                                    panelViewController.updateForContentDimensions(
+                                        width,
+                                        newHeight,
+                                        0, /* animateDurationMs */
+                                    )
+                                }
+                                size.isMedium && currentSize.isSmall -> {
+                                    val duration = AuthDialog.ANIMATE_SMALL_TO_MEDIUM_DURATION_MS
+                                    panelViewController.updateForContentDimensions(
+                                        width,
+                                        height,
+                                        duration,
+                                    )
+                                    startMonitoredAnimation(
+                                        listOf(
+                                            iconHolderView.asVerticalAnimator(
+                                                duration = duration.toLong(),
+                                                toY = iconHolderOriginalY,
+                                            ),
+                                            viewsToFadeInOnSizeChange.asFadeInAnimator(
+                                                duration = duration.toLong(),
+                                                delay = duration.toLong(),
+                                            ),
+                                        )
+                                    )
+                                }
+                                size.isMedium && currentSize.isNullOrNotSmall -> {
+                                    panelViewController.updateForContentDimensions(
+                                        width,
+                                        height,
+                                        0, /* animateDurationMs */
+                                    )
+                                }
+                                size.isLarge -> {
+                                    val duration = AuthDialog.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS
+                                    panelViewController.setUseFullScreen(true)
+                                    panelViewController.updateForContentDimensions(
+                                        panelViewController.containerWidth,
+                                        panelViewController.containerHeight,
+                                        duration,
+                                    )
+
+                                    startMonitoredAnimation(
+                                        listOf(
+                                            view.asVerticalAnimator(
+                                                duration.toLong() * 2 / 3,
+                                                toY = view.y - fullSizeYOffset
+                                            ),
+                                            listOf(view)
+                                                .asFadeInAnimator(
+                                                    duration = duration.toLong() / 2,
+                                                    delay = duration.toLong(),
+                                                ),
+                                        )
+                                    )
+                                    // TODO(b/251476085): clean up (copied from legacy)
+                                    if (view.isAttachedToWindow) {
+                                        val parent = view.parent as? ViewGroup
+                                        parent?.removeView(view)
+                                    }
+                                }
+                            }
+
+                            currentSize = size
+                            notifyAccessibilityChanged()
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+private fun TextView.showTextOrHide(forceHide: Boolean = false) {
+    visibility = if (forceHide || text.isBlank()) View.GONE else View.VISIBLE
+}
+
+private fun View.asVerticalAnimator(
+    duration: Long,
+    toY: Float,
+    fromY: Float = this.y
+): ValueAnimator {
+    val animator = ValueAnimator.ofFloat(fromY, toY)
+    animator.duration = duration
+    animator.addUpdateListener { y = it.animatedValue as Float }
+    return animator
+}
+
+private fun List<View>.asFadeInAnimator(duration: Long, delay: Long): ValueAnimator {
+    forEach { it.alpha = 0f }
+    val animator = ValueAnimator.ofFloat(0f, 1f)
+    animator.duration = duration
+    animator.startDelay = delay
+    animator.addUpdateListener {
+        val alpha = it.animatedValue as Float
+        forEach { view -> view.alpha = alpha }
+    }
+    return animator
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/HeaderViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialHeaderViewModel.kt
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/HeaderViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialHeaderViewModel.kt
index ba23f1c..a64798c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/HeaderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialHeaderViewModel.kt
@@ -4,7 +4,7 @@
 import android.os.UserHandle
 
 /** View model for the top-level header / info area of BiometricPrompt. */
-interface HeaderViewModel {
+interface CredentialHeaderViewModel {
     val user: UserHandle
     val title: String
     val subtitle: String
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
index 84bbceb..9d7b940 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt
@@ -7,8 +7,8 @@
 import com.android.internal.widget.LockPatternView
 import com.android.systemui.R
 import com.android.systemui.biometrics.Utils
-import com.android.systemui.biometrics.domain.interactor.BiometricPromptCredentialInteractor
 import com.android.systemui.biometrics.domain.interactor.CredentialStatus
+import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor
 import com.android.systemui.biometrics.domain.model.BiometricPromptRequest
 import com.android.systemui.dagger.qualifiers.Application
 import javax.inject.Inject
@@ -27,11 +27,11 @@
 @Inject
 constructor(
     @Application private val applicationContext: Context,
-    private val credentialInteractor: BiometricPromptCredentialInteractor,
+    private val credentialInteractor: PromptCredentialInteractor,
 ) {
 
     /** Top level information about the prompt. */
-    val header: Flow<HeaderViewModel> =
+    val header: Flow<CredentialHeaderViewModel> =
         credentialInteractor.prompt.filterIsInstance<BiometricPromptRequest.Credential>().map {
             request ->
             BiometricPromptHeaderViewModelImpl(
@@ -109,12 +109,14 @@
     }
 
     /** Check a PIN or password and update [validatedAttestation] or [remainingAttempts]. */
-    suspend fun checkCredential(text: CharSequence, header: HeaderViewModel) =
+    suspend fun checkCredential(text: CharSequence, header: CredentialHeaderViewModel) =
         checkCredential(credentialInteractor.checkCredential(header.asRequest(), text = text))
 
     /** Check a pattern and update [validatedAttestation] or [remainingAttempts]. */
-    suspend fun checkCredential(pattern: List<LockPatternView.Cell>, header: HeaderViewModel) =
-        checkCredential(credentialInteractor.checkCredential(header.asRequest(), pattern = pattern))
+    suspend fun checkCredential(
+        pattern: List<LockPatternView.Cell>,
+        header: CredentialHeaderViewModel
+    ) = checkCredential(credentialInteractor.checkCredential(header.asRequest(), pattern = pattern))
 
     private suspend fun checkCredential(result: CredentialStatus) {
         when (result) {
@@ -172,7 +174,7 @@
     override val subtitle: String,
     override val description: String,
     override val icon: Drawable,
-) : HeaderViewModel
+) : CredentialHeaderViewModel
 
-private fun HeaderViewModel.asRequest(): BiometricPromptRequest.Credential =
+private fun CredentialHeaderViewModel.asRequest(): BiometricPromptRequest.Credential =
     (this as BiometricPromptHeaderViewModelImpl).request
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthState.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthState.kt
new file mode 100644
index 0000000..9cb91b3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthState.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.ui.viewmodel
+
+import com.android.systemui.biometrics.domain.model.BiometricModality
+
+/**
+ * The authenticated state with the [authenticatedModality] (when [isAuthenticated]) with an
+ * optional [delay] to keep the UI showing before dismissing when [needsUserConfirmation] is not
+ * required.
+ */
+data class PromptAuthState(
+    val isAuthenticated: Boolean,
+    val authenticatedModality: BiometricModality = BiometricModality.None,
+    val needsUserConfirmation: Boolean = false,
+    val delay: Long = 0,
+) {
+    /** If authentication was successful and the user has confirmed (or does not need to). */
+    val isAuthenticatedAndConfirmed: Boolean
+        get() = isAuthenticated && !needsUserConfirmation
+
+    /** If a successful authentication has not occurred. */
+    val isNotAuthenticated: Boolean
+        get() = !isAuthenticated
+
+    /** If a authentication has succeeded and it was done by face (may need confirmation). */
+    val isAuthenticatedByFace: Boolean
+        get() = isAuthenticated && authenticatedModality == BiometricModality.Face
+
+    /** If a authentication has succeeded and it was done by fingerprint (may need confirmation). */
+    val isAuthenticatedByFingerprint: Boolean
+        get() = isAuthenticated && authenticatedModality == BiometricModality.Fingerprint
+
+    /** Copies this state, but toggles [needsUserConfirmation] to false. */
+    fun asConfirmed(): PromptAuthState =
+        PromptAuthState(
+            isAuthenticated = isAuthenticated,
+            authenticatedModality = authenticatedModality,
+            needsUserConfirmation = false,
+            delay = delay,
+        )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptMessage.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptMessage.kt
new file mode 100644
index 0000000..219da71
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptMessage.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.ui.viewmodel
+
+/**
+ * A help, hint, or error message to show.
+ *
+ * These typically correspond to the same category of help/error callbacks from the underlying HAL
+ * that runs the biometric operation, but may be customized by the framework.
+ */
+sealed interface PromptMessage {
+
+    /** The message to show the user or the empty string. */
+    val message: String
+        get() =
+            when (this) {
+                is Error -> errorMessage
+                is Help -> helpMessage
+                else -> ""
+            }
+
+    /** If this is an [Error] or [Help] message. */
+    val isErrorOrHelp: Boolean
+        get() = this is Error || this is Help
+
+    /** An error message. */
+    data class Error(val errorMessage: String) : PromptMessage
+
+    /** A help message. */
+    data class Help(val helpMessage: String) : PromptMessage
+
+    /** No message. */
+    object Empty : PromptMessage
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptSize.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptSize.kt
new file mode 100644
index 0000000..d779062
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptSize.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.ui.viewmodel
+
+/** The size of a biometric prompt. */
+enum class PromptSize {
+    /** Minimal UI, showing only biometric icon. */
+    SMALL,
+    /** Normal-sized biometric UI, showing title, icon, buttons, etc. */
+    MEDIUM,
+    /** Full-screen credential UI. */
+    LARGE,
+}
+
+val PromptSize?.isSmall: Boolean
+    get() = this != null && this == PromptSize.SMALL
+
+val PromptSize?.isNotSmall: Boolean
+    get() = this != null && this != PromptSize.SMALL
+
+val PromptSize?.isNullOrNotSmall: Boolean
+    get() = this == null || this != PromptSize.SMALL
+
+val PromptSize?.isMedium: Boolean
+    get() = this != null && this == PromptSize.MEDIUM
+
+val PromptSize?.isLarge: Boolean
+    get() = this != null && this == PromptSize.LARGE
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
new file mode 100644
index 0000000..2f8ed09
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.biometrics.ui.viewmodel
+
+import android.hardware.biometrics.BiometricPrompt
+import android.util.Log
+import com.android.systemui.biometrics.AuthBiometricView
+import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor
+import com.android.systemui.biometrics.domain.model.BiometricModalities
+import com.android.systemui.biometrics.domain.model.BiometricModality
+import com.android.systemui.biometrics.shared.model.PromptKind
+import javax.inject.Inject
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+/** ViewModel for BiometricPrompt. */
+class PromptViewModel
+@Inject
+constructor(
+    private val interactor: PromptSelectorInteractor,
+) {
+    /** The set of modalities available for this prompt */
+    val modalities: Flow<BiometricModalities> =
+        interactor.prompt.map { it?.modalities ?: BiometricModalities() }.distinctUntilChanged()
+
+    // TODO(b/251476085): remove after icon controllers are migrated - do not keep this state
+    private var _legacyState = MutableStateFlow(AuthBiometricView.STATE_AUTHENTICATING_ANIMATING_IN)
+    val legacyState: StateFlow<Int> = _legacyState.asStateFlow()
+
+    private val _isAuthenticating: MutableStateFlow<Boolean> = MutableStateFlow(false)
+
+    /** If the user is currently authenticating (i.e. at least one biometric is scanning). */
+    val isAuthenticating: Flow<Boolean> = _isAuthenticating.asStateFlow()
+
+    private val _isAuthenticated: MutableStateFlow<PromptAuthState> =
+        MutableStateFlow(PromptAuthState(false))
+
+    /** If the user has successfully authenticated and confirmed (when explicitly required). */
+    val isAuthenticated: Flow<PromptAuthState> = _isAuthenticated.asStateFlow()
+
+    /** If the API caller requested explicit confirmation after successful authentication. */
+    val isConfirmationRequested: Flow<Boolean> = interactor.isConfirmationRequested
+
+    /** The kind of credential the user has. */
+    val credentialKind: Flow<PromptKind> = interactor.credentialKind
+
+    /** The label to use for the cancel button. */
+    val negativeButtonText: Flow<String> = interactor.prompt.map { it?.negativeButtonText ?: "" }
+
+    private val _message: MutableStateFlow<PromptMessage> = MutableStateFlow(PromptMessage.Empty)
+
+    /** A message to show the user, if there is an error, hint, or help to show. */
+    val message: Flow<PromptMessage> = _message.asStateFlow()
+
+    private val isRetrySupported: Flow<Boolean> = modalities.map { it.hasFace }
+
+    private val _fingerprintStartMode = MutableStateFlow(FingerprintStartMode.Pending)
+
+    /** Fingerprint sensor state. */
+    val fingerprintStartMode: Flow<FingerprintStartMode> = _fingerprintStartMode.asStateFlow()
+
+    private val _forceLargeSize = MutableStateFlow(false)
+    private val _forceMediumSize = MutableStateFlow(false)
+
+    /** The size of the prompt. */
+    val size: Flow<PromptSize> =
+        combine(
+                _forceLargeSize,
+                _forceMediumSize,
+                modalities,
+                interactor.isConfirmationRequested,
+                fingerprintStartMode,
+            ) { forceLarge, forceMedium, modalities, confirmationRequired, fpStartMode ->
+                when {
+                    forceLarge -> PromptSize.LARGE
+                    forceMedium -> PromptSize.MEDIUM
+                    modalities.hasFaceOnly && !confirmationRequired -> PromptSize.SMALL
+                    modalities.hasFaceAndFingerprint &&
+                        !confirmationRequired &&
+                        fpStartMode == FingerprintStartMode.Pending -> PromptSize.SMALL
+                    else -> PromptSize.MEDIUM
+                }
+            }
+            .distinctUntilChanged()
+
+    /** Title for the prompt. */
+    val title: Flow<String> = interactor.prompt.map { it?.title ?: "" }.distinctUntilChanged()
+
+    /** Subtitle for the prompt. */
+    val subtitle: Flow<String> = interactor.prompt.map { it?.subtitle ?: "" }.distinctUntilChanged()
+
+    /** Description for the prompt. */
+    val description: Flow<String> =
+        interactor.prompt.map { it?.description ?: "" }.distinctUntilChanged()
+
+    /** If the indicator (help, error) message should be shown. */
+    val isIndicatorMessageVisible: Flow<Boolean> =
+        combine(
+                size,
+                message,
+            ) { size, message ->
+                size.isNotSmall && message.message.isNotBlank()
+            }
+            .distinctUntilChanged()
+
+    /** If the auth is pending confirmation and the confirm button should be shown. */
+    val isConfirmButtonVisible: Flow<Boolean> =
+        combine(
+                size,
+                isAuthenticated,
+            ) { size, authState ->
+                size.isNotSmall && authState.isAuthenticated && authState.needsUserConfirmation
+            }
+            .distinctUntilChanged()
+
+    /** If the negative button should be shown. */
+    val isNegativeButtonVisible: Flow<Boolean> =
+        combine(
+                size,
+                isAuthenticated,
+                interactor.isCredentialAllowed,
+            ) { size, authState, credentialAllowed ->
+                size.isNotSmall && authState.isNotAuthenticated && !credentialAllowed
+            }
+            .distinctUntilChanged()
+
+    /** If the cancel button should be shown (. */
+    val isCancelButtonVisible: Flow<Boolean> =
+        combine(
+                size,
+                isAuthenticated,
+                isNegativeButtonVisible,
+                isConfirmButtonVisible,
+            ) { size, authState, showNegativeButton, showConfirmButton ->
+                size.isNotSmall &&
+                    authState.isAuthenticated &&
+                    !showNegativeButton &&
+                    showConfirmButton
+            }
+            .distinctUntilChanged()
+
+    private val _canTryAgainNow = MutableStateFlow(false)
+    /**
+     * If authentication can be manually restarted via the try again button or touching a
+     * fingerprint sensor.
+     */
+    val canTryAgainNow: Flow<Boolean> =
+        combine(
+                _canTryAgainNow,
+                size,
+                isAuthenticated,
+                isRetrySupported,
+            ) { readyToTryAgain, size, authState, supportsRetry ->
+                readyToTryAgain && size.isNotSmall && supportsRetry && authState.isNotAuthenticated
+            }
+            .distinctUntilChanged()
+
+    /** If the try again button show be shown (only the button, see [canTryAgainNow]). */
+    val isTryAgainButtonVisible: Flow<Boolean> =
+        combine(
+                canTryAgainNow,
+                modalities,
+            ) { tryAgainIsPossible, modalities ->
+                tryAgainIsPossible && modalities.hasFaceOnly
+            }
+            .distinctUntilChanged()
+
+    /** If the credential fallback button show be shown. */
+    val isCredentialButtonVisible: Flow<Boolean> =
+        combine(
+                size,
+                isAuthenticated,
+                interactor.isCredentialAllowed,
+            ) { size, authState, credentialAllowed ->
+                size.isNotSmall && authState.isNotAuthenticated && credentialAllowed
+            }
+            .distinctUntilChanged()
+
+    private var messageJob: Job? = null
+
+    /**
+     * Show a temporary error [message] associated with an optional [failedModality].
+     *
+     * An optional [messageAfterError] will be shown via [showAuthenticating] when
+     * [authenticateAfterError] is set (or via [showHelp] when not set) after the error is
+     * dismissed.
+     *
+     * The error is ignored if the user has already authenticated and it is treated as
+     * [onSilentError] if [suppressIfErrorShowing] is set and an error message is already showing.
+     */
+    suspend fun showTemporaryError(
+        message: String,
+        messageAfterError: String = "",
+        authenticateAfterError: Boolean = false,
+        suppressIfErrorShowing: Boolean = false,
+        failedModality: BiometricModality = BiometricModality.None,
+    ) = coroutineScope {
+        if (_isAuthenticated.value.isAuthenticated) {
+            return@coroutineScope
+        }
+        if (_message.value.isErrorOrHelp && suppressIfErrorShowing) {
+            onSilentError(failedModality)
+            return@coroutineScope
+        }
+
+        _isAuthenticating.value = false
+        _isAuthenticated.value = PromptAuthState(false)
+        _forceMediumSize.value = true
+        _canTryAgainNow.value = supportsRetry(failedModality)
+        _message.value = PromptMessage.Error(message)
+        _legacyState.value = AuthBiometricView.STATE_ERROR
+
+        messageJob?.cancel()
+        messageJob = launch {
+            delay(BiometricPrompt.HIDE_DIALOG_DELAY.toLong())
+            if (authenticateAfterError) {
+                showAuthenticating(messageAfterError)
+            } else {
+                showHelp(messageAfterError)
+            }
+        }
+    }
+
+    /**
+     * Call instead of [showTemporaryError] if an error from the HAL should be silently ignored to
+     * enable retry (if the [failedModality] supports retrying).
+     *
+     * Ignored if the user has already authenticated.
+     */
+    private fun onSilentError(failedModality: BiometricModality = BiometricModality.None) {
+        if (_isAuthenticated.value.isNotAuthenticated) {
+            _canTryAgainNow.value = supportsRetry(failedModality)
+        }
+    }
+
+    /**
+     * Call to ensure the fingerprint sensor has started. Either when the dialog is first shown
+     * (most cases) or when it should be enabled after a first error (coex implicit flow).
+     */
+    fun ensureFingerprintHasStarted(isDelayed: Boolean) {
+        if (_fingerprintStartMode.value == FingerprintStartMode.Pending) {
+            _fingerprintStartMode.value =
+                if (isDelayed) FingerprintStartMode.Delayed else FingerprintStartMode.Normal
+        }
+    }
+
+    // enable retry only when face fails (fingerprint runs constantly)
+    private fun supportsRetry(failedModality: BiometricModality) =
+        failedModality == BiometricModality.Face
+
+    /**
+     * Show a persistent help message.
+     *
+     * Will be show even if the user has already authenticated.
+     */
+    suspend fun showHelp(message: String) {
+        val alreadyAuthenticated = _isAuthenticated.value.isAuthenticated
+        if (!alreadyAuthenticated) {
+            _isAuthenticating.value = false
+            _isAuthenticated.value = PromptAuthState(false)
+        }
+
+        _message.value =
+            if (message.isNotBlank()) PromptMessage.Help(message) else PromptMessage.Empty
+        _forceMediumSize.value = true
+        _legacyState.value =
+            if (alreadyAuthenticated) {
+                AuthBiometricView.STATE_PENDING_CONFIRMATION
+            } else {
+                AuthBiometricView.STATE_HELP
+            }
+
+        messageJob?.cancel()
+        messageJob = null
+    }
+
+    /**
+     * Show a temporary help message and transition back to a fixed message.
+     *
+     * Ignored if the user has already authenticated.
+     */
+    suspend fun showTemporaryHelp(
+        message: String,
+        messageAfterHelp: String = "",
+    ) = coroutineScope {
+        if (_isAuthenticated.value.isAuthenticated) {
+            return@coroutineScope
+        }
+
+        _isAuthenticating.value = false
+        _isAuthenticated.value = PromptAuthState(false)
+        _message.value =
+            if (message.isNotBlank()) PromptMessage.Help(message) else PromptMessage.Empty
+        _forceMediumSize.value = true
+        _legacyState.value = AuthBiometricView.STATE_HELP
+
+        messageJob?.cancel()
+        messageJob = launch {
+            delay(BiometricPrompt.HIDE_DIALOG_DELAY.toLong())
+            showAuthenticating(messageAfterHelp)
+        }
+    }
+
+    /** Show the user that biometrics are actively running and set [isAuthenticating]. */
+    fun showAuthenticating(message: String = "", isRetry: Boolean = false) {
+        if (_isAuthenticated.value.isAuthenticated) {
+            // TODO(jbolinger): convert to go/tex-apc?
+            Log.w(TAG, "Cannot show authenticating after authenticated")
+            return
+        }
+
+        _isAuthenticating.value = true
+        _isAuthenticated.value = PromptAuthState(false)
+        _message.value = if (message.isBlank()) PromptMessage.Empty else PromptMessage.Help(message)
+        _legacyState.value = AuthBiometricView.STATE_AUTHENTICATING
+
+        // reset the try again button(s) after the user attempts a retry
+        if (isRetry) {
+            _canTryAgainNow.value = false
+        }
+
+        messageJob?.cancel()
+        messageJob = null
+    }
+
+    /**
+     * Show successfully authentication, set [isAuthenticated], and dismiss the prompt after a
+     * [dismissAfterDelay] or prompt for explicit confirmation (if required).
+     */
+    suspend fun showAuthenticated(
+        modality: BiometricModality,
+        dismissAfterDelay: Long,
+        helpMessage: String = "",
+    ) {
+        if (_isAuthenticated.value.isAuthenticated) {
+            // TODO(jbolinger): convert to go/tex-apc?
+            Log.w(TAG, "Cannot show authenticated after authenticated")
+            return
+        }
+
+        _isAuthenticating.value = false
+        val needsUserConfirmation = needsExplicitConfirmation(modality)
+        _isAuthenticated.value =
+            PromptAuthState(true, modality, needsUserConfirmation, dismissAfterDelay)
+        _message.value = PromptMessage.Empty
+        _legacyState.value =
+            if (needsUserConfirmation) {
+                AuthBiometricView.STATE_PENDING_CONFIRMATION
+            } else {
+                AuthBiometricView.STATE_AUTHENTICATED
+            }
+
+        messageJob?.cancel()
+        messageJob = null
+
+        if (helpMessage.isNotBlank()) {
+            showHelp(helpMessage)
+        }
+    }
+
+    private suspend fun needsExplicitConfirmation(modality: BiometricModality): Boolean {
+        val availableModalities = modalities.first()
+        val confirmationRequested = interactor.isConfirmationRequested.first()
+
+        if (availableModalities.hasFaceAndFingerprint) {
+            // coex only needs confirmation when face is successful, unless it happens on the
+            // first attempt (i.e. without failure) before fingerprint scanning starts
+            if (modality == BiometricModality.Face) {
+                return (fingerprintStartMode.first() != FingerprintStartMode.Pending) ||
+                    confirmationRequested
+            }
+        }
+        if (availableModalities.hasFaceOnly) {
+            return confirmationRequested
+        }
+        // fingerprint only never requires confirmation
+        return false
+    }
+
+    /**
+     * Set the prompt's auth state to authenticated and confirmed.
+     *
+     * This should only be used after [showAuthenticated] when the operation requires explicit user
+     * confirmation.
+     */
+    fun confirmAuthenticated() {
+        val authState = _isAuthenticated.value
+        if (authState.isNotAuthenticated) {
+            "Cannot show authenticated after authenticated"
+            Log.w(TAG, "Cannot confirm authenticated when not authenticated")
+            return
+        }
+
+        _isAuthenticated.value = authState.asConfirmed()
+        _message.value = PromptMessage.Empty
+        _legacyState.value = AuthBiometricView.STATE_AUTHENTICATED
+
+        messageJob?.cancel()
+        messageJob = null
+    }
+
+    /**
+     * Switch to the credential view.
+     *
+     * TODO(b/251476085): this should be decoupled from the shared panel controller
+     */
+    fun onSwitchToCredential() {
+        _forceLargeSize.value = true
+    }
+
+    companion object {
+        private const val TAG = "PromptViewModel"
+    }
+}
+
+/** How the fingerprint sensor was started for the prompt. */
+enum class FingerprintStartMode {
+    /** Fingerprint sensor has not started. */
+    Pending,
+
+    /** Fingerprint sensor started immediately when prompt was displayed. */
+    Normal,
+
+    /** Fingerprint sensor started after the first failure of another passive modality. */
+    Delayed;
+
+    /** If this is [Normal] or [Delayed]. */
+    val isStarted: Boolean
+        get() = this == Normal || this == Delayed
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/data/repo/BouncerRepository.kt b/packages/SystemUI/src/com/android/systemui/bouncer/data/repo/BouncerRepository.kt
index 4c817b2..49a0a3c 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/data/repo/BouncerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/data/repo/BouncerRepository.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.bouncer.data.repo
 
+import com.android.systemui.bouncer.shared.model.AuthenticationThrottledModel
 import com.android.systemui.dagger.SysUISingleton
 import javax.inject.Inject
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -29,7 +30,15 @@
     /** The user-facing message to show in the bouncer. */
     val message: StateFlow<String?> = _message.asStateFlow()
 
+    private val _throttling = MutableStateFlow<AuthenticationThrottledModel?>(null)
+    /** The current authentication throttling state. If `null`, there's no throttling. */
+    val throttling: StateFlow<AuthenticationThrottledModel?> = _throttling.asStateFlow()
+
     fun setMessage(message: String?) {
         _message.value = message
     }
+
+    fun setThrottling(throttling: AuthenticationThrottledModel?) {
+        _throttling.value = throttling
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
index 57ce580..e462e2f 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
@@ -17,10 +17,12 @@
 package com.android.systemui.bouncer.domain.interactor
 
 import android.content.Context
+import androidx.annotation.VisibleForTesting
 import com.android.systemui.R
 import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.bouncer.data.repo.BouncerRepository
+import com.android.systemui.bouncer.shared.model.AuthenticationThrottledModel
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.model.SceneKey
@@ -29,8 +31,11 @@
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
 
 /** Encapsulates business logic and application state accessing use-cases. */
@@ -46,7 +51,22 @@
 ) {
 
     /** The user-facing message to show in the bouncer. */
-    val message: StateFlow<String?> = repository.message
+    val message: StateFlow<String?> =
+        combine(
+                repository.message,
+                repository.throttling,
+            ) { message, throttling ->
+                messageOrThrottlingMessage(message, throttling)
+            }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue =
+                    messageOrThrottlingMessage(
+                        repository.message.value,
+                        repository.throttling.value,
+                    )
+            )
 
     /**
      * The currently-configured authentication method. This determines how the authentication
@@ -55,6 +75,9 @@
     val authenticationMethod: StateFlow<AuthenticationMethodModel> =
         authenticationInteractor.authenticationMethod
 
+    /** The current authentication throttling state. If `null`, there's no throttling. */
+    val throttling: StateFlow<AuthenticationThrottledModel?> = repository.throttling
+
     init {
         applicationScope.launch {
             combine(
@@ -73,7 +96,7 @@
                             is AuthenticationMethodModel.Swipe ->
                                 sceneInteractor.setCurrentScene(
                                     containerName,
-                                    SceneModel(SceneKey.LockScreen),
+                                    SceneModel(SceneKey.Lockscreen),
                                 )
                             else -> Unit
                         }
@@ -129,14 +152,39 @@
     fun authenticate(
         input: List<Any>,
     ) {
+        if (repository.throttling.value != null) {
+            return
+        }
+
         val isAuthenticated = authenticationInteractor.authenticate(input)
-        if (isAuthenticated) {
-            sceneInteractor.setCurrentScene(
-                containerName = containerName,
-                scene = SceneModel(SceneKey.Gone),
-            )
-        } else {
-            repository.setMessage(errorMessage(authenticationMethod.value))
+        val failedAttempts = authenticationInteractor.failedAuthenticationAttempts.value
+        when {
+            isAuthenticated -> {
+                repository.setThrottling(null)
+                sceneInteractor.setCurrentScene(
+                    containerName = containerName,
+                    scene = SceneModel(SceneKey.Gone),
+                )
+            }
+            failedAttempts >= THROTTLE_AGGRESSIVELY_AFTER || failedAttempts % THROTTLE_EVERY == 0 ->
+                applicationScope.launch {
+                    var remainingDurationSec = THROTTLE_DURATION_SEC
+                    while (remainingDurationSec > 0) {
+                        repository.setThrottling(
+                            AuthenticationThrottledModel(
+                                failedAttemptCount = failedAttempts,
+                                totalDurationSec = THROTTLE_DURATION_SEC,
+                                remainingDurationSec = remainingDurationSec,
+                            )
+                        )
+                        remainingDurationSec--
+                        delay(1000)
+                    }
+
+                    repository.setThrottling(null)
+                    clearMessage()
+                }
+            else -> repository.setMessage(errorMessage(authenticationMethod.value))
         }
     }
 
@@ -163,10 +211,31 @@
         }
     }
 
+    private fun messageOrThrottlingMessage(
+        message: String?,
+        throttling: AuthenticationThrottledModel?,
+    ): String {
+        return when {
+            throttling != null ->
+                applicationContext.getString(
+                    com.android.internal.R.string.lockscreen_too_many_failed_attempts_countdown,
+                    throttling.remainingDurationSec,
+                )
+            message != null -> message
+            else -> ""
+        }
+    }
+
     @AssistedFactory
     interface Factory {
         fun create(
             containerName: String,
         ): BouncerInteractor
     }
+
+    companion object {
+        @VisibleForTesting const val THROTTLE_DURATION_SEC = 30
+        @VisibleForTesting const val THROTTLE_AGGRESSIVELY_AFTER = 15
+        @VisibleForTesting const val THROTTLE_EVERY = 5
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/shared/model/AuthenticationThrottledModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/shared/model/AuthenticationThrottledModel.kt
new file mode 100644
index 0000000..cbea635
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/shared/model/AuthenticationThrottledModel.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bouncer.shared.model
+
+/**
+ * Models application state for when further authentication attempts are being throttled due to too
+ * many consecutive failed authentication attempts.
+ */
+data class AuthenticationThrottledModel(
+    /** Total number of failed attempts so far. */
+    val failedAttemptCount: Int,
+    /** Total amount of time the user has to wait before attempting again. */
+    val totalDurationSec: Int,
+    /** Remaining amount of time the user has to wait before attempting again. */
+    val remainingDurationSec: Int,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
new file mode 100644
index 0000000..774a559
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bouncer.ui.viewmodel
+
+import kotlinx.coroutines.flow.StateFlow
+
+sealed interface AuthMethodBouncerViewModel {
+    /**
+     * Whether user input is enabled.
+     *
+     * If `false`, user input should be completely ignored in the UI as the user is "locked out" of
+     * being able to attempt to unlock the device.
+     */
+    val isInputEnabled: StateFlow<Boolean>
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
index 8a183ae..02991bd 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
@@ -16,26 +16,93 @@
 
 package com.android.systemui.bouncer.ui.viewmodel
 
+import android.content.Context
+import com.android.systemui.R
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
 import com.android.systemui.dagger.qualifiers.Application
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
 
 /** Holds UI state and handles user input on bouncer UIs. */
 class BouncerViewModel
 @AssistedInject
 constructor(
+    @Application private val applicationContext: Context,
     @Application private val applicationScope: CoroutineScope,
     interactorFactory: BouncerInteractor.Factory,
-    containerName: String,
+    @Assisted containerName: String,
 ) {
     private val interactor: BouncerInteractor = interactorFactory.create(containerName)
 
+    /**
+     * Whether updates to the message should be cross-animated from one message to another.
+     *
+     * If `false`, no animation should be applied, the message text should just be replaced
+     * instantly.
+     */
+    val isMessageUpdateAnimationsEnabled: StateFlow<Boolean> =
+        interactor.throttling
+            .map { it == null }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = interactor.throttling.value == null,
+            )
+
+    private val isInputEnabled: StateFlow<Boolean> =
+        interactor.throttling
+            .map { it == null }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = interactor.throttling.value == null,
+            )
+
+    private val pin: PinBouncerViewModel by lazy {
+        PinBouncerViewModel(
+            applicationScope = applicationScope,
+            interactor = interactor,
+            isInputEnabled = isInputEnabled,
+        )
+    }
+
+    private val password: PasswordBouncerViewModel by lazy {
+        PasswordBouncerViewModel(
+            interactor = interactor,
+            isInputEnabled = isInputEnabled,
+        )
+    }
+
+    private val pattern: PatternBouncerViewModel by lazy {
+        PatternBouncerViewModel(
+            applicationContext = applicationContext,
+            applicationScope = applicationScope,
+            interactor = interactor,
+            isInputEnabled = isInputEnabled,
+        )
+    }
+
+    /** View-model for the current UI, based on the current authentication method. */
+    val authMethod: StateFlow<AuthMethodBouncerViewModel?> =
+        interactor.authenticationMethod
+            .map { authMethod -> toViewModel(authMethod) }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = toViewModel(interactor.authenticationMethod.value),
+            )
+
     /** The user-facing message to show in the bouncer. */
     val message: StateFlow<String> =
         interactor.message
@@ -46,30 +113,74 @@
                 initialValue = interactor.message.value ?: "",
             )
 
-    /** Notifies that the authenticate button was clicked. */
-    fun onAuthenticateButtonClicked() {
-        // TODO(b/280877228): remove this and send the real input.
-        interactor.authenticate(
-            when (interactor.authenticationMethod.value) {
-                is AuthenticationMethodModel.PIN -> listOf(1, 2, 3, 4)
-                is AuthenticationMethodModel.Password -> "password".toList()
-                is AuthenticationMethodModel.Pattern ->
-                    listOf(
-                        AuthenticationMethodModel.Pattern.PatternCoordinate(2, 0),
-                        AuthenticationMethodModel.Pattern.PatternCoordinate(2, 1),
-                        AuthenticationMethodModel.Pattern.PatternCoordinate(2, 2),
-                        AuthenticationMethodModel.Pattern.PatternCoordinate(1, 1),
-                        AuthenticationMethodModel.Pattern.PatternCoordinate(0, 0),
-                        AuthenticationMethodModel.Pattern.PatternCoordinate(0, 1),
-                        AuthenticationMethodModel.Pattern.PatternCoordinate(0, 2),
-                    )
-                else -> emptyList()
-            }
-        )
+    private val _throttlingDialogMessage = MutableStateFlow<String?>(null)
+    /**
+     * A message for a throttling dialog to show when the user has attempted the wrong credential
+     * too many times and now must wait a while before attempting again.
+     *
+     * If `null`, no dialog should be shown.
+     *
+     * Once the dialog is shown, the UI should call [onThrottlingDialogDismissed] when the user
+     * dismisses this dialog.
+     */
+    val throttlingDialogMessage: StateFlow<String?> = _throttlingDialogMessage.asStateFlow()
+
+    init {
+        applicationScope.launch {
+            interactor.throttling
+                .map { model ->
+                    model?.let {
+                        when (interactor.authenticationMethod.value) {
+                            is AuthenticationMethodModel.PIN ->
+                                R.string.kg_too_many_failed_pin_attempts_dialog_message
+                            is AuthenticationMethodModel.Password ->
+                                R.string.kg_too_many_failed_password_attempts_dialog_message
+                            is AuthenticationMethodModel.Pattern ->
+                                R.string.kg_too_many_failed_pattern_attempts_dialog_message
+                            else -> null
+                        }?.let { stringResourceId ->
+                            applicationContext.getString(
+                                stringResourceId,
+                                model.failedAttemptCount,
+                                model.totalDurationSec,
+                            )
+                        }
+                    }
+                }
+                .distinctUntilChanged()
+                .collect { dialogMessageOrNull ->
+                    if (dialogMessageOrNull != null) {
+                        _throttlingDialogMessage.value = dialogMessageOrNull
+                    }
+                }
+        }
     }
 
     /** Notifies that the emergency services button was clicked. */
     fun onEmergencyServicesButtonClicked() {
-        // TODO(b/280877228): implement this.
+        // TODO(b/280877228): implement this
+    }
+
+    /** Notifies that a throttling dialog has been dismissed by the user. */
+    fun onThrottlingDialogDismissed() {
+        _throttlingDialogMessage.value = null
+    }
+
+    private fun toViewModel(
+        authMethod: AuthenticationMethodModel,
+    ): AuthMethodBouncerViewModel? {
+        return when (authMethod) {
+            is AuthenticationMethodModel.PIN -> pin
+            is AuthenticationMethodModel.Password -> password
+            is AuthenticationMethodModel.Pattern -> pattern
+            else -> null
+        }
+    }
+
+    @AssistedFactory
+    interface Factory {
+        fun create(
+            containerName: String,
+        ): BouncerViewModel
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
new file mode 100644
index 0000000..c38fcaa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bouncer.ui.viewmodel
+
+import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+/** Holds UI state and handles user input for the password bouncer UI. */
+class PasswordBouncerViewModel(
+    private val interactor: BouncerInteractor,
+    override val isInputEnabled: StateFlow<Boolean>,
+) : AuthMethodBouncerViewModel {
+
+    private val _password = MutableStateFlow("")
+    /** The password entered so far. */
+    val password: StateFlow<String> = _password.asStateFlow()
+
+    /** Notifies that the UI has been shown to the user. */
+    fun onShown() {
+        interactor.resetMessage()
+    }
+
+    /** Notifies that the user has changed the password input. */
+    fun onPasswordInputChanged(password: String) {
+        if (this.password.value.isEmpty() && password.isNotEmpty()) {
+            interactor.clearMessage()
+        }
+
+        _password.value = password
+    }
+
+    /** Notifies that the user has pressed the key for attempting to authenticate the password. */
+    fun onAuthenticateKeyPressed() {
+        interactor.authenticate(password.value.toCharArray().toList())
+        _password.value = ""
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
new file mode 100644
index 0000000..1b0b38e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bouncer.ui.viewmodel
+
+import android.content.Context
+import android.util.TypedValue
+import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
+import kotlin.math.max
+import kotlin.math.min
+import kotlin.math.pow
+import kotlin.math.sqrt
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+/** Holds UI state and handles user input for the pattern bouncer UI. */
+class PatternBouncerViewModel(
+    private val applicationContext: Context,
+    applicationScope: CoroutineScope,
+    private val interactor: BouncerInteractor,
+    override val isInputEnabled: StateFlow<Boolean>,
+) : AuthMethodBouncerViewModel {
+
+    /** The number of columns in the dot grid. */
+    val columnCount = 3
+    /** The number of rows in the dot grid. */
+    val rowCount = 3
+
+    private val _selectedDots = MutableStateFlow<LinkedHashSet<PatternDotViewModel>>(linkedSetOf())
+    /** The dots that were selected by the user, in the order of selection. */
+    val selectedDots: StateFlow<List<PatternDotViewModel>> =
+        _selectedDots
+            .map { it.toList() }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = emptyList(),
+            )
+
+    private val _currentDot = MutableStateFlow<PatternDotViewModel?>(null)
+    /** The most-recently selected dot that the user selected. */
+    val currentDot: StateFlow<PatternDotViewModel?> = _currentDot.asStateFlow()
+
+    private val _dots = MutableStateFlow(defaultDots())
+    /** All dots on the grid. */
+    val dots: StateFlow<List<PatternDotViewModel>> = _dots.asStateFlow()
+
+    /** Whether the pattern itself should be rendered visibly. */
+    val isPatternVisible: StateFlow<Boolean> =
+        interactor.authenticationMethod
+            .map { authMethod -> isPatternVisible(authMethod) }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.Eagerly,
+                initialValue = isPatternVisible(interactor.authenticationMethod.value),
+            )
+
+    /** Notifies that the UI has been shown to the user. */
+    fun onShown() {
+        interactor.resetMessage()
+    }
+
+    /** Notifies that the user has started a drag gesture across the dot grid. */
+    fun onDragStart() {
+        interactor.clearMessage()
+    }
+
+    /**
+     * Notifies that the user is dragging across the dot grid.
+     *
+     * @param xPx The horizontal coordinate of the position of the user's pointer, in pixels.
+     * @param yPx The vertical coordinate of the position of the user's pointer, in pixels.
+     * @param containerSizePx The size of the container of the dot grid, in pixels. It's assumed
+     *   that the dot grid is perfectly square such that width and height are equal.
+     * @param verticalOffsetPx How far down from `0` does the dot grid start on the display.
+     */
+    fun onDrag(xPx: Float, yPx: Float, containerSizePx: Int, verticalOffsetPx: Float) {
+        val cellWidthPx = containerSizePx / columnCount
+        val cellHeightPx = containerSizePx / rowCount
+
+        if (xPx < 0 || yPx < verticalOffsetPx) {
+            return
+        }
+
+        val dotColumn = (xPx / cellWidthPx).toInt()
+        val dotRow = ((yPx - verticalOffsetPx) / cellHeightPx).toInt()
+        if (dotColumn > columnCount - 1 || dotRow > rowCount - 1) {
+            return
+        }
+
+        val dotPixelX = dotColumn * cellWidthPx + cellWidthPx / 2
+        val dotPixelY = dotRow * cellHeightPx + cellHeightPx / 2 + verticalOffsetPx
+
+        val distance = sqrt((xPx - dotPixelX).pow(2) + (yPx - dotPixelY).pow(2))
+        val hitRadius = hitFactor * min(cellWidthPx, cellHeightPx) / 2
+        if (distance > hitRadius) {
+            return
+        }
+
+        val hitDot = dots.value.firstOrNull { dot -> dot.x == dotColumn && dot.y == dotRow }
+        if (hitDot != null && !_selectedDots.value.contains(hitDot)) {
+            val skippedOverDots =
+                currentDot.value?.let { previousDot ->
+                    buildList {
+                        var dot = previousDot
+                        while (dot != hitDot) {
+                            add(dot)
+                            dot =
+                                PatternDotViewModel(
+                                    x =
+                                        if (hitDot.x > dot.x) dot.x + 1
+                                        else if (hitDot.x < dot.x) dot.x - 1 else dot.x,
+                                    y =
+                                        if (hitDot.y > dot.y) dot.y + 1
+                                        else if (hitDot.y < dot.y) dot.y - 1 else dot.y,
+                                )
+                        }
+                    }
+                }
+                    ?: emptyList()
+
+            _selectedDots.value =
+                linkedSetOf<PatternDotViewModel>().apply {
+                    addAll(_selectedDots.value)
+                    addAll(skippedOverDots)
+                    add(hitDot)
+                }
+            _currentDot.value = hitDot
+        }
+    }
+
+    /** Notifies that the user has ended the drag gesture across the dot grid. */
+    fun onDragEnd() {
+        interactor.authenticate(_selectedDots.value.map { it.toCoordinate() })
+
+        _dots.value = defaultDots()
+        _currentDot.value = null
+        _selectedDots.value = linkedSetOf()
+    }
+
+    private fun isPatternVisible(authMethodModel: AuthenticationMethodModel): Boolean {
+        return (authMethodModel as? AuthenticationMethodModel.Pattern)?.isPatternVisible ?: false
+    }
+
+    private fun defaultDots(): List<PatternDotViewModel> {
+        return buildList {
+            (0 until columnCount).forEach { x ->
+                (0 until rowCount).forEach { y ->
+                    add(
+                        PatternDotViewModel(
+                            x = x,
+                            y = y,
+                        )
+                    )
+                }
+            }
+        }
+    }
+
+    private val hitFactor: Float by lazy {
+        val outValue = TypedValue()
+        applicationContext.resources.getValue(
+            com.android.internal.R.dimen.lock_pattern_dot_hit_factor,
+            outValue,
+            true
+        )
+        max(min(outValue.float, 1f), MIN_DOT_HIT_FACTOR)
+    }
+
+    companion object {
+        private const val MIN_DOT_HIT_FACTOR = 0.2f
+    }
+}
+
+data class PatternDotViewModel(
+    val x: Int,
+    val y: Int,
+) {
+    fun toCoordinate(): AuthenticationMethodModel.Pattern.PatternCoordinate {
+        return AuthenticationMethodModel.Pattern.PatternCoordinate(
+            x = x,
+            y = y,
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
new file mode 100644
index 0000000..2a733d9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bouncer.ui.viewmodel
+
+import androidx.annotation.VisibleForTesting
+import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
+import com.android.systemui.util.kotlin.pairwise
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
+
+/** Holds UI state and handles user input for the PIN code bouncer UI. */
+class PinBouncerViewModel(
+    private val applicationScope: CoroutineScope,
+    private val interactor: BouncerInteractor,
+    override val isInputEnabled: StateFlow<Boolean>,
+) : AuthMethodBouncerViewModel {
+
+    private val entered = MutableStateFlow<List<Int>>(emptyList())
+    /**
+     * The length of the PIN digits that were input so far, two values are supplied the previous and
+     * the current.
+     */
+    val pinLengths: StateFlow<Pair<Int, Int>> =
+        entered
+            .pairwise()
+            .map { it.previousValue.size to it.newValue.size }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = 0 to 0,
+            )
+    private var resetPinJob: Job? = null
+
+    /** Notifies that the UI has been shown to the user. */
+    fun onShown() {
+        interactor.resetMessage()
+    }
+
+    /** Notifies that the user clicked on a PIN button with the given digit value. */
+    fun onPinButtonClicked(input: Int) {
+        resetPinJob?.cancel()
+        resetPinJob = null
+
+        if (entered.value.isEmpty()) {
+            interactor.clearMessage()
+        }
+
+        entered.value += input
+    }
+
+    /** Notifies that the user clicked the backspace button. */
+    fun onBackspaceButtonClicked() {
+        if (entered.value.isEmpty()) {
+            return
+        }
+
+        entered.value = entered.value.toMutableList().apply { removeLast() }
+    }
+
+    /** Notifies that the user long-pressed the backspace button. */
+    fun onBackspaceButtonLongPressed() {
+        resetPinJob?.cancel()
+        resetPinJob =
+            applicationScope.launch {
+                while (entered.value.isNotEmpty()) {
+                    onBackspaceButtonClicked()
+                    delay(BACKSPACE_LONG_PRESS_DELAY_MS)
+                }
+            }
+    }
+
+    /** Notifies that the user clicked the "enter" button. */
+    fun onAuthenticateButtonClicked() {
+        interactor.authenticate(entered.value)
+        entered.value = emptyList()
+    }
+
+    companion object {
+        @VisibleForTesting const val BACKSPACE_LONG_PRESS_DELAY_MS = 80L
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index 691017b..b2bcb05 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -232,8 +232,7 @@
 
         // check for false tap if it is a seekbar interaction
         if (interactionType == MEDIA_SEEKBAR) {
-            localResult[0] &= isFalseTap(mFeatureFlags.isEnabled(Flags.MEDIA_FALSING_PENALTY)
-                    ? FalsingManager.MODERATE_PENALTY : FalsingManager.LOW_PENALTY);
+            localResult[0] &= isFalseTap(FalsingManager.MODERATE_PENALTY);
         }
 
         logDebug("False Gesture (type: " + interactionType + "): " + localResult[0]);
diff --git a/packages/SystemUI/src/com/android/systemui/complication/ComplicationTypesUpdater.java b/packages/SystemUI/src/com/android/systemui/complication/ComplicationTypesUpdater.java
index a334c1e..0bdc7f1 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/ComplicationTypesUpdater.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/ComplicationTypesUpdater.java
@@ -77,6 +77,10 @@
                 Settings.Secure.SCREENSAVER_HOME_CONTROLS_ENABLED,
                 settingsObserver,
                 UserHandle.myUserId());
+        mSecureSettings.registerContentObserverForUser(
+                Settings.Secure.LOCKSCREEN_SHOW_CONTROLS,
+                settingsObserver,
+                UserHandle.myUserId());
         settingsObserver.onChange(false);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java b/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java
index f973aee..4d99282 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java
@@ -24,6 +24,7 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Resources;
 import android.util.Log;
 import android.view.View;
 import android.widget.ImageView;
@@ -39,6 +40,7 @@
 import com.android.systemui.controls.management.ControlsListingController;
 import com.android.systemui.controls.ui.ControlsActivity;
 import com.android.systemui.controls.ui.ControlsUiController;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dagger.qualifiers.SystemUser;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.plugins.ActivityStarter;
@@ -56,17 +58,20 @@
  * devices at home like lights and thermostats).
  */
 public class DreamHomeControlsComplication implements Complication {
+    private final Resources mResources;
     private final DreamHomeControlsComplicationComponent.Factory mComponentFactory;
 
     @Inject
     public DreamHomeControlsComplication(
+            @Main Resources resources,
             DreamHomeControlsComplicationComponent.Factory componentFactory) {
+        mResources = resources;
         mComponentFactory = componentFactory;
     }
 
     @Override
     public ViewHolder createView(ComplicationViewModel model) {
-        return mComponentFactory.create().getViewHolder();
+        return mComponentFactory.create(mResources).getViewHolder();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamHomeControlsComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamHomeControlsComplicationComponent.java
index ef18d66..2b5aa7c 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamHomeControlsComplicationComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamHomeControlsComplicationComponent.java
@@ -18,12 +18,19 @@
 
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
 import android.view.LayoutInflater;
 import android.widget.ImageView;
 
+import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.complication.DreamHomeControlsComplication;
+import com.android.systemui.shared.shadow.DoubleShadowIconDrawable;
+import com.android.systemui.shared.shadow.DoubleShadowTextHelper;
 
+import dagger.BindsInstance;
 import dagger.Module;
 import dagger.Provides;
 import dagger.Subcomponent;
@@ -59,7 +66,7 @@
      */
     @Subcomponent.Factory
     interface Factory {
-        DreamHomeControlsComplicationComponent create();
+        DreamHomeControlsComplicationComponent create(@BindsInstance Resources resources);
     }
 
     /**
@@ -68,6 +75,7 @@
     @Module
     interface DreamHomeControlsModule {
         String DREAM_HOME_CONTROLS_CHIP_VIEW = "dream_home_controls_chip_view";
+        String DREAM_HOME_CONTROLS_BACKGROUND_DRAWABLE = "dream_home_controls_background_drawable";
 
         /**
          * Provides the dream home controls chip view.
@@ -75,9 +83,56 @@
         @Provides
         @DreamHomeControlsComplicationScope
         @Named(DREAM_HOME_CONTROLS_CHIP_VIEW)
-        static ImageView provideHomeControlsChipView(LayoutInflater layoutInflater) {
-            return (ImageView) layoutInflater.inflate(R.layout.dream_overlay_home_controls_chip,
-                    null, false);
+        static ImageView provideHomeControlsChipView(
+                LayoutInflater layoutInflater,
+                @Named(DREAM_HOME_CONTROLS_BACKGROUND_DRAWABLE) Drawable backgroundDrawable) {
+            final ImageView chip =
+                    (ImageView) layoutInflater.inflate(R.layout.dream_overlay_home_controls_chip,
+                            null, false);
+            chip.setBackground(backgroundDrawable);
+
+            return chip;
+        }
+
+        @Provides
+        @DreamHomeControlsComplicationScope
+        @Named(DREAM_HOME_CONTROLS_BACKGROUND_DRAWABLE)
+        static Drawable providesHomeControlsBackground(Context context, Resources resources) {
+            final Drawable background = new DoubleShadowIconDrawable(createShadowInfo(
+                            resources,
+                            R.dimen.dream_overlay_bottom_affordance_key_text_shadow_radius,
+                            R.dimen.dream_overlay_bottom_affordance_key_text_shadow_dx,
+                            R.dimen.dream_overlay_bottom_affordance_key_text_shadow_dy,
+                            R.dimen.dream_overlay_bottom_affordance_key_shadow_alpha
+                    ),
+                    createShadowInfo(
+                            resources,
+                            R.dimen.dream_overlay_bottom_affordance_ambient_text_shadow_radius,
+                            R.dimen.dream_overlay_bottom_affordance_ambient_text_shadow_dx,
+                            R.dimen.dream_overlay_bottom_affordance_ambient_text_shadow_dy,
+                            R.dimen.dream_overlay_bottom_affordance_ambient_shadow_alpha
+                    ),
+                    resources.getDrawable(R.drawable.dream_overlay_bottom_affordance_bg),
+                    resources.getDimensionPixelOffset(
+                            R.dimen.dream_overlay_bottom_affordance_width),
+                    resources.getDimensionPixelSize(R.dimen.dream_overlay_bottom_affordance_inset)
+            );
+
+            background.setTintList(
+                    Utils.getColorAttr(context, com.android.internal.R.attr.colorSurface));
+
+            return background;
+        }
+
+        private static DoubleShadowTextHelper.ShadowInfo createShadowInfo(Resources resources,
+                int blurId, int offsetXId, int offsetYId, int alphaId) {
+
+            return new DoubleShadowTextHelper.ShadowInfo(
+                    resources.getDimension(blurId),
+                    resources.getDimension(offsetXId),
+                    resources.getDimension(offsetYId),
+                    resources.getFloat(alphaId)
+            );
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index 92607c6..d73c85b 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -328,6 +328,13 @@
 
     @VisibleForTesting
     internal fun startRemovingApp(componentName: ComponentName, appName: CharSequence) {
+        activityStarter.dismissKeyguardThenExecute({
+            showAppRemovalDialog(componentName, appName)
+            true
+        }, null, true)
+    }
+
+    private fun showAppRemovalDialog(componentName: ComponentName, appName: CharSequence) {
         removeAppDialog?.cancel()
         removeAppDialog = dialogsFactory.createRemoveAppDialog(context, appName) { shouldRemove ->
             if (!shouldRemove || !controlsController.get().removeFavorites(componentName)) {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
index dba353b..8d5a2dd 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
@@ -32,6 +32,7 @@
 import com.android.systemui.sensorprivacy.television.TvUnblockSensorActivity;
 import com.android.systemui.settings.brightness.BrightnessDialog;
 import com.android.systemui.statusbar.tv.notifications.TvNotificationPanelActivity;
+import com.android.systemui.telephony.ui.activity.SwitchToManagedProfileForCallActivity;
 import com.android.systemui.tuner.TunerActivity;
 import com.android.systemui.usb.UsbAccessoryUriActivity;
 import com.android.systemui.usb.UsbConfirmActivity;
@@ -178,4 +179,11 @@
     @ClassKey(TvSensorPrivacyChangedActivity.class)
     public abstract Activity bindTvSensorPrivacyChangedActivity(
             TvSensorPrivacyChangedActivity activity);
+
+    /** Inject into SwitchToManagedProfileForCallActivity. */
+    @Binds
+    @IntoMap
+    @ClassKey(SwitchToManagedProfileForCallActivity.class)
+    public abstract Activity bindSwitchToManagedProfileForCallActivity(
+            SwitchToManagedProfileForCallActivity activity);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java b/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java
index 8764297..a3e26b8 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/PluginModule.java
@@ -16,17 +16,13 @@
 
 package com.android.systemui.dagger;
 
-import com.android.systemui.ActivityStarterDelegate;
 import com.android.systemui.classifier.FalsingManagerProxy;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.globalactions.GlobalActionsComponent;
 import com.android.systemui.globalactions.GlobalActionsImpl;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.GlobalActions;
-import com.android.systemui.plugins.PluginDependencyProvider;
 import com.android.systemui.plugins.VolumeDialogController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.StatusBarStateControllerImpl;
@@ -36,7 +32,6 @@
 
 import dagger.Binds;
 import dagger.Module;
-import dagger.Provides;
 
 /**
  * Module for binding Plugin implementations.
@@ -47,16 +42,8 @@
 public abstract class PluginModule {
 
     /** */
-    @Provides
-    static ActivityStarter provideActivityStarter(ActivityStarterDelegate delegate,
-            PluginDependencyProvider dependencyProvider, ActivityStarterImpl activityStarterImpl,
-            FeatureFlags featureFlags) {
-        if (featureFlags.isEnabled(Flags.USE_NEW_ACTIVITY_STARTER)) {
-            return activityStarterImpl;
-        }
-        dependencyProvider.allowPluginDependency(ActivityStarter.class, delegate);
-        return delegate;
-    }
+    @Binds
+    abstract ActivityStarter provideActivityStarter(ActivityStarterImpl activityStarterImpl);
 
     /** */
     @Binds
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
index f68bd49..2262d8a 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
@@ -40,6 +40,7 @@
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsImplementation;
 import com.android.systemui.rotationlock.RotationLockModule;
+import com.android.systemui.scene.SceneContainerFrameworkModule;
 import com.android.systemui.screenshot.ReferenceScreenshotModule;
 import com.android.systemui.settings.dagger.MultiUserUtilsModule;
 import com.android.systemui.shade.NotificationShadeWindowControllerImpl;
@@ -103,6 +104,7 @@
         QSModule.class,
         ReferenceScreenshotModule.class,
         RotationLockModule.class,
+        SceneContainerFrameworkModule.class,
         StatusBarEventsModule.class,
         StartCentralSurfacesModule.class,
         VolumeModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index 1a0fcea..52355f3 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -42,6 +42,7 @@
 import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.desktopmode.DesktopMode;
 import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
+import com.android.wm.shell.keyguard.KeyguardTransitions;
 import com.android.wm.shell.onehanded.OneHanded;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.recents.RecentTasks;
@@ -104,6 +105,9 @@
         Builder setTransitions(ShellTransitions t);
 
         @BindsInstance
+        Builder setKeyguardTransitions(KeyguardTransitions k);
+
+        @BindsInstance
         Builder setStartingSurface(Optional<StartingSurface> s);
 
         @BindsInstance
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index 5d6479e..25634f0 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.dagger
 
 import com.android.keyguard.KeyguardBiometricLockoutLogger
-import com.android.systemui.ChooserSelector
 import com.android.systemui.CoreStartable
 import com.android.systemui.LatencyTester
 import com.android.systemui.ScreenDecorations
@@ -55,6 +54,7 @@
 import com.android.systemui.toast.ToastUI
 import com.android.systemui.usb.StorageNotification
 import com.android.systemui.util.NotificationChannels
+import com.android.systemui.util.StartBinderLoggerModule
 import com.android.systemui.volume.VolumeUI
 import com.android.systemui.wmshell.WMShell
 import dagger.Binds
@@ -68,6 +68,7 @@
 @Module(includes = [
     MultiUserUtilsModule::class,
     StartControlsStartableModule::class,
+    StartBinderLoggerModule::class,
 ])
 abstract class SystemUICoreStartableModule {
     /** Inject into AuthController.  */
@@ -84,12 +85,6 @@
         service: BiometricNotificationService
     ): CoreStartable
 
-    /** Inject into ChooserCoreStartable. */
-    @Binds
-    @IntoMap
-    @ClassKey(ChooserSelector::class)
-    abstract fun bindChooserSelector(sysui: ChooserSelector): CoreStartable
-
     /** Inject into ClipboardListener.  */
     @Binds
     @IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 70c859e..5bcf32a 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -55,6 +55,8 @@
 import com.android.systemui.keyboard.KeyboardModule;
 import com.android.systemui.keyguard.data.BouncerViewModule;
 import com.android.systemui.log.dagger.LogModule;
+import com.android.systemui.log.dagger.MonitorLog;
+import com.android.systemui.log.table.TableLogBuffer;
 import com.android.systemui.mediaprojection.appselector.MediaProjectionModule;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.motiontool.MotionToolModule;
@@ -250,8 +252,8 @@
     @Provides
     @SystemUser
     static Monitor provideSystemUserMonitor(@Main Executor executor,
-            SystemProcessCondition systemProcessCondition) {
-        return new Monitor(executor, Collections.singleton(systemProcessCondition));
+            SystemProcessCondition systemProcessCondition, @MonitorLog TableLogBuffer logBuffer) {
+        return new Monitor(executor, Collections.singleton(systemProcessCondition), logBuffer);
     }
 
     @BindsOptionalOf
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
index 17d2332..b71871e 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
@@ -31,6 +31,7 @@
 import com.android.wm.shell.dagger.WMSingleton;
 import com.android.wm.shell.desktopmode.DesktopMode;
 import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
+import com.android.wm.shell.keyguard.KeyguardTransitions;
 import com.android.wm.shell.onehanded.OneHanded;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.recents.RecentTasks;
@@ -99,6 +100,9 @@
     ShellTransitions getTransitions();
 
     @WMSingleton
+    KeyguardTransitions getKeyguardTransitions();
+
+    @WMSingleton
     Optional<StartingSurface> getStartingSurface();
 
     @WMSingleton
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 26fd086..d6c0829 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -63,7 +63,7 @@
 
     // TODO(b/279735475): Tracking Bug
     @JvmField
-    val NEW_LIGHT_BAR_LOGIC = unreleasedFlag(279735475, "new_light_bar_logic", teamfood = true)
+    val NEW_LIGHT_BAR_LOGIC = releasedFlag(279735475, "new_light_bar_logic")
 
     /**
      * This flag is server-controlled and should stay as [unreleasedFlag] since we never want to
@@ -88,8 +88,7 @@
     // TODO(b/278873737): Tracking Bug
     @JvmField
     val LOAD_NOTIFICATIONS_BEFORE_THE_USER_SWITCH_IS_COMPLETE =
-            unreleasedFlag(278873737, "load_notifications_before_the_user_switch_is_complete",
-                    teamfood = true)
+            releasedFlag(278873737, "load_notifications_before_the_user_switch_is_complete")
 
     // TODO(b/277338665): Tracking Bug
     @JvmField
@@ -105,6 +104,16 @@
     val SENSITIVE_REVEAL_ANIM =
         unreleasedFlag(268005230, "sensitive_reveal_anim", teamfood = true)
 
+    // TODO(b/280783617): Tracking Bug
+    @Keep
+    @JvmField
+    val BUILDER_EXTRAS_OVERRIDE =
+            sysPropBooleanFlag(
+                    128,
+                    "persist.sysui.notification.builder_extras_override",
+                    default = false
+            )
+
     // 200 - keyguard/lockscreen
     // ** Flag retired **
     // public static final BooleanFlag KEYGUARD_LAYOUT =
@@ -120,7 +129,12 @@
         resourceBooleanFlag(204, R.bool.config_enableBouncerUserSwitcher, "bouncer_user_switcher")
 
     // TODO(b/254512676): Tracking Bug
-    @JvmField val LOCKSCREEN_CUSTOM_CLOCKS = releasedFlag(207, "lockscreen_custom_clocks")
+    @JvmField
+    val LOCKSCREEN_CUSTOM_CLOCKS = resourceBooleanFlag(
+        207,
+        R.bool.config_enableLockScreenCustomClocks,
+        "lockscreen_custom_clocks"
+    )
 
     // TODO(b/275694445): Tracking Bug
     @JvmField
@@ -132,7 +146,7 @@
      * the digits when the clock moves.
      */
     @JvmField
-    val STEP_CLOCK_ANIMATION = unreleasedFlag(212, "step_clock_animation", teamfood = true)
+    val STEP_CLOCK_ANIMATION = releasedFlag(212, "step_clock_animation")
 
     /**
      * Migration from the legacy isDozing/dozeAmount paths to the new KeyguardTransitionRepository
@@ -161,6 +175,7 @@
      * Migrates control of the LightRevealScrim's reveal effect and amount from legacy code to the
      * new KeyguardTransitionRepository.
      */
+    // TODO(b/281655028): Tracking bug
     @JvmField
     val LIGHT_REVEAL_MIGRATION = unreleasedFlag(218, "light_reveal_migration", teamfood = false)
 
@@ -212,6 +227,7 @@
             )
 
     /** Whether to use a new data source for intents to run on keyguard dismissal. */
+    // TODO(b/275069969): Tracking bug.
     @JvmField
     val REFACTOR_KEYGUARD_DISMISS_INTENT = unreleasedFlag(231, "refactor_keyguard_dismiss_intent")
 
@@ -237,6 +253,16 @@
     @JvmField
     val DELAY_BOUNCER = unreleasedFlag(235, "delay_bouncer")
 
+    /** Migrate the indication area to the new keyguard root view. */
+    // TODO(b/280067944): Tracking bug.
+    @JvmField
+    val MIGRATE_INDICATION_AREA = unreleasedFlag(236, "migrate_indication_area")
+
+    /** Whether to listen for fingerprint authentication over keyguard occluding activities. */
+    // TODO(b/283260512): Tracking bug.
+    @JvmField
+    val FP_LISTEN_OCCLUDING_APPS = unreleasedFlag(237, "fp_listen_occluding_apps")
+
     // 300 - power menu
     // TODO(b/254512600): Tracking Bug
     @JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite")
@@ -333,8 +359,7 @@
 
     // TODO(b/280426085): Tracking Bug
     @JvmField
-    val NEW_BLUETOOTH_REPOSITORY =
-        unreleasedFlag(612, "new_bluetooth_repository", teamfood = true)
+    val NEW_BLUETOOTH_REPOSITORY = unreleasedFlag(612, "new_bluetooth_repository")
 
     // 700 - dialer/calls
     // TODO(b/254512734): Tracking Bug
@@ -382,8 +407,6 @@
     // TODO(b/254513168): Tracking Bug
     @JvmField val UMO_SURFACE_RIPPLE = releasedFlag(907, "umo_surface_ripple")
 
-    @JvmField val MEDIA_FALSING_PENALTY = releasedFlag(908, "media_falsing_media")
-
     // TODO(b/261734857): Tracking Bug
     @JvmField val UMO_TURBULENCE_NOISE = releasedFlag(909, "umo_turbulence_noise")
 
@@ -512,13 +535,6 @@
     val ENABLE_PIP_APP_ICON_OVERLAY =
         sysPropBooleanFlag(1115, "persist.wm.debug.enable_pip_app_icon_overlay", default = true)
 
-    // TODO(b/272110828): Tracking bug
-    @Keep
-    @JvmField
-    val ENABLE_MOVE_FLOATING_WINDOW_IN_TABLETOP =
-        sysPropBooleanFlag(
-            1116, "persist.wm.debug.enable_move_floating_window_in_tabletop", default = true)
-
     // TODO(b/273443374): Tracking Bug
     @Keep
     @JvmField val LOCKSCREEN_LIVE_WALLPAPER =
@@ -557,7 +573,7 @@
 
     // TODO(b/270987164): Tracking Bug
     @JvmField
-    val TRACKPAD_GESTURE_FEATURES = releasedFlag(1205, "trackpad_gesture_features")
+    val TRACKPAD_GESTURE_FEATURES = unreleasedFlag(1205, "trackpad_gesture_features", teamfood = true)
 
     // TODO(b/263826204): Tracking Bug
     @JvmField
@@ -602,13 +618,12 @@
         unreleasedFlag(1401, "quick_tap_flow_framework", teamfood = false)
 
     // 1500 - chooser aka sharesheet
-    // TODO(b/254512507): Tracking Bug
-    val CHOOSER_UNBUNDLED = releasedFlag(1500, "chooser_unbundled")
 
     // 1700 - clipboard
     @JvmField val CLIPBOARD_REMOTE_BEHAVIOR = releasedFlag(1701, "clipboard_remote_behavior")
     // TODO(b/278714186) Tracking Bug
-    @JvmField val CLIPBOARD_IMAGE_TIMEOUT = unreleasedFlag(1702, "clipboard_image_timeout")
+    @JvmField val CLIPBOARD_IMAGE_TIMEOUT =
+            unreleasedFlag(1702, "clipboard_image_timeout", teamfood = true)
     // TODO(b/279405451): Tracking Bug
     @JvmField
     val CLIPBOARD_SHARED_TRANSITIONS = unreleasedFlag(1703, "clipboard_shared_transitions")
@@ -660,14 +675,14 @@
     val WARN_ON_BLOCKING_BINDER_TRANSACTIONS =
         unreleasedFlag(2400, "warn_on_blocking_binder_transactions")
 
-    // 2500 - output switcher
-    // TODO(b/261538825): Tracking Bug
+    // TODO(b/283071711): Tracking bug
     @JvmField
-    val OUTPUT_SWITCHER_ADVANCED_LAYOUT = releasedFlag(2500, "output_switcher_advanced_layout")
+    val TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK =
+            unreleasedFlag(2401, "trim_resources_with_background_trim_on_lock")
+
+    // TODO:(b/283203305): Tracking bug
     @JvmField
-    val OUTPUT_SWITCHER_ROUTES_PROCESSING = releasedFlag(2501, "output_switcher_routes_processing")
-    @JvmField
-    val OUTPUT_SWITCHER_DEVICE_STATUS = releasedFlag(2502, "output_switcher_device_status")
+    val TRIM_FONT_CACHES_AT_UNLOCK = releasedFlag(2402, "trim_font_caches_on_unlock")
 
     // 2700 - unfold transitions
     // TODO(b/265764985): Tracking Bug
@@ -704,11 +719,6 @@
     val LARGE_SHADE_GRANULAR_ALPHA_INTERPOLATION =
             releasedFlag(2602, "large_shade_granular_alpha_interpolation")
 
-    // TODO(b/272805037): Tracking Bug
-    @JvmField
-    val ADVANCED_VPN_ENABLED = releasedFlag(2800, name = "AdvancedVpn__enable_feature",
-            namespace = "vpn")
-
     // TODO(b/277201412): Tracking Bug
     @JvmField
     val SPLIT_SHADE_SUBPIXEL_OPTIMIZATION =
@@ -717,4 +727,13 @@
     // TODO(b/278761837): Tracking Bug
     @JvmField
     val USE_NEW_ACTIVITY_STARTER = releasedFlag(2801, name = "use_new_activity_starter")
+
+    // TODO(b/283084712): Tracking Bug
+    @JvmField
+    val IMPROVED_HUN_ANIMATIONS = unreleasedFlag(283084712, "improved_hun_animations")
+
+    // TODO(b/283447257): Tracking bug
+    @JvmField
+    val BIGPICTURE_NOTIFICATION_LAZY_LOADING =
+            unreleasedFlag(283447257, "bigpicture_notification_lazy_loading")
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/KeyboardBacklightDialogCoordinator.kt b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/KeyboardBacklightDialogCoordinator.kt
index 5e806b6..1f421fa 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/KeyboardBacklightDialogCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/KeyboardBacklightDialogCoordinator.kt
@@ -21,41 +21,44 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyboard.backlight.ui.view.KeyboardBacklightDialog
+import com.android.systemui.keyboard.backlight.ui.viewmodel.BacklightDialogContentViewModel
 import com.android.systemui.keyboard.backlight.ui.viewmodel.BacklightDialogViewModel
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
 
+private fun defaultCreateDialog(context: Context): (Int, Int) -> KeyboardBacklightDialog {
+    return { currentLevel: Int, maxLevel: Int ->
+        KeyboardBacklightDialog(context, currentLevel, maxLevel)
+    }
+}
+
 /**
  * Based on the state produced from [BacklightDialogViewModel] shows or hides keyboard backlight
  * indicator
  */
 @SysUISingleton
 class KeyboardBacklightDialogCoordinator
-@Inject
 constructor(
     @Application private val applicationScope: CoroutineScope,
-    private val context: Context,
     private val viewModel: BacklightDialogViewModel,
+    private val createDialog: (Int, Int) -> KeyboardBacklightDialog
 ) {
 
+    @Inject
+    constructor(
+        @Application applicationScope: CoroutineScope,
+        context: Context,
+        viewModel: BacklightDialogViewModel
+    ) : this(applicationScope, viewModel, defaultCreateDialog(context))
+
     var dialog: KeyboardBacklightDialog? = null
 
     fun startListening() {
         applicationScope.launch {
-            viewModel.dialogContent.collect { dialogViewModel ->
-                if (dialogViewModel != null) {
-                    if (dialog == null) {
-                        dialog =
-                            KeyboardBacklightDialog(
-                                context,
-                                initialCurrentLevel = dialogViewModel.currentValue,
-                                initialMaxLevel = dialogViewModel.maxValue
-                            )
-                        dialog?.show()
-                    } else {
-                        dialog?.updateState(dialogViewModel.currentValue, dialogViewModel.maxValue)
-                    }
+            viewModel.dialogContent.collect { contentModel ->
+                if (contentModel != null) {
+                    showDialog(contentModel)
                 } else {
                     dialog?.dismiss()
                     dialog = null
@@ -63,4 +66,15 @@
             }
         }
     }
+
+    private fun showDialog(model: BacklightDialogContentViewModel) {
+        if (dialog == null) {
+            dialog = createDialog(model.currentValue, model.maxValue)
+        } else {
+            dialog?.updateState(model.currentValue, model.maxValue)
+        }
+        // let's always show dialog - even if we're just updating it, it might have been dismissed
+        // externally by tapping finger outside of it
+        dialog?.show()
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
index d3678b5..7078341 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
@@ -22,9 +22,12 @@
 import android.app.Dialog
 import android.content.Context
 import android.graphics.drawable.ShapeDrawable
+import android.graphics.drawable.shapes.OvalShape
 import android.graphics.drawable.shapes.RoundRectShape
 import android.os.Bundle
 import android.view.Gravity
+import android.view.View
+import android.view.ViewGroup.MarginLayoutParams
 import android.view.Window
 import android.view.WindowManager
 import android.widget.FrameLayout
@@ -32,9 +35,10 @@
 import android.widget.LinearLayout
 import android.widget.LinearLayout.LayoutParams
 import android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
+import androidx.annotation.IdRes
+import androidx.core.view.setPadding
 import com.android.settingslib.Utils
 import com.android.systemui.R
-import com.android.systemui.util.children
 
 class KeyboardBacklightDialog(
     context: Context,
@@ -51,7 +55,7 @@
     private data class BacklightIconProperties(
         val width: Int,
         val height: Int,
-        val leftMargin: Int,
+        val padding: Int,
     )
 
     private data class StepViewProperties(
@@ -71,6 +75,7 @@
     private lateinit var rootProperties: RootProperties
     private lateinit var iconProperties: BacklightIconProperties
     private lateinit var stepProperties: StepViewProperties
+
     @ColorInt
     var filledRectangleColor = getColorFromStyle(com.android.internal.R.attr.materialColorPrimary)
     @ColorInt
@@ -78,7 +83,16 @@
         getColorFromStyle(com.android.internal.R.attr.materialColorOutlineVariant)
     @ColorInt
     var backgroundColor = getColorFromStyle(com.android.internal.R.attr.materialColorSurfaceBright)
-    @ColorInt var iconColor = getColorFromStyle(com.android.internal.R.attr.materialColorOnPrimary)
+    @ColorInt
+    var defaultIconColor = getColorFromStyle(com.android.internal.R.attr.materialColorOnPrimary)
+    @ColorInt
+    var defaultIconBackgroundColor =
+        getColorFromStyle(com.android.internal.R.attr.materialColorPrimary)
+    @ColorInt
+    var dimmedIconColor = getColorFromStyle(com.android.internal.R.attr.materialColorOnSurface)
+    @ColorInt
+    var dimmedIconBackgroundColor =
+        getColorFromStyle(com.android.internal.R.attr.materialColorSurfaceDim)
 
     init {
         currentLevel = initialCurrentLevel
@@ -111,8 +125,7 @@
                 BacklightIconProperties(
                     width = getDimensionPixelSize(R.dimen.backlight_indicator_icon_width),
                     height = getDimensionPixelSize(R.dimen.backlight_indicator_icon_height),
-                    leftMargin =
-                        getDimensionPixelSize(R.dimen.backlight_indicator_icon_left_margin),
+                    padding = getDimensionPixelSize(R.dimen.backlight_indicator_icon_padding),
                 )
             stepProperties =
                 StepViewProperties(
@@ -139,23 +152,34 @@
         if (maxLevel != max || forceRefresh) {
             maxLevel = max
             rootView.removeAllViews()
+            rootView.addView(buildIconTile())
             buildStepViews().forEach { rootView.addView(it) }
         }
         currentLevel = current
-        updateLevel()
+        updateIconTile()
+        updateStepColors()
     }
 
-    private fun updateLevel() {
-        rootView.children.forEachIndexed(
-            action = { index, v ->
-                val drawable = v.background as ShapeDrawable
-                if (index <= currentLevel) {
-                    updateColor(drawable, filledRectangleColor)
-                } else {
-                    updateColor(drawable, emptyRectangleColor)
-                }
-            }
-        )
+    private fun updateIconTile() {
+        val iconTile = rootView.findViewById(BACKLIGHT_ICON_ID) as ImageView
+        val backgroundDrawable = iconTile.background as ShapeDrawable
+        if (currentLevel == 0) {
+            iconTile.setColorFilter(dimmedIconColor)
+            updateColor(backgroundDrawable, dimmedIconBackgroundColor)
+        } else {
+            iconTile.setColorFilter(defaultIconColor)
+            updateColor(backgroundDrawable, defaultIconBackgroundColor)
+        }
+    }
+
+    private fun updateStepColors() {
+        (1 until rootView.childCount).forEach { index ->
+            val drawable = rootView.getChildAt(index).background as ShapeDrawable
+            updateColor(
+                drawable,
+                if (index <= currentLevel) filledRectangleColor else emptyRectangleColor,
+            )
+        }
     }
 
     private fun updateColor(drawable: ShapeDrawable, @ColorInt color: Int) {
@@ -192,9 +216,33 @@
     }
 
     private fun buildStepViews(): List<FrameLayout> {
-        val stepViews = (0..maxLevel).map { i -> createStepViewAt(i) }
-        stepViews[0].addView(createBacklightIconView())
-        return stepViews
+        return (1..maxLevel).map { i -> createStepViewAt(i) }
+    }
+
+    private fun buildIconTile(): View {
+        val diameter = stepProperties.height
+        val circleDrawable =
+            ShapeDrawable(OvalShape()).apply {
+                intrinsicHeight = diameter
+                intrinsicWidth = diameter
+            }
+
+        return ImageView(context).apply {
+            setImageResource(R.drawable.ic_keyboard_backlight)
+            id = BACKLIGHT_ICON_ID
+            setColorFilter(defaultIconColor)
+            setPadding(iconProperties.padding)
+            layoutParams =
+                MarginLayoutParams(diameter, diameter).apply {
+                    setMargins(
+                        /* left= */ stepProperties.horizontalMargin,
+                        /* top= */ 0,
+                        /* right= */ stepProperties.horizontalMargin,
+                        /* bottom= */ 0
+                    )
+                }
+            background = circleDrawable
+        }
     }
 
     private fun createStepViewAt(i: Int): FrameLayout {
@@ -221,18 +269,6 @@
         }
     }
 
-    private fun createBacklightIconView(): ImageView {
-        return ImageView(context).apply {
-            setImageResource(R.drawable.ic_keyboard_backlight)
-            setColorFilter(iconColor)
-            layoutParams =
-                FrameLayout.LayoutParams(iconProperties.width, iconProperties.height).apply {
-                    gravity = Gravity.CENTER
-                    leftMargin = iconProperties.leftMargin
-                }
-        }
-    }
-
     private fun setWindowPosition() {
         window?.apply {
             setGravity(Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL)
@@ -262,30 +298,29 @@
     private fun radiiForIndex(i: Int, last: Int): FloatArray {
         val smallRadius = stepProperties.smallRadius
         val largeRadius = stepProperties.largeRadius
-        return when (i) {
-            0 -> // left radii bigger
-            floatArrayOf(
-                    largeRadius,
-                    largeRadius,
-                    smallRadius,
-                    smallRadius,
-                    smallRadius,
-                    smallRadius,
-                    largeRadius,
-                    largeRadius
-                )
-            last -> // right radii bigger
-            floatArrayOf(
-                    smallRadius,
-                    smallRadius,
-                    largeRadius,
-                    largeRadius,
-                    largeRadius,
-                    largeRadius,
-                    smallRadius,
-                    smallRadius
-                )
-            else -> FloatArray(8) { smallRadius } // all radii equal
+        val radii = FloatArray(8) { smallRadius }
+        if (i == 1) {
+            radii.setLeftCorners(largeRadius)
         }
+        // note "first" and "last" might be the same tile
+        if (i == last) {
+            radii.setRightCorners(largeRadius)
+        }
+        return radii
+    }
+
+    private fun FloatArray.setLeftCorners(radius: Float) {
+        LEFT_CORNERS_INDICES.forEach { this[it] = radius }
+    }
+    private fun FloatArray.setRightCorners(radius: Float) {
+        RIGHT_CORNERS_INDICES.forEach { this[it] = radius }
+    }
+
+    private companion object {
+        @IdRes val BACKLIGHT_ICON_ID = R.id.backlight_icon
+
+        // indices used to define corners radii in ShapeDrawable
+        val LEFT_CORNERS_INDICES: IntArray = intArrayOf(0, 1, 6, 7)
+        val RIGHT_CORNERS_INDICES: IntArray = intArrayOf(2, 3, 4, 5)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 8b6bd24..a8d22c4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -19,9 +19,7 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.view.RemoteAnimationTarget.MODE_CLOSING;
 import static android.view.RemoteAnimationTarget.MODE_OPENING;
-import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
-import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
@@ -31,21 +29,16 @@
 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM;
 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
 import static android.view.WindowManager.TRANSIT_OLD_NONE;
-import static android.view.WindowManager.TRANSIT_OPEN;
-import static android.view.WindowManager.TRANSIT_TO_BACK;
-import static android.view.WindowManager.TRANSIT_TO_FRONT;
 import static android.view.WindowManager.TransitionFlags;
 import static android.view.WindowManager.TransitionOldType;
 import static android.view.WindowManager.TransitionType;
-import static android.window.TransitionInfo.FLAG_OCCLUDES_KEYGUARD;
 
+import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.app.Service;
 import android.app.WindowConfiguration;
 import android.content.Intent;
-import android.graphics.Point;
-import android.graphics.Rect;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Debug;
@@ -67,10 +60,9 @@
 import android.view.WindowManagerPolicyConstants;
 import android.window.IRemoteTransition;
 import android.window.IRemoteTransitionFinishedCallback;
-import android.window.RemoteTransition;
-import android.window.TransitionFilter;
 import android.window.TransitionInfo;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.policy.IKeyguardDrawnCallback;
 import com.android.internal.policy.IKeyguardExitCallback;
@@ -81,6 +73,7 @@
 import com.android.systemui.settings.DisplayTracker;
 import com.android.wm.shell.transition.ShellTransitions;
 import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.util.TransitionUtil;
 
 import java.util.ArrayList;
 
@@ -109,7 +102,8 @@
         }
     }
 
-    private static RemoteAnimationTarget[] wrap(TransitionInfo info, boolean wallpapers) {
+    private static RemoteAnimationTarget[] wrap(TransitionInfo info, boolean wallpapers,
+            SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
         final ArrayList<RemoteAnimationTarget> out = new ArrayList<>();
         for (int i = 0; i < info.getChanges().size(); i++) {
             boolean changeIsWallpaper =
@@ -119,39 +113,26 @@
             final TransitionInfo.Change change = info.getChanges().get(i);
             final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
             final int taskId = taskInfo != null ? change.getTaskInfo().taskId : -1;
-            boolean isNotInRecents;
-            WindowConfiguration windowConfiguration = null;
-            if (taskInfo != null) {
-                if (taskInfo.getConfiguration() != null) {
-                    windowConfiguration =
-                            change.getTaskInfo().getConfiguration().windowConfiguration;
-                }
-                isNotInRecents = !change.getTaskInfo().isRunning;
-            } else {
-                isNotInRecents = true;
-            }
-            Rect localBounds = new Rect(change.getEndAbsBounds());
-            localBounds.offsetTo(change.getEndRelOffset().x, change.getEndRelOffset().y);
 
-            final RemoteAnimationTarget target = new RemoteAnimationTarget(
-                    taskId,
-                    newModeToLegacyMode(change.getMode()),
-                    change.getLeash(),
-                    (change.getFlags() & TransitionInfo.FLAG_TRANSLUCENT) != 0
-                            || (change.getFlags() & TransitionInfo.FLAG_SHOW_WALLPAPER) != 0,
-                    null /* clipRect */,
-                    new Rect(0, 0, 0, 0) /* contentInsets */,
-                    info.getChanges().size() - i,
-                    new Point(), localBounds, new Rect(change.getEndAbsBounds()),
-                    windowConfiguration, isNotInRecents, null /* startLeash */,
-                    change.getStartAbsBounds(), taskInfo, false /* allowEnterPip */);
-            // Use hasAnimatingParent to mark the anything below root task
             if (taskId != -1 && change.getParent() != null) {
                 final TransitionInfo.Change parentChange = info.getChange(change.getParent());
                 if (parentChange != null && parentChange.getTaskInfo() != null) {
-                    target.hasAnimatingParent = true;
+                    // Only adding the root task as the animation target.
+                    continue;
                 }
             }
+
+            // Avoid wrapping non-task and non-wallpaper changes as they don't need to animate
+            // for keyguard unlock animation.
+            if (taskId < 0 && !wallpapers) continue;
+
+            final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
+                    // wallpapers go into the "below" layer space
+                    info.getChanges().size() - i,
+                    // keyguard treats wallpaper as translucent
+                    (change.getFlags() & TransitionInfo.FLAG_SHOW_WALLPAPER) != 0,
+                    info, t, leashMap);
+
             out.add(target);
         }
         return out.toArray(new RemoteAnimationTarget[out.size()]);
@@ -164,8 +145,8 @@
             return apps.length == 0 ? TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER
                     : TRANSIT_OLD_KEYGUARD_GOING_AWAY;
         } else if (type == TRANSIT_KEYGUARD_OCCLUDE) {
-            boolean isOccludeByDream = apps.length > 0 && apps[0].taskInfo.topActivityType
-                    == WindowConfiguration.ACTIVITY_TYPE_DREAM;
+            boolean isOccludeByDream = apps.length > 0 && apps[0].taskInfo != null
+                    && apps[0].taskInfo.topActivityType == WindowConfiguration.ACTIVITY_TYPE_DREAM;
             if (isOccludeByDream) return TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM;
             return TRANSIT_OLD_KEYGUARD_OCCLUDE;
         } else if (type == TRANSIT_KEYGUARD_UNOCCLUDE) {
@@ -178,77 +159,85 @@
 
     // Wrap Keyguard going away animation.
     // Note: Also used for wrapping occlude by Dream animation. It works (with some redundancy).
-    private static IRemoteTransition wrap(IRemoteAnimationRunner runner) {
+    public static IRemoteTransition wrap(IRemoteAnimationRunner runner) {
         return new IRemoteTransition.Stub() {
-            final ArrayMap<IBinder, IRemoteTransitionFinishedCallback> mFinishCallbacks =
-                    new ArrayMap<>();
+
+            private final ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = new ArrayMap<>();
+
+            @GuardedBy("mLeashMap")
+            private IRemoteTransitionFinishedCallback mFinishCallback = null;
 
             @Override
             public void startAnimation(IBinder transition, TransitionInfo info,
                     SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback)
                     throws RemoteException {
                 Slog.d(TAG, "Starts IRemoteAnimationRunner: info=" + info);
-                final RemoteAnimationTarget[] apps = wrap(info, false /* wallpapers */);
-                final RemoteAnimationTarget[] wallpapers = wrap(info, true /* wallpapers */);
-                final RemoteAnimationTarget[] nonApps = new RemoteAnimationTarget[0];
 
-                // Sets the alpha to 0 for the opening root task for fade in animation. And since
-                // the fade in animation can only apply on the first opening app, so set alpha to 1
-                // for anything else.
-                boolean foundOpening = false;
-                for (RemoteAnimationTarget target : apps) {
-                    if (target.taskId != -1
-                            && target.mode == RemoteAnimationTarget.MODE_OPENING
-                            && !target.hasAnimatingParent) {
-                        if (foundOpening) {
-                            Log.w(TAG, "More than one opening target");
-                            t.setAlpha(target.leash, 1.0f);
-                            continue;
+                synchronized (mLeashMap) {
+                    final RemoteAnimationTarget[] apps =
+                            wrap(info, false /* wallpapers */, t, mLeashMap);
+                    final RemoteAnimationTarget[] wallpapers =
+                            wrap(info, true /* wallpapers */, t, mLeashMap);
+                    final RemoteAnimationTarget[] nonApps = new RemoteAnimationTarget[0];
+
+                    // Set alpha back to 1 for the independent changes because we will be animating
+                    // children instead.
+                    for (TransitionInfo.Change chg : info.getChanges()) {
+                        if (TransitionInfo.isIndependent(chg, info)) {
+                            t.setAlpha(chg.getLeash(), 1.f);
                         }
-                        t.setAlpha(target.leash, 0.0f);
-                        foundOpening = true;
-                    } else {
-                        t.setAlpha(target.leash, 1.0f);
                     }
-                }
-                t.apply();
-                synchronized (mFinishCallbacks) {
-                    mFinishCallbacks.put(transition, finishCallback);
-                }
-                runner.onAnimationStart(getTransitionOldType(info.getType(), info.getFlags(), apps),
-                        apps, wallpapers, nonApps,
-                        new IRemoteAnimationFinishedCallback.Stub() {
-                            @Override
-                            public void onAnimationFinished() throws RemoteException {
-                                synchronized (mFinishCallbacks) {
-                                    if (mFinishCallbacks.remove(transition) == null) return;
+                    initAlphaForAnimationTargets(t, apps);
+                    initAlphaForAnimationTargets(t, wallpapers);
+                    t.apply();
+                    mFinishCallback = finishCallback;
+                    runner.onAnimationStart(
+                            getTransitionOldType(info.getType(), info.getFlags(), apps),
+                            apps, wallpapers, nonApps,
+                            new IRemoteAnimationFinishedCallback.Stub() {
+                                @Override
+                                public void onAnimationFinished() throws RemoteException {
+                                    synchronized (mLeashMap) {
+                                        Slog.d(TAG, "Finish IRemoteAnimationRunner.");
+                                        finish();
+                                    }
                                 }
-                                info.releaseAllSurfaces();
-                                Slog.d(TAG, "Finish IRemoteAnimationRunner.");
-                                finishCallback.onTransitionFinished(null /* wct */, null /* t */);
                             }
-                        }
-                );
+                    );
+                }
             }
 
             public void mergeAnimation(IBinder candidateTransition, TransitionInfo candidateInfo,
                     SurfaceControl.Transaction candidateT, IBinder currentTransition,
-                    IRemoteTransitionFinishedCallback candidateFinishCallback) {
+                    IRemoteTransitionFinishedCallback candidateFinishCallback)
+                    throws RemoteException {
                 try {
-                    final IRemoteTransitionFinishedCallback currentFinishCB;
-                    synchronized (mFinishCallbacks) {
-                        currentFinishCB = mFinishCallbacks.remove(currentTransition);
+                    synchronized (mLeashMap) {
+                        runner.onAnimationCancelled();
+                        finish();
                     }
-                    if (currentFinishCB == null) {
-                        Slog.e(TAG, "Called mergeAnimation, but finish callback is missing");
-                        return;
-                    }
-                    runner.onAnimationCancelled();
-                    currentFinishCB.onTransitionFinished(null /* wct */, null /* t */);
                 } catch (RemoteException e) {
                     // nothing, we'll just let it finish on its own I guess.
                 }
             }
+
+            private static void initAlphaForAnimationTargets(@NonNull SurfaceControl.Transaction t,
+                    @NonNull RemoteAnimationTarget[] targets) {
+                for (RemoteAnimationTarget target : targets) {
+                    if (target.mode != MODE_OPENING) continue;
+                    t.setAlpha(target.leash, 0.f);
+                }
+            }
+
+            @GuardedBy("mLeashMap")
+            private void finish() throws RemoteException {
+                mLeashMap.clear();
+                final IRemoteTransitionFinishedCallback finishCallback = mFinishCallback;
+                if (finishCallback != null) {
+                    mFinishCallback = null;
+                    finishCallback.onTransitionFinished(null /* wct */, null /* t */);
+                }
+            }
         };
     }
 
@@ -273,7 +262,8 @@
         if (mShellTransitions == null || !Transitions.ENABLE_SHELL_TRANSITIONS) {
             RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
             final RemoteAnimationAdapter exitAnimationAdapter =
-                    new RemoteAnimationAdapter(mExitAnimationRunner, 0, 0);
+                    new RemoteAnimationAdapter(
+                            mKeyguardViewMediator.getExitAnimationRunner(), 0, 0);
             definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY,
                     exitAnimationAdapter);
             definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
@@ -297,92 +287,7 @@
                     unoccludeAnimationAdapter);
             ActivityTaskManager.getInstance().registerRemoteAnimationsForDisplay(
                     mDisplayTracker.getDefaultDisplayId(), definition);
-            return;
         }
-        Slog.d(TAG, "KeyguardService registerRemote: TRANSIT_KEYGUARD_GOING_AWAY");
-        TransitionFilter f = new TransitionFilter();
-        f.mFlags = TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
-        mShellTransitions.registerRemote(f, new RemoteTransition(
-                wrap(mExitAnimationRunner), getIApplicationThread(), "ExitKeyguard"));
-
-        Slog.d(TAG, "KeyguardService registerRemote: TRANSIT_KEYGUARD_(UN)OCCLUDE");
-        // Register for occluding
-        final RemoteTransition occludeTransition = new RemoteTransition(
-                mOccludeAnimation, getIApplicationThread(), "KeyguardOcclude");
-        f = new TransitionFilter();
-        f.mFlags = TRANSIT_FLAG_KEYGUARD_LOCKED;
-        f.mRequirements = new TransitionFilter.Requirement[]{
-                new TransitionFilter.Requirement(), new TransitionFilter.Requirement()};
-        // First require at-least one app showing that occludes.
-        f.mRequirements[0].mMustBeIndependent = false;
-        f.mRequirements[0].mFlags = FLAG_OCCLUDES_KEYGUARD;
-        f.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
-        // Then require that we aren't closing any occludes (because this would mean a
-        // regular task->task or activity->activity animation not involving keyguard).
-        f.mRequirements[1].mNot = true;
-        f.mRequirements[1].mMustBeIndependent = false;
-        f.mRequirements[1].mFlags = FLAG_OCCLUDES_KEYGUARD;
-        f.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
-        mShellTransitions.registerRemote(f, occludeTransition);
-
-        // Now register for un-occlude.
-        final RemoteTransition unoccludeTransition = new RemoteTransition(
-                mUnoccludeAnimation, getIApplicationThread(), "KeyguardUnocclude");
-        f = new TransitionFilter();
-        f.mFlags = TRANSIT_FLAG_KEYGUARD_LOCKED;
-        f.mRequirements = new TransitionFilter.Requirement[]{
-                new TransitionFilter.Requirement(), new TransitionFilter.Requirement()};
-        // First require at-least one app going-away (doesn't need occlude flag
-        // as that is implicit by it having been visible and we don't want to exclude
-        // cases where we are un-occluding because the app removed its showWhenLocked
-        // capability at runtime).
-        f.mRequirements[1].mMustBeIndependent = false;
-        f.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
-        f.mRequirements[1].mMustBeTask = true;
-        // Then require that we aren't opening any occludes (otherwise we'd remain
-        // occluded).
-        f.mRequirements[0].mNot = true;
-        f.mRequirements[0].mMustBeIndependent = false;
-        f.mRequirements[0].mFlags = FLAG_OCCLUDES_KEYGUARD;
-        f.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
-        mShellTransitions.registerRemote(f, unoccludeTransition);
-
-        // Register for specific transition type.
-        // Above filter cannot fulfill all conditions.
-        // E.g. close top activity while screen off but next activity is occluded, this should
-        // an occluded transition, but since the activity is invisible, the condition would
-        // match unoccluded transition.
-        // But on the contrary, if we add above condition in occluded transition, then when user
-        // trying to dismiss occluded activity when unlock keyguard, the condition would match
-        // occluded transition.
-        f = new TransitionFilter();
-        f.mTypeSet = new int[]{TRANSIT_KEYGUARD_OCCLUDE};
-        mShellTransitions.registerRemote(f, occludeTransition);
-
-        f = new TransitionFilter();
-        f.mTypeSet = new int[]{TRANSIT_KEYGUARD_UNOCCLUDE};
-        mShellTransitions.registerRemote(f, unoccludeTransition);
-
-        Slog.d(TAG, "KeyguardService registerRemote: TRANSIT_KEYGUARD_OCCLUDE for DREAM");
-        // Register for occluding by Dream
-        f = new TransitionFilter();
-        f.mFlags = TRANSIT_FLAG_KEYGUARD_LOCKED;
-        f.mRequirements = new TransitionFilter.Requirement[]{
-                new TransitionFilter.Requirement(), new TransitionFilter.Requirement()};
-        // First require at-least one app of type DREAM showing that occludes.
-        f.mRequirements[0].mActivityType = WindowConfiguration.ACTIVITY_TYPE_DREAM;
-        f.mRequirements[0].mMustBeIndependent = false;
-        f.mRequirements[0].mFlags = FLAG_OCCLUDES_KEYGUARD;
-        f.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
-        // Then require that we aren't closing any occludes (because this would mean a
-        // regular task->task or activity->activity animation not involving keyguard).
-        f.mRequirements[1].mNot = true;
-        f.mRequirements[1].mMustBeIndependent = false;
-        f.mRequirements[1].mFlags = FLAG_OCCLUDES_KEYGUARD;
-        f.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
-        mShellTransitions.registerRemote(f, new RemoteTransition(
-                wrap(mKeyguardViewMediator.getOccludeByDreamAnimationRunner()),
-                getIApplicationThread(), "KeyguardOccludeByDream"));
     }
 
     @Override
@@ -402,77 +307,30 @@
         }
     }
 
-    private final IRemoteAnimationRunner.Stub mExitAnimationRunner =
-            new IRemoteAnimationRunner.Stub() {
-        @Override // Binder interface
-        public void onAnimationStart(@WindowManager.TransitionOldType int transit,
-                RemoteAnimationTarget[] apps,
-                RemoteAnimationTarget[] wallpapers,
-                RemoteAnimationTarget[] nonApps,
-                IRemoteAnimationFinishedCallback finishedCallback) {
-            Trace.beginSection("mExitAnimationRunner.onAnimationStart#startKeyguardExitAnimation");
-            checkPermission();
-            mKeyguardViewMediator.startKeyguardExitAnimation(transit, apps, wallpapers,
-                    nonApps, finishedCallback);
-            Trace.endSection();
-        }
-
-        @Override // Binder interface
-        public void onAnimationCancelled() {
-            mKeyguardViewMediator.cancelKeyguardExitAnimation();
-        }
-    };
-
-    final IRemoteTransition mOccludeAnimation = new IRemoteTransition.Stub() {
-        @Override
-        public void startAnimation(IBinder transition, TransitionInfo info,
-                SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback)
-                    throws RemoteException {
-            t.apply();
-            mBinder.setOccluded(true /* isOccluded */, true /* animate */);
-            finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
-            info.releaseAllSurfaces();
-        }
-
-        @Override
-        public void mergeAnimation(IBinder transition, TransitionInfo info,
-                SurfaceControl.Transaction t, IBinder mergeTarget,
-                IRemoteTransitionFinishedCallback finishCallback) {
-            t.close();
-            info.releaseAllSurfaces();
-        }
-    };
-
-    final IRemoteTransition mUnoccludeAnimation = new IRemoteTransition.Stub() {
-        @Override
-        public void startAnimation(IBinder transition, TransitionInfo info,
-                SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback)
-                throws RemoteException {
-            t.apply();
-            mBinder.setOccluded(false /* isOccluded */, true /* animate */);
-            finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
-            info.releaseAllSurfaces();
-        }
-
-        @Override
-        public void mergeAnimation(IBinder transition, TransitionInfo info,
-                SurfaceControl.Transaction t, IBinder mergeTarget,
-                IRemoteTransitionFinishedCallback finishCallback) {
-            t.close();
-            info.releaseAllSurfaces();
-        }
-    };
-
     private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {
+        private static final String TRACK_NAME = "IKeyguardService";
+
+        /**
+         * Helper for tracing the most-recent call on the IKeyguardService interface.
+         * IKeyguardService is oneway, so we are most interested in the order of the calls as they
+         * are received. We use an async track to make it easier to visualize in the trace.
+         * @param name name of the trace section
+         */
+        private static void trace(String name) {
+            Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, TRACK_NAME, 0);
+            Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_APP, TRACK_NAME, name, 0);
+        }
 
         @Override // Binder interface
         public void addStateMonitorCallback(IKeyguardStateCallback callback) {
+            trace("addStateMonitorCallback");
             checkPermission();
             mKeyguardViewMediator.addStateMonitorCallback(callback);
         }
 
         @Override // Binder interface
         public void verifyUnlock(IKeyguardExitCallback callback) {
+            trace("verifyUnlock");
             Trace.beginSection("KeyguardService.mBinder#verifyUnlock");
             checkPermission();
             mKeyguardViewMediator.verifyUnlock(callback);
@@ -481,6 +339,7 @@
 
         @Override // Binder interface
         public void setOccluded(boolean isOccluded, boolean animate) {
+            trace("setOccluded isOccluded=" + isOccluded + " animate=" + animate);
             Log.d(TAG, "setOccluded(" + isOccluded + ")");
 
             Trace.beginSection("KeyguardService.mBinder#setOccluded");
@@ -491,24 +350,28 @@
 
         @Override // Binder interface
         public void dismiss(IKeyguardDismissCallback callback, CharSequence message) {
+            trace("dismiss message=" + message);
             checkPermission();
             mKeyguardViewMediator.dismiss(callback, message);
         }
 
         @Override // Binder interface
         public void onDreamingStarted() {
+            trace("onDreamingStarted");
             checkPermission();
             mKeyguardViewMediator.onDreamingStarted();
         }
 
         @Override // Binder interface
         public void onDreamingStopped() {
+            trace("onDreamingStopped");
             checkPermission();
             mKeyguardViewMediator.onDreamingStopped();
         }
 
         @Override // Binder interface
         public void onStartedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason) {
+            trace("onStartedGoingToSleep pmSleepReason=" + pmSleepReason);
             checkPermission();
             mKeyguardViewMediator.onStartedGoingToSleep(
                     WindowManagerPolicyConstants.translateSleepReasonToOffReason(pmSleepReason));
@@ -519,6 +382,8 @@
         @Override // Binder interface
         public void onFinishedGoingToSleep(
                 @PowerManager.GoToSleepReason int pmSleepReason, boolean cameraGestureTriggered) {
+            trace("onFinishedGoingToSleep pmSleepReason=" + pmSleepReason
+                    + " cameraGestureTriggered=" + cameraGestureTriggered);
             checkPermission();
             mKeyguardViewMediator.onFinishedGoingToSleep(
                     WindowManagerPolicyConstants.translateSleepReasonToOffReason(pmSleepReason),
@@ -530,6 +395,8 @@
         @Override // Binder interface
         public void onStartedWakingUp(
                 @PowerManager.WakeReason int pmWakeReason, boolean cameraGestureTriggered) {
+            trace("onStartedWakingUp pmWakeReason=" + pmWakeReason
+                    + " cameraGestureTriggered=" + cameraGestureTriggered);
             Trace.beginSection("KeyguardService.mBinder#onStartedWakingUp");
             checkPermission();
             mKeyguardViewMediator.onStartedWakingUp(pmWakeReason, cameraGestureTriggered);
@@ -540,6 +407,7 @@
 
         @Override // Binder interface
         public void onFinishedWakingUp() {
+            trace("onFinishedWakingUp");
             Trace.beginSection("KeyguardService.mBinder#onFinishedWakingUp");
             checkPermission();
             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.FINISHED_WAKING_UP);
@@ -548,6 +416,7 @@
 
         @Override // Binder interface
         public void onScreenTurningOn(IKeyguardDrawnCallback callback) {
+            trace("onScreenTurningOn");
             Trace.beginSection("KeyguardService.mBinder#onScreenTurningOn");
             checkPermission();
             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_ON,
@@ -582,6 +451,7 @@
 
         @Override // Binder interface
         public void onScreenTurnedOn() {
+            trace("onScreenTurnedOn");
             Trace.beginSection("KeyguardService.mBinder#onScreenTurnedOn");
             checkPermission();
             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_ON);
@@ -591,12 +461,14 @@
 
         @Override // Binder interface
         public void onScreenTurningOff() {
+            trace("onScreenTurningOff");
             checkPermission();
             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_OFF);
         }
 
         @Override // Binder interface
         public void onScreenTurnedOff() {
+            trace("onScreenTurnedOff");
             checkPermission();
             mKeyguardViewMediator.onScreenTurnedOff();
             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_OFF);
@@ -605,12 +477,14 @@
 
         @Override // Binder interface
         public void setKeyguardEnabled(boolean enabled) {
+            trace("setKeyguardEnabled enabled" + enabled);
             checkPermission();
             mKeyguardViewMediator.setKeyguardEnabled(enabled);
         }
 
         @Override // Binder interface
         public void onSystemReady() {
+            trace("onSystemReady");
             Trace.beginSection("KeyguardService.mBinder#onSystemReady");
             checkPermission();
             mKeyguardViewMediator.onSystemReady();
@@ -619,24 +493,28 @@
 
         @Override // Binder interface
         public void doKeyguardTimeout(Bundle options) {
+            trace("doKeyguardTimeout");
             checkPermission();
             mKeyguardViewMediator.doKeyguardTimeout(options);
         }
 
         @Override // Binder interface
         public void setSwitchingUser(boolean switching) {
+            trace("setSwitchingUser switching=" + switching);
             checkPermission();
             mKeyguardViewMediator.setSwitchingUser(switching);
         }
 
         @Override // Binder interface
         public void setCurrentUser(int userId) {
+            trace("setCurrentUser userId=" + userId);
             checkPermission();
             mKeyguardViewMediator.setCurrentUser(userId);
         }
 
-        @Override
+        @Override // Binder interface
         public void onBootCompleted() {
+            trace("onBootCompleted");
             checkPermission();
             mKeyguardViewMediator.onBootCompleted();
         }
@@ -646,28 +524,33 @@
          * {@code IRemoteAnimationRunner#onAnimationStart} instead.
          */
         @Deprecated
-        @Override
+        @Override // Binder interface
         public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
+            trace("startKeyguardExitAnimation startTime=" + startTime
+                    + " fadeoutDuration=" + fadeoutDuration);
             Trace.beginSection("KeyguardService.mBinder#startKeyguardExitAnimation");
             checkPermission();
             mKeyguardViewMediator.startKeyguardExitAnimation(startTime, fadeoutDuration);
             Trace.endSection();
         }
 
-        @Override
+        @Override // Binder interface
         public void onShortPowerPressedGoHome() {
+            trace("onShortPowerPressedGoHome");
             checkPermission();
             mKeyguardViewMediator.onShortPowerPressedGoHome();
         }
 
-        @Override
+        @Override // Binder interface
         public void dismissKeyguardToLaunch(Intent intentToLaunch) {
+            trace("dismissKeyguardToLaunch");
             checkPermission();
             mKeyguardViewMediator.dismissKeyguardToLaunch(intentToLaunch);
         }
 
-        @Override
+        @Override // Binder interface
         public void onSystemKeyPressed(int keycode) {
+            trace("onSystemKeyPressed keycode=" + keycode);
             checkPermission();
             mKeyguardViewMediator.onSystemKeyPressed(keycode);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index bd6dfe3..29a7fe7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -258,12 +258,10 @@
      */
     private var surfaceBehindAlpha = 1f
 
-    private var wallpaperAlpha = 1f
-
     @VisibleForTesting
     var surfaceBehindAlphaAnimator = ValueAnimator.ofFloat(0f, 1f)
 
-    var wallpaperAlphaAnimator = ValueAnimator.ofFloat(0f, 1f)
+    var wallpaperCannedUnlockAnimator = ValueAnimator.ofFloat(0f, 1f)
 
     /**
      * Matrix applied to [surfaceBehindRemoteAnimationTarget], which is the surface of the
@@ -330,6 +328,7 @@
                     if (surfaceBehindAlpha == 0f) {
                         Log.d(TAG, "surfaceBehindAlphaAnimator#onAnimationEnd")
                         surfaceBehindRemoteAnimationTargets = null
+                        wallpaperTargets = null
                         keyguardViewMediator.get().finishSurfaceBehindRemoteAnimation(
                             false /* cancelled */)
                     } else {
@@ -340,23 +339,17 @@
             })
         }
 
-        with(wallpaperAlphaAnimator) {
+        with(wallpaperCannedUnlockAnimator) {
             duration = LAUNCHER_ICONS_ANIMATION_DURATION_MS
             interpolator = Interpolators.ALPHA_OUT
             addUpdateListener { valueAnimator: ValueAnimator ->
-                wallpaperAlpha = valueAnimator.animatedValue as Float
-                setWallpaperAppearAmount(wallpaperAlpha)
+                setWallpaperAppearAmount(valueAnimator.animatedValue as Float)
             }
             addListener(object : AnimatorListenerAdapter() {
                 override fun onAnimationEnd(animation: Animator) {
-                    Log.d(TAG, "wallpaperAlphaAnimator#onAnimationEnd, animation ended ")
-                    if (wallpaperAlpha == 1f) {
-                        wallpaperTargets = null
-                        keyguardViewMediator.get().finishExitRemoteAnimation()
-                    } else {
-                        Log.d(TAG, "wallpaperAlphaAnimator#onAnimationEnd, " +
-                                "animation was cancelled: skipping finishAnimation()")
-                    }
+                    Log.d(TAG, "wallpaperCannedUnlockAnimator#onAnimationEnd")
+                    keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
+                        false /* cancelled */)
                 }
             })
         }
@@ -387,11 +380,6 @@
             context.resources.getDimensionPixelSize(R.dimen.rounded_corner_radius).toFloat()
     }
 
-    fun isAnyKeyguyardAnimatorPlaying(): Boolean {
-        return surfaceBehindAlphaAnimator.isStarted ||
-                wallpaperAlphaAnimator.isStarted || surfaceBehindEntryAnimator.isStarted
-    }
-
     /**
      * Add a listener to be notified of various stages of the unlock animation.
      */
@@ -536,8 +524,6 @@
         wallpaperTargets = wallpapers
         surfaceBehindRemoteAnimationStartTime = startTime
 
-        fadeInWallpaper()
-
         // If we specifically requested that the surface behind be made visible (vs. it being made
         // visible because we're unlocking), then we're in the middle of a swipe-to-unlock touch
         // gesture and the surface behind the keyguard should be made visible so that we can animate
@@ -599,7 +585,9 @@
         // Finish the keyguard remote animation if the dismiss amount has crossed the threshold.
         // Check it here in case there is no more change to the dismiss amount after the last change
         // that starts the keyguard animation. @see #updateKeyguardViewMediatorIfThresholdsReached()
-        finishKeyguardExitRemoteAnimationIfReachThreshold()
+        if (!playingCannedUnlockAnimation) {
+            finishKeyguardExitRemoteAnimationIfReachThreshold()
+        }
     }
 
     /**
@@ -649,8 +637,10 @@
      * Unlock to the launcher, using in-window animations, and the smartspace shared element
      * transition if possible.
      */
-    private fun unlockToLauncherWithInWindowAnimations() {
-        setSurfaceBehindAppearAmount(1f)
+
+    @VisibleForTesting
+    fun unlockToLauncherWithInWindowAnimations() {
+        setSurfaceBehindAppearAmount(1f, wallpapers = false)
 
         try {
             // Begin the animation, waiting for the shade to animate out.
@@ -674,10 +664,13 @@
 
         // Now that the Launcher surface (with its smartspace positioned identically to ours) is
         // visible, hide our smartspace.
-        lockscreenSmartspace?.visibility = View.INVISIBLE
+        if (lockscreenSmartspace?.visibility == View.VISIBLE) {
+            lockscreenSmartspace?.visibility = View.INVISIBLE
+        }
 
-        // As soon as the shade has animated out of the way, finish the keyguard exit animation. The
-        // in-window animations in the Launcher window will end on their own.
+        // As soon as the shade has animated out of the way, start the canned unlock animation,
+        // which will finish keyguard exit when it completes. The in-window animations in the
+        // Launcher window will end on their own.
         handler.postDelayed({
             if (keyguardViewMediator.get().isShowingAndNotOccluded &&
                 !keyguardStateController.isKeyguardGoingAway) {
@@ -686,8 +679,12 @@
                 return@postDelayed
             }
 
-            keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
-                false /* cancelled */)
+            if (wallpaperTargets != null) {
+              fadeInWallpaper()
+            } else {
+                keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
+                    false /* cancelled */)
+            }
         }, CANNED_UNLOCK_START_DELAY)
     }
 
@@ -809,7 +806,16 @@
      * animations and swipe gestures to animate the surface's entry (and exit, if the swipe is
      * cancelled).
      */
-    fun setSurfaceBehindAppearAmount(amount: Float) {
+    fun setSurfaceBehindAppearAmount(amount: Float, wallpapers: Boolean = true) {
+        val animationAlpha = when {
+            // If we're snapping the keyguard back, immediately begin fading it out.
+            keyguardStateController.isSnappingKeyguardBackAfterSwipe -> amount
+            // If the screen has turned back off, the unlock animation is going to be cancelled,
+            // so set the surface alpha to 0f so it's no longer visible.
+            !powerManager.isInteractive -> 0f
+            else -> surfaceBehindAlpha
+        }
+
         surfaceBehindRemoteAnimationTargets?.forEach { surfaceBehindRemoteAnimationTarget ->
             val surfaceHeight: Int = surfaceBehindRemoteAnimationTarget.screenSpaceBounds.height()
 
@@ -826,8 +832,8 @@
 
             // Translate up from the bottom.
             surfaceBehindMatrix.setTranslate(
-                    surfaceBehindRemoteAnimationTarget.localBounds.left.toFloat(),
-                    surfaceBehindRemoteAnimationTarget.localBounds.top.toFloat() +
+                    surfaceBehindRemoteAnimationTarget.screenSpaceBounds.left.toFloat(),
+                    surfaceBehindRemoteAnimationTarget.screenSpaceBounds.top.toFloat() +
                             surfaceHeight * SURFACE_BEHIND_START_TRANSLATION_Y * (1f - amount)
             )
 
@@ -839,16 +845,6 @@
                     surfaceHeight * SURFACE_BEHIND_SCALE_PIVOT_Y
             )
 
-
-            val animationAlpha = when {
-                // If we're snapping the keyguard back, immediately begin fading it out.
-                keyguardStateController.isSnappingKeyguardBackAfterSwipe -> amount
-                // If the screen has turned back off, the unlock animation is going to be cancelled,
-                // so set the surface alpha to 0f so it's no longer visible.
-                !powerManager.isInteractive -> 0f
-                else -> surfaceBehindAlpha
-            }
-
             // SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is
             // unable to draw
             val sc: SurfaceControl? = surfaceBehindRemoteAnimationTarget.leash
@@ -863,28 +859,27 @@
             } else {
                 applyParamsToSurface(
                         SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
-                                surfaceBehindRemoteAnimationTarget.leash)
-                                .withMatrix(surfaceBehindMatrix)
-                                .withCornerRadius(roundedCornerRadius)
-                                .withAlpha(animationAlpha)
-                                .build()
+                            surfaceBehindRemoteAnimationTarget.leash)
+                            .withMatrix(surfaceBehindMatrix)
+                            .withCornerRadius(roundedCornerRadius)
+                            .withAlpha(animationAlpha)
+                            .build()
                 )
             }
         }
+
+        if (wallpapers) {
+            setWallpaperAppearAmount(amount)
+        }
     }
 
-    /**
-     * Modify the opacity of a wallpaper window.
-     */
     fun setWallpaperAppearAmount(amount: Float) {
-        wallpaperTargets?.forEach { wallpaper ->
-            val animationAlpha = when {
-                // If the screen has turned back off, the unlock animation is going to be cancelled,
-                // so set the surface alpha to 0f so it's no longer visible.
-                !powerManager.isInteractive -> 0f
-                else -> amount
-            }
+        val animationAlpha = when {
+            !powerManager.isInteractive -> 0f
+            else -> amount
+        }
 
+        wallpaperTargets?.forEach { wallpaper ->
             // SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is
             // unable to draw
             val sc: SurfaceControl? = wallpaper.leash
@@ -923,6 +918,7 @@
         setSurfaceBehindAppearAmount(1f)
         surfaceBehindAlphaAnimator.cancel()
         surfaceBehindEntryAnimator.cancel()
+        wallpaperCannedUnlockAnimator.cancel()
         try {
             launcherUnlockController?.setUnlockAmount(1f, false /* forceIfAnimating */)
         } catch (e: RemoteException) {
@@ -931,13 +927,16 @@
 
         // That target is no longer valid since the animation finished, null it out.
         surfaceBehindRemoteAnimationTargets = null
+        wallpaperTargets = null
 
         playingCannedUnlockAnimation = false
         willUnlockWithInWindowLauncherAnimations = false
         willUnlockWithSmartspaceTransition = false
 
         // The lockscreen surface is gone, so it is now safe to re-show the smartspace.
-        lockscreenSmartspace?.visibility = View.VISIBLE
+        if (lockscreenSmartspace?.visibility == View.INVISIBLE) {
+            lockscreenSmartspace?.visibility = View.VISIBLE
+        }
 
         listeners.forEach { it.onUnlockAnimationFinished() }
     }
@@ -972,8 +971,8 @@
 
     private fun fadeInWallpaper() {
         Log.d(TAG, "fadeInWallpaper")
-        wallpaperAlphaAnimator.cancel()
-        wallpaperAlphaAnimator.start()
+        wallpaperCannedUnlockAnimator.cancel()
+        wallpaperCannedUnlockAnimator.start()
     }
 
     private fun fadeOutSurfaceBehind() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index ddc12c9..45e4623 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -93,6 +93,7 @@
 import android.view.WindowManagerPolicyConstants;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
+import android.window.IRemoteTransition;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -153,12 +154,14 @@
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.util.DeviceConfigProxy;
+import com.android.wm.shell.keyguard.KeyguardTransitions;
 
 import dagger.Lazy;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Optional;
 import java.util.concurrent.Executor;
 
 /**
@@ -961,7 +964,26 @@
                 }
             };
 
-    private IRemoteAnimationRunner mOccludeAnimationRunner =
+    private final IRemoteAnimationRunner.Stub mExitAnimationRunner =
+            new IRemoteAnimationRunner.Stub() {
+        @Override // Binder interface
+        public void onAnimationStart(@WindowManager.TransitionOldType int transit,
+                RemoteAnimationTarget[] apps,
+                RemoteAnimationTarget[] wallpapers,
+                RemoteAnimationTarget[] nonApps,
+                IRemoteAnimationFinishedCallback finishedCallback) {
+            Trace.beginSection("mExitAnimationRunner.onAnimationStart#startKeyguardExitAnimation");
+            startKeyguardExitAnimation(transit, apps, wallpapers, nonApps, finishedCallback);
+            Trace.endSection();
+        }
+
+        @Override // Binder interface
+        public void onAnimationCancelled() {
+            cancelKeyguardExitAnimation();
+        }
+    };
+
+    private final IRemoteAnimationRunner mOccludeAnimationRunner =
             new OccludeActivityLaunchRemoteAnimationRunner(mOccludeAnimationController);
 
     private final IRemoteAnimationRunner mOccludeByDreamAnimationRunner =
@@ -1003,7 +1025,8 @@
                     }
 
                     final RemoteAnimationTarget primary = apps[0];
-                    final boolean isDream = (apps[0].taskInfo.topActivityType
+                    final boolean isDream = (apps[0].taskInfo != null
+                            && apps[0].taskInfo.topActivityType
                             == WindowConfiguration.ACTIVITY_TYPE_DREAM);
                     if (!isDream) {
                         Log.w(TAG, "The occluding app isn't Dream; "
@@ -1103,7 +1126,8 @@
                     }
 
                     final RemoteAnimationTarget primary = apps[0];
-                    final boolean isDream = (apps[0].taskInfo.topActivityType
+                    final boolean isDream = (apps[0].taskInfo != null
+                            && apps[0].taskInfo.topActivityType
                             == WindowConfiguration.ACTIVITY_TYPE_DREAM);
 
                     final SyncRtSurfaceTransactionApplier applier =
@@ -1186,6 +1210,7 @@
     private final InteractionJankMonitor mInteractionJankMonitor;
     private boolean mWallpaperSupportsAmbientMode;
     private ScreenOnCoordinator mScreenOnCoordinator;
+    private final KeyguardTransitions mKeyguardTransitions;
 
     private Lazy<ActivityLaunchAnimator> mActivityLaunchAnimator;
     private Lazy<ScrimController> mScrimControllerLazy;
@@ -1221,6 +1246,7 @@
             ScreenOffAnimationController screenOffAnimationController,
             Lazy<NotificationShadeDepthController> notificationShadeDepthController,
             ScreenOnCoordinator screenOnCoordinator,
+            KeyguardTransitions keyguardTransitions,
             InteractionJankMonitor interactionJankMonitor,
             DreamOverlayStateController dreamOverlayStateController,
             Lazy<ShadeController> shadeControllerLazy,
@@ -1248,6 +1274,7 @@
         dumpManager.registerDumpable(getClass().getName(), this);
         mDeviceConfig = deviceConfig;
         mScreenOnCoordinator = screenOnCoordinator;
+        mKeyguardTransitions = keyguardTransitions;
         mNotificationShadeWindowControllerLazy = notificationShadeWindowControllerLazy;
         mShowHomeOverLockscreen = mDeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_SYSTEMUI,
@@ -1323,6 +1350,12 @@
             setShowingLocked(false /* showing */, true /* forceCallbacks */);
         }
 
+        mKeyguardTransitions.register(
+                KeyguardService.wrap(getExitAnimationRunner()),
+                KeyguardService.wrap(getOccludeAnimationRunner()),
+                KeyguardService.wrap(getOccludeByDreamAnimationRunner()),
+                KeyguardService.wrap(getUnoccludeAnimationRunner()));
+
         final ContentResolver cr = mContext.getContentResolver();
 
         mDeviceInteractive = mPM.isInteractive();
@@ -1468,13 +1501,17 @@
             notifyFinishedGoingToSleep();
 
             if (cameraGestureTriggered) {
-
                 // Just to make sure, make sure the device is awake.
                 mContext.getSystemService(PowerManager.class).wakeUp(SystemClock.uptimeMillis(),
                         PowerManager.WAKE_REASON_CAMERA_LAUNCH,
                         "com.android.systemui:CAMERA_GESTURE_PREVENT_LOCK");
                 setPendingLock(false);
                 mPendingReset = false;
+                mPowerGestureIntercepted = true;
+                if (DEBUG) {
+                    Log.d(TAG, "cameraGestureTriggered=" + cameraGestureTriggered
+                            + ",mPowerGestureIntercepted=" + mPowerGestureIntercepted);
+                }
             }
 
             if (mPendingReset) {
@@ -1673,7 +1710,13 @@
             mAnimatingScreenOff = false;
             cancelDoKeyguardLaterLocked();
             cancelDoKeyguardForChildProfilesLocked();
-            if (DEBUG) Log.d(TAG, "onStartedWakingUp, seq = " + mDelayedShowingSequence);
+            if (cameraGestureTriggered) {
+                mPowerGestureIntercepted = true;
+            }
+            if (DEBUG) {
+                Log.d(TAG, "onStartedWakingUp, seq = " + mDelayedShowingSequence
+                        + ", mPowerGestureIntercepted = " + mPowerGestureIntercepted);
+            }
             notifyStartedWakingUp();
         }
         mUiEventLogger.logWithInstanceIdAndPosition(
@@ -1858,6 +1901,10 @@
         Trace.endSection();
     }
 
+    public IRemoteAnimationRunner getExitAnimationRunner() {
+        return mExitAnimationRunner;
+    }
+
     public IRemoteAnimationRunner getOccludeAnimationRunner() {
         return mOccludeAnimationRunner;
     }
@@ -1896,12 +1943,19 @@
                 startKeyguardExitAnimation(0, 0);
             }
 
+            mPowerGestureIntercepted = mUpdateMonitor.isSecureCameraLaunchedOverKeyguard();
+
             if (mOccluded != isOccluded) {
                 mOccluded = isOccluded;
                 mKeyguardViewControllerLazy.get().setOccluded(isOccluded, animate
                         && mDeviceInteractive);
                 adjustStatusBarLocked();
             }
+
+            if (DEBUG) {
+                Log.d(TAG, "isOccluded=" + isOccluded + ",mPowerGestureIntercepted="
+                        + mPowerGestureIntercepted);
+            }
         }
         Trace.endSection();
     }
@@ -2955,19 +3009,6 @@
         mSurfaceBehindRemoteAnimationRequested = false;
         mSurfaceBehindRemoteAnimationRunning = false;
         mKeyguardStateController.notifyKeyguardGoingAway(false);
-        finishExitRemoteAnimation();
-    }
-
-    void finishExitRemoteAnimation() {
-        if (mKeyguardUnlockAnimationControllerLazy.get().isAnyKeyguyardAnimatorPlaying()
-                || mKeyguardStateController.isDismissingFromSwipe()) {
-            // If the animation is ongoing, or we are not done with the swipe gesture,
-            // it's too early to terminate the animation
-            Log.d(TAG, "finishAnimation not executing now because "
-                    + "not all animations have finished");
-            return;
-        }
-        Log.d(TAG, "finishAnimation executing");
 
         if (mSurfaceBehindRemoteAnimationFinishedCallback != null) {
             try {
@@ -3019,6 +3060,10 @@
                 flags |= StatusBarManager.DISABLE_RECENT;
             }
 
+            if (mPowerGestureIntercepted) {
+                flags |= StatusBarManager.DISABLE_RECENT;
+            }
+
             if (DEBUG) {
                 Log.d(TAG, "adjustStatusBarLocked: mShowing=" + mShowing + " mOccluded=" + mOccluded
                         + " isSecure=" + isSecure() + " force=" + forceHideHomeRecentsButtons
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt
new file mode 100644
index 0000000..1978b3d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard
+
+import android.annotation.WorkerThread
+import android.content.ComponentCallbacks2
+import android.graphics.HardwareRenderer
+import android.os.Trace
+import android.util.Log
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.WakefulnessState
+import com.android.systemui.utils.GlobalWindowManager
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+/**
+ * Releases cached resources on allocated by keyguard.
+ *
+ * We release most resources when device goes idle since that's the least likely time it'll cause
+ * jank during use. Idle in this case means after lockscreen -> AoD transition completes or when the
+ * device screen is turned off, depending on settings.
+ */
+@SysUISingleton
+class ResourceTrimmer
+@Inject
+constructor(
+    private val keyguardInteractor: KeyguardInteractor,
+    private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
+    private val globalWindowManager: GlobalWindowManager,
+    @Application private val applicationScope: CoroutineScope,
+    @Background private val bgDispatcher: CoroutineDispatcher,
+    private val featureFlags: FeatureFlags,
+) : CoreStartable, WakefulnessLifecycle.Observer {
+
+    override fun start() {
+        Log.d(LOG_TAG, "Resource trimmer registered.")
+        if (
+            !(featureFlags.isEnabled(Flags.TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK) ||
+                featureFlags.isEnabled(Flags.TRIM_FONT_CACHES_AT_UNLOCK))
+        ) {
+            return
+        }
+
+        applicationScope.launch(bgDispatcher) {
+            // We need to wait for the AoD transition (and animation) to complete.
+            // This means we're waiting for isDreaming (== implies isDoze) and dozeAmount == 1f
+            // signal. This is to make sure we don't clear font caches during animation which
+            // would jank and leave stale data in memory.
+            val isDozingFully =
+                keyguardInteractor.dozeAmount.map { it == 1f }.distinctUntilChanged()
+            combine(
+                    keyguardInteractor.wakefulnessModel.map { it.state },
+                    keyguardInteractor.isDreaming,
+                    isDozingFully,
+                    ::Triple
+                )
+                .distinctUntilChanged()
+                .collect { onWakefulnessUpdated(it.first, it.second, it.third) }
+        }
+
+        applicationScope.launch(bgDispatcher) {
+            // We drop 1 to avoid triggering on initial collect().
+            keyguardTransitionInteractor.anyStateToGoneTransition.collect { transition ->
+                if (transition.transitionState == TransitionState.FINISHED) {
+                    onKeyguardGone()
+                }
+            }
+        }
+    }
+
+    @WorkerThread
+    private fun onKeyguardGone() {
+        if (!featureFlags.isEnabled(Flags.TRIM_FONT_CACHES_AT_UNLOCK)) {
+            return
+        }
+
+        if (DEBUG) {
+            Log.d(LOG_TAG, "Trimming font caches since keyguard went away.")
+        }
+        // We want to clear temporary caches we've created while rendering and animating
+        // lockscreen elements, especially clocks.
+        globalWindowManager.trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
+        globalWindowManager.trimCaches(HardwareRenderer.CACHE_TRIM_FONT)
+    }
+
+    @WorkerThread
+    private fun onWakefulnessUpdated(
+        wakefulness: WakefulnessState,
+        isDreaming: Boolean,
+        isDozingFully: Boolean
+    ) {
+        if (!featureFlags.isEnabled(Flags.TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK)) {
+            return
+        }
+
+        if (DEBUG) {
+            Log.d(
+                LOG_TAG,
+                "Wakefulness: $wakefulness Dreaming: $isDreaming DozeAmount: $isDozingFully"
+            )
+        }
+        // There are three scenarios:
+        // * No dozing and no AoD at all - where we go directly to ASLEEP with isDreaming = false
+        //      and dozeAmount == 0f
+        // * Dozing without Aod - where we go to ASLEEP with isDreaming = true and dozeAmount jumps
+        //      to 1f
+        // * AoD - where we go to ASLEEP with iDreaming = true and dozeAmount slowly increases
+        //      to 1f
+        val dozeDisabledAndScreenOff = wakefulness == WakefulnessState.ASLEEP && !isDreaming
+        val dozeEnabledAndDozeAnimationCompleted =
+            wakefulness == WakefulnessState.ASLEEP && isDreaming && isDozingFully
+        if (dozeDisabledAndScreenOff || dozeEnabledAndDozeAnimationCompleted) {
+            Trace.beginSection("ResourceTrimmer#trimMemory")
+            Log.d(LOG_TAG, "SysUI asleep, trimming memory.")
+            globalWindowManager.trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
+            globalWindowManager.trimCaches(HardwareRenderer.CACHE_TRIM_ALL)
+            Trace.endSection()
+        }
+    }
+
+    companion object {
+        private const val LOG_TAG = "ResourceTrimmer"
+        private val DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardBouncerMessages.kt b/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/data/factory/BouncerMessageFactory.kt
similarity index 67%
rename from packages/SystemUI/src/com/android/keyguard/KeyguardBouncerMessages.kt
rename to packages/SystemUI/src/com/android/systemui/keyguard/bouncer/data/factory/BouncerMessageFactory.kt
index f4145db..4085dab 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardBouncerMessages.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/data/factory/BouncerMessageFactory.kt
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.keyguard
+package com.android.systemui.keyguard.bouncer.data.factory
 
 import android.annotation.IntDef
+import com.android.keyguard.KeyguardSecurityModel
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode
 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT
 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEFAULT
@@ -34,6 +35,7 @@
 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TIMEOUT
 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED
 import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_USER_REQUEST
+import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.R.string.bouncer_face_not_recognized
 import com.android.systemui.R.string.keyguard_enter_password
 import com.android.systemui.R.string.keyguard_enter_pattern
@@ -71,10 +73,86 @@
 import com.android.systemui.R.string.kg_wrong_password_try_again
 import com.android.systemui.R.string.kg_wrong_pattern_try_again
 import com.android.systemui.R.string.kg_wrong_pin_try_again
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.bouncer.shared.model.BouncerMessageModel
+import com.android.systemui.keyguard.bouncer.shared.model.Message
+import javax.inject.Inject
 
-typealias BouncerMessage = Pair<Int, Int>
+@SysUISingleton
+class BouncerMessageFactory
+@Inject
+constructor(
+    private val updateMonitor: KeyguardUpdateMonitor,
+    private val securityModel: KeyguardSecurityModel,
+) {
 
-fun emptyBouncerMessage(): BouncerMessage = Pair(0, 0)
+    fun createFromPromptReason(
+        @BouncerPromptReason reason: Int,
+        userId: Int,
+    ): BouncerMessageModel? {
+        val pair =
+            getBouncerMessage(
+                reason,
+                securityModel.getSecurityMode(userId),
+                updateMonitor.isFingerprintAllowedInBouncer
+            )
+        return pair?.let {
+            BouncerMessageModel(
+                message = Message(messageResId = pair.first),
+                secondaryMessage = Message(messageResId = pair.second)
+            )
+        }
+    }
+
+    fun createFromString(
+        primaryMsg: String? = null,
+        secondaryMsg: String? = null
+    ): BouncerMessageModel =
+        BouncerMessageModel(
+            message = primaryMsg?.let { Message(message = it) },
+            secondaryMessage = secondaryMsg?.let { Message(message = it) },
+        )
+
+    /**
+     * Helper method that provides the relevant bouncer message that should be shown for different
+     * scenarios indicated by [reason]. [securityMode] & [fpAllowedInBouncer] parameters are used to
+     * provide a more specific message.
+     */
+    private fun getBouncerMessage(
+        @BouncerPromptReason reason: Int,
+        securityMode: SecurityMode,
+        fpAllowedInBouncer: Boolean = false
+    ): Pair<Int, Int>? {
+        return when (reason) {
+            PROMPT_REASON_RESTART -> authRequiredAfterReboot(securityMode)
+            PROMPT_REASON_TIMEOUT -> authRequiredAfterPrimaryAuthTimeout(securityMode)
+            PROMPT_REASON_DEVICE_ADMIN -> authRequiredAfterAdminLockdown(securityMode)
+            PROMPT_REASON_USER_REQUEST -> authRequiredAfterUserLockdown(securityMode)
+            PROMPT_REASON_AFTER_LOCKOUT -> biometricLockout(securityMode)
+            PROMPT_REASON_PREPARE_FOR_UPDATE -> authRequiredForUnattendedUpdate(securityMode)
+            PROMPT_REASON_FINGERPRINT_LOCKED_OUT -> fingerprintUnlockUnavailable(securityMode)
+            PROMPT_REASON_FACE_LOCKED_OUT -> faceUnlockUnavailable(securityMode)
+            PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT ->
+                if (fpAllowedInBouncer) incorrectSecurityInputWithFingerprint(securityMode)
+                else incorrectSecurityInput(securityMode)
+            PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT ->
+                if (fpAllowedInBouncer) nonStrongAuthTimeoutWithFingerprintAllowed(securityMode)
+                else nonStrongAuthTimeout(securityMode)
+            PROMPT_REASON_TRUSTAGENT_EXPIRED ->
+                if (fpAllowedInBouncer) trustAgentDisabledWithFingerprintAllowed(securityMode)
+                else trustAgentDisabled(securityMode)
+            PROMPT_REASON_INCORRECT_FACE_INPUT ->
+                if (fpAllowedInBouncer) incorrectFaceInputWithFingerprintAllowed(securityMode)
+                else incorrectFaceInput(securityMode)
+            PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT -> incorrectFingerprintInput(securityMode)
+            PROMPT_REASON_DEFAULT ->
+                if (fpAllowedInBouncer) defaultMessageWithFingerprint(securityMode)
+                else defaultMessage(securityMode)
+            PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT -> primaryAuthLockedOut(securityMode)
+            else -> null
+        }
+    }
+}
 
 @Retention(AnnotationRetention.SOURCE)
 @IntDef(
@@ -97,48 +175,7 @@
 )
 annotation class BouncerPromptReason
 
-/**
- * Helper method that provides the relevant bouncer message that should be shown for different
- * scenarios indicated by [reason]. [securityMode] & [fpAllowedInBouncer] parameters are used to
- * provide a more specific message.
- */
-@JvmOverloads
-fun getBouncerMessage(
-    @BouncerPromptReason reason: Int,
-    securityMode: SecurityMode,
-    fpAllowedInBouncer: Boolean = false
-): BouncerMessage {
-    return when (reason) {
-        PROMPT_REASON_RESTART -> authRequiredAfterReboot(securityMode)
-        PROMPT_REASON_TIMEOUT -> authRequiredAfterPrimaryAuthTimeout(securityMode)
-        PROMPT_REASON_DEVICE_ADMIN -> authRequiredAfterAdminLockdown(securityMode)
-        PROMPT_REASON_USER_REQUEST -> authRequiredAfterUserLockdown(securityMode)
-        PROMPT_REASON_AFTER_LOCKOUT -> biometricLockout(securityMode)
-        PROMPT_REASON_PREPARE_FOR_UPDATE -> authRequiredForUnattendedUpdate(securityMode)
-        PROMPT_REASON_FINGERPRINT_LOCKED_OUT -> fingerprintUnlockUnavailable(securityMode)
-        PROMPT_REASON_FACE_LOCKED_OUT -> faceUnlockUnavailable(securityMode)
-        PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT ->
-            if (fpAllowedInBouncer) incorrectSecurityInputWithFingerprint(securityMode)
-            else incorrectSecurityInput(securityMode)
-        PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT ->
-            if (fpAllowedInBouncer) nonStrongAuthTimeoutWithFingerprintAllowed(securityMode)
-            else nonStrongAuthTimeout(securityMode)
-        PROMPT_REASON_TRUSTAGENT_EXPIRED ->
-            if (fpAllowedInBouncer) trustAgentDisabledWithFingerprintAllowed(securityMode)
-            else trustAgentDisabled(securityMode)
-        PROMPT_REASON_INCORRECT_FACE_INPUT ->
-            if (fpAllowedInBouncer) incorrectFaceInputWithFingerprintAllowed(securityMode)
-            else incorrectFaceInput(securityMode)
-        PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT -> incorrectFingerprintInput(securityMode)
-        PROMPT_REASON_DEFAULT ->
-            if (fpAllowedInBouncer) defaultMessageWithFingerprint(securityMode)
-            else defaultMessage(securityMode)
-        PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT -> primaryAuthLockedOut(securityMode)
-        else -> emptyBouncerMessage()
-    }
-}
-
-fun defaultMessage(securityMode: SecurityMode): BouncerMessage {
+private fun defaultMessage(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(keyguard_enter_pattern, 0)
         SecurityMode.Password -> Pair(keyguard_enter_password, 0)
@@ -147,7 +184,7 @@
     }
 }
 
-fun defaultMessageWithFingerprint(securityMode: SecurityMode): BouncerMessage {
+private fun defaultMessageWithFingerprint(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, 0)
         SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, 0)
@@ -156,7 +193,7 @@
     }
 }
 
-fun incorrectSecurityInput(securityMode: SecurityMode): BouncerMessage {
+private fun incorrectSecurityInput(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(kg_wrong_pattern_try_again, 0)
         SecurityMode.Password -> Pair(kg_wrong_password_try_again, 0)
@@ -165,7 +202,7 @@
     }
 }
 
-fun incorrectSecurityInputWithFingerprint(securityMode: SecurityMode): BouncerMessage {
+private fun incorrectSecurityInputWithFingerprint(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(kg_wrong_pattern_try_again, kg_wrong_input_try_fp_suggestion)
         SecurityMode.Password -> Pair(kg_wrong_password_try_again, kg_wrong_input_try_fp_suggestion)
@@ -174,7 +211,7 @@
     }
 }
 
-fun incorrectFingerprintInput(securityMode: SecurityMode): BouncerMessage {
+private fun incorrectFingerprintInput(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(kg_fp_not_recognized, kg_bio_try_again_or_pattern)
         SecurityMode.Password -> Pair(kg_fp_not_recognized, kg_bio_try_again_or_password)
@@ -183,7 +220,7 @@
     }
 }
 
-fun incorrectFaceInput(securityMode: SecurityMode): BouncerMessage {
+private fun incorrectFaceInput(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(bouncer_face_not_recognized, kg_bio_try_again_or_pattern)
         SecurityMode.Password -> Pair(bouncer_face_not_recognized, kg_bio_try_again_or_password)
@@ -192,7 +229,7 @@
     }
 }
 
-fun incorrectFaceInputWithFingerprintAllowed(securityMode: SecurityMode): BouncerMessage {
+private fun incorrectFaceInputWithFingerprintAllowed(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, bouncer_face_not_recognized)
         SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, bouncer_face_not_recognized)
@@ -201,7 +238,7 @@
     }
 }
 
-fun biometricLockout(securityMode: SecurityMode): BouncerMessage {
+private fun biometricLockout(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_bio_too_many_attempts_pattern)
         SecurityMode.Password -> Pair(keyguard_enter_password, kg_bio_too_many_attempts_password)
@@ -210,7 +247,7 @@
     }
 }
 
-fun authRequiredAfterReboot(securityMode: SecurityMode): BouncerMessage {
+private fun authRequiredAfterReboot(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_reason_restart_pattern)
         SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_reason_restart_password)
@@ -219,7 +256,7 @@
     }
 }
 
-fun authRequiredAfterAdminLockdown(securityMode: SecurityMode): BouncerMessage {
+private fun authRequiredAfterAdminLockdown(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_dpm_lock)
         SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_after_dpm_lock)
@@ -228,7 +265,7 @@
     }
 }
 
-fun authRequiredAfterUserLockdown(securityMode: SecurityMode): BouncerMessage {
+private fun authRequiredAfterUserLockdown(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_after_user_lockdown_pattern)
         SecurityMode.Password ->
@@ -238,7 +275,7 @@
     }
 }
 
-fun authRequiredForUnattendedUpdate(securityMode: SecurityMode): BouncerMessage {
+private fun authRequiredForUnattendedUpdate(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_unattended_update)
         SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_unattended_update)
@@ -247,7 +284,7 @@
     }
 }
 
-fun authRequiredAfterPrimaryAuthTimeout(securityMode: SecurityMode): BouncerMessage {
+private fun authRequiredAfterPrimaryAuthTimeout(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_pattern_auth_timeout)
         SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_password_auth_timeout)
@@ -256,7 +293,7 @@
     }
 }
 
-fun nonStrongAuthTimeout(securityMode: SecurityMode): BouncerMessage {
+private fun nonStrongAuthTimeout(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_prompt_auth_timeout)
         SecurityMode.Password -> Pair(keyguard_enter_password, kg_prompt_auth_timeout)
@@ -265,7 +302,7 @@
     }
 }
 
-fun nonStrongAuthTimeoutWithFingerprintAllowed(securityMode: SecurityMode): BouncerMessage {
+private fun nonStrongAuthTimeoutWithFingerprintAllowed(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, kg_prompt_auth_timeout)
         SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, kg_prompt_auth_timeout)
@@ -274,7 +311,7 @@
     }
 }
 
-fun faceUnlockUnavailable(securityMode: SecurityMode): BouncerMessage {
+private fun faceUnlockUnavailable(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_face_locked_out)
         SecurityMode.Password -> Pair(keyguard_enter_password, kg_face_locked_out)
@@ -283,7 +320,7 @@
     }
 }
 
-fun fingerprintUnlockUnavailable(securityMode: SecurityMode): BouncerMessage {
+private fun fingerprintUnlockUnavailable(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_fp_locked_out)
         SecurityMode.Password -> Pair(keyguard_enter_password, kg_fp_locked_out)
@@ -292,7 +329,7 @@
     }
 }
 
-fun trustAgentDisabled(securityMode: SecurityMode): BouncerMessage {
+private fun trustAgentDisabled(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(keyguard_enter_pattern, kg_trust_agent_disabled)
         SecurityMode.Password -> Pair(keyguard_enter_password, kg_trust_agent_disabled)
@@ -301,7 +338,7 @@
     }
 }
 
-fun trustAgentDisabledWithFingerprintAllowed(securityMode: SecurityMode): BouncerMessage {
+private fun trustAgentDisabledWithFingerprintAllowed(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern -> Pair(kg_unlock_with_pattern_or_fp, kg_trust_agent_disabled)
         SecurityMode.Password -> Pair(kg_unlock_with_password_or_fp, kg_trust_agent_disabled)
@@ -310,7 +347,7 @@
     }
 }
 
-fun primaryAuthLockedOut(securityMode: SecurityMode): BouncerMessage {
+private fun primaryAuthLockedOut(securityMode: SecurityMode): Pair<Int, Int> {
     return when (securityMode) {
         SecurityMode.Pattern ->
             Pair(kg_too_many_failed_attempts_countdown, kg_primary_auth_locked_out_pattern)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/data/repository/BouncerMessageRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/data/repository/BouncerMessageRepository.kt
new file mode 100644
index 0000000..c4400bc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/data/repository/BouncerMessageRepository.kt
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.bouncer.data.repository
+
+import android.hardware.biometrics.BiometricSourceType
+import android.hardware.biometrics.BiometricSourceType.FACE
+import android.hardware.biometrics.BiometricSourceType.FINGERPRINT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_FACE_LOCKED_OUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_FINGERPRINT_LOCKED_OUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_FACE_INPUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NONE
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PREPARE_FOR_UPDATE
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_RESTART
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TIMEOUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_TRUSTAGENT_EXPIRED
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_USER_REQUEST
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.bouncer.data.factory.BouncerMessageFactory
+import com.android.systemui.keyguard.bouncer.shared.model.BouncerMessageModel
+import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.data.repository.TrustRepository
+import com.android.systemui.user.data.repository.UserRepository
+import javax.inject.Inject
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
+
+/** Provide different sources of messages that needs to be shown on the bouncer. */
+interface BouncerMessageRepository {
+    /**
+     * Messages that are shown in response to the incorrect security attempts on the bouncer and
+     * primary authentication method being locked out, along with countdown messages before primary
+     * auth is active again.
+     */
+    val primaryAuthMessage: Flow<BouncerMessageModel?>
+
+    /**
+     * Help messages that are shown to the user on how to successfully perform authentication using
+     * face.
+     */
+    val faceAcquisitionMessage: Flow<BouncerMessageModel?>
+
+    /**
+     * Help messages that are shown to the user on how to successfully perform authentication using
+     * fingerprint.
+     */
+    val fingerprintAcquisitionMessage: Flow<BouncerMessageModel?>
+
+    /** Custom message that is displayed when the bouncer is being shown to launch an app. */
+    val customMessage: Flow<BouncerMessageModel?>
+
+    /**
+     * Messages that are shown in response to biometric authentication attempts through face or
+     * fingerprint.
+     */
+    val biometricAuthMessage: Flow<BouncerMessageModel?>
+
+    /** Messages that are shown when certain auth flags are set. */
+    val authFlagsMessage: Flow<BouncerMessageModel?>
+
+    /** Messages that are show after biometrics are locked out temporarily or permanently */
+    val biometricLockedOutMessage: Flow<BouncerMessageModel?>
+
+    /** Set the value for [primaryAuthMessage] */
+    fun setPrimaryAuthMessage(value: BouncerMessageModel?)
+
+    /** Set the value for [faceAcquisitionMessage] */
+    fun setFaceAcquisitionMessage(value: BouncerMessageModel?)
+    /** Set the value for [fingerprintAcquisitionMessage] */
+    fun setFingerprintAcquisitionMessage(value: BouncerMessageModel?)
+
+    /** Set the value for [customMessage] */
+    fun setCustomMessage(value: BouncerMessageModel?)
+
+    /**
+     * Clear any previously set messages for [primaryAuthMessage], [faceAcquisitionMessage],
+     * [fingerprintAcquisitionMessage] & [customMessage]
+     */
+    fun clearMessage()
+}
+
+@SysUISingleton
+class BouncerMessageRepositoryImpl
+@Inject
+constructor(
+    trustRepository: TrustRepository,
+    biometricSettingsRepository: BiometricSettingsRepository,
+    updateMonitor: KeyguardUpdateMonitor,
+    private val bouncerMessageFactory: BouncerMessageFactory,
+    private val userRepository: UserRepository,
+    fingerprintAuthRepository: DeviceEntryFingerprintAuthRepository,
+) : BouncerMessageRepository {
+
+    private val isFaceEnrolledAndEnabled =
+        and(
+            biometricSettingsRepository.isFaceAuthenticationEnabled,
+            biometricSettingsRepository.isFaceEnrolled
+        )
+
+    private val isFingerprintEnrolledAndEnabled =
+        and(
+            biometricSettingsRepository.isFingerprintEnabledByDevicePolicy,
+            biometricSettingsRepository.isFingerprintEnrolled
+        )
+
+    private val isAnyBiometricsEnabledAndEnrolled =
+        or(isFaceEnrolledAndEnabled, isFingerprintEnrolledAndEnabled)
+
+    private val authFlagsBasedPromptReason: Flow<Int> =
+        combine(
+                biometricSettingsRepository.authenticationFlags,
+                trustRepository.isCurrentUserTrustManaged,
+                isAnyBiometricsEnabledAndEnrolled,
+                ::Triple
+            )
+            .map { (flags, isTrustManaged, biometricsEnrolledAndEnabled) ->
+                val trustOrBiometricsAvailable = (isTrustManaged || biometricsEnrolledAndEnabled)
+                return@map if (
+                    trustOrBiometricsAvailable && flags.isPrimaryAuthRequiredAfterReboot
+                ) {
+                    PROMPT_REASON_RESTART
+                } else if (trustOrBiometricsAvailable && flags.isPrimaryAuthRequiredAfterTimeout) {
+                    PROMPT_REASON_TIMEOUT
+                } else if (flags.isPrimaryAuthRequiredAfterDpmLockdown) {
+                    PROMPT_REASON_DEVICE_ADMIN
+                } else if (isTrustManaged && flags.someAuthRequiredAfterUserRequest) {
+                    PROMPT_REASON_TRUSTAGENT_EXPIRED
+                } else if (isTrustManaged && flags.someAuthRequiredAfterTrustAgentExpired) {
+                    PROMPT_REASON_TRUSTAGENT_EXPIRED
+                } else if (trustOrBiometricsAvailable && flags.isInUserLockdown) {
+                    PROMPT_REASON_USER_REQUEST
+                } else if (
+                    trustOrBiometricsAvailable && flags.primaryAuthRequiredForUnattendedUpdate
+                ) {
+                    PROMPT_REASON_PREPARE_FOR_UPDATE
+                } else if (
+                    trustOrBiometricsAvailable &&
+                        flags.strongerAuthRequiredAfterNonStrongBiometricsTimeout
+                ) {
+                    PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT
+                } else {
+                    PROMPT_REASON_NONE
+                }
+            }
+
+    private val biometricAuthReason: Flow<Int> =
+        conflatedCallbackFlow {
+                val callback =
+                    object : KeyguardUpdateMonitorCallback() {
+                        override fun onBiometricAuthFailed(
+                            biometricSourceType: BiometricSourceType?
+                        ) {
+                            val promptReason =
+                                if (biometricSourceType == FINGERPRINT)
+                                    PROMPT_REASON_INCORRECT_FINGERPRINT_INPUT
+                                else if (
+                                    biometricSourceType == FACE && !updateMonitor.isFaceLockedOut
+                                ) {
+                                    PROMPT_REASON_INCORRECT_FACE_INPUT
+                                } else PROMPT_REASON_NONE
+                            trySendWithFailureLogging(promptReason, TAG, "onBiometricAuthFailed")
+                        }
+
+                        override fun onBiometricsCleared() {
+                            trySendWithFailureLogging(
+                                PROMPT_REASON_NONE,
+                                TAG,
+                                "onBiometricsCleared"
+                            )
+                        }
+
+                        override fun onBiometricAcquired(
+                            biometricSourceType: BiometricSourceType?,
+                            acquireInfo: Int
+                        ) {
+                            trySendWithFailureLogging(
+                                PROMPT_REASON_NONE,
+                                TAG,
+                                "clearBiometricPrompt for new auth session."
+                            )
+                        }
+
+                        override fun onBiometricAuthenticated(
+                            userId: Int,
+                            biometricSourceType: BiometricSourceType?,
+                            isStrongBiometric: Boolean
+                        ) {
+                            trySendWithFailureLogging(
+                                PROMPT_REASON_NONE,
+                                TAG,
+                                "onBiometricAuthenticated"
+                            )
+                        }
+                    }
+                updateMonitor.registerCallback(callback)
+                awaitClose { updateMonitor.removeCallback(callback) }
+            }
+            .distinctUntilChanged()
+
+    private val _primaryAuthMessage = MutableStateFlow<BouncerMessageModel?>(null)
+    override val primaryAuthMessage: Flow<BouncerMessageModel?> = _primaryAuthMessage
+
+    private val _faceAcquisitionMessage = MutableStateFlow<BouncerMessageModel?>(null)
+    override val faceAcquisitionMessage: Flow<BouncerMessageModel?> = _faceAcquisitionMessage
+
+    private val _fingerprintAcquisitionMessage = MutableStateFlow<BouncerMessageModel?>(null)
+    override val fingerprintAcquisitionMessage: Flow<BouncerMessageModel?> =
+        _fingerprintAcquisitionMessage
+
+    private val _customMessage = MutableStateFlow<BouncerMessageModel?>(null)
+    override val customMessage: Flow<BouncerMessageModel?> = _customMessage
+
+    override val biometricAuthMessage: Flow<BouncerMessageModel?> =
+        biometricAuthReason
+            .map {
+                if (it == PROMPT_REASON_NONE) null
+                else
+                    bouncerMessageFactory.createFromPromptReason(
+                        it,
+                        userRepository.getSelectedUserInfo().id
+                    )
+            }
+            .onStart { emit(null) }
+            .distinctUntilChanged()
+
+    override val authFlagsMessage: Flow<BouncerMessageModel?> =
+        authFlagsBasedPromptReason
+            .map {
+                if (it == PROMPT_REASON_NONE) null
+                else
+                    bouncerMessageFactory.createFromPromptReason(
+                        it,
+                        userRepository.getSelectedUserInfo().id
+                    )
+            }
+            .onStart { emit(null) }
+            .distinctUntilChanged()
+
+    // TODO (b/262838215): Replace with DeviceEntryFaceAuthRepository when the new face auth system
+    // has been launched.
+    private val faceLockedOut: Flow<Boolean> = conflatedCallbackFlow {
+        val callback =
+            object : KeyguardUpdateMonitorCallback() {
+                override fun onLockedOutStateChanged(biometricSourceType: BiometricSourceType?) {
+                    if (biometricSourceType == FACE) {
+                        trySendWithFailureLogging(
+                            updateMonitor.isFaceLockedOut,
+                            TAG,
+                            "face lock out state changed."
+                        )
+                    }
+                }
+            }
+        updateMonitor.registerCallback(callback)
+        trySendWithFailureLogging(updateMonitor.isFaceLockedOut, TAG, "face lockout initial value")
+        awaitClose { updateMonitor.removeCallback(callback) }
+    }
+
+    override val biometricLockedOutMessage: Flow<BouncerMessageModel?> =
+        combine(fingerprintAuthRepository.isLockedOut, faceLockedOut) { fp, face ->
+            return@combine if (fp) {
+                bouncerMessageFactory.createFromPromptReason(
+                    PROMPT_REASON_FINGERPRINT_LOCKED_OUT,
+                    userRepository.getSelectedUserInfo().id
+                )
+            } else if (face) {
+                bouncerMessageFactory.createFromPromptReason(
+                    PROMPT_REASON_FACE_LOCKED_OUT,
+                    userRepository.getSelectedUserInfo().id
+                )
+            } else null
+        }
+
+    override fun setPrimaryAuthMessage(value: BouncerMessageModel?) {
+        _primaryAuthMessage.value = value
+    }
+
+    override fun setFaceAcquisitionMessage(value: BouncerMessageModel?) {
+        _faceAcquisitionMessage.value = value
+    }
+
+    override fun setFingerprintAcquisitionMessage(value: BouncerMessageModel?) {
+        _fingerprintAcquisitionMessage.value = value
+    }
+
+    override fun setCustomMessage(value: BouncerMessageModel?) {
+        _customMessage.value = value
+    }
+
+    override fun clearMessage() {
+        _fingerprintAcquisitionMessage.value = null
+        _faceAcquisitionMessage.value = null
+        _primaryAuthMessage.value = null
+        _customMessage.value = null
+    }
+
+    companion object {
+        const val TAG = "BouncerDetailedMessageRepository"
+    }
+}
+
+private fun and(flow: Flow<Boolean>, anotherFlow: Flow<Boolean>) =
+    flow.combine(anotherFlow) { a, b -> a && b }
+
+private fun or(flow: Flow<Boolean>, anotherFlow: Flow<Boolean>) =
+    flow.combine(anotherFlow) { a, b -> a || b }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/domain/interactor/BouncerMessageAuditLogger.kt b/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/domain/interactor/BouncerMessageAuditLogger.kt
new file mode 100644
index 0000000..56f81fc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/domain/interactor/BouncerMessageAuditLogger.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.bouncer.domain.interactor
+
+import android.os.Build
+import android.util.Log
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.bouncer.data.repository.BouncerMessageRepository
+import com.android.systemui.keyguard.bouncer.shared.model.BouncerMessageModel
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.launch
+
+private val TAG = BouncerMessageAuditLogger::class.simpleName!!
+
+/** Logger that echoes bouncer messages state to logcat in debuggable builds. */
+@SysUISingleton
+class BouncerMessageAuditLogger
+@Inject
+constructor(
+    @Application private val scope: CoroutineScope,
+    private val repository: BouncerMessageRepository,
+    private val interactor: BouncerMessageInteractor,
+) : CoreStartable {
+    override fun start() {
+        if (Build.isDebuggable()) {
+            collectAndLog(repository.biometricAuthMessage, "biometricMessage: ")
+            collectAndLog(repository.primaryAuthMessage, "primaryAuthMessage: ")
+            collectAndLog(repository.customMessage, "customMessage: ")
+            collectAndLog(repository.faceAcquisitionMessage, "faceAcquisitionMessage: ")
+            collectAndLog(
+                repository.fingerprintAcquisitionMessage,
+                "fingerprintAcquisitionMessage: "
+            )
+            collectAndLog(repository.authFlagsMessage, "authFlagsMessage: ")
+            collectAndLog(interactor.bouncerMessage, "interactor.bouncerMessage: ")
+        }
+    }
+
+    private fun collectAndLog(flow: Flow<BouncerMessageModel?>, context: String) {
+        scope.launch { flow.collect { Log.d(TAG, context + it) } }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/domain/interactor/BouncerMessageInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/domain/interactor/BouncerMessageInteractor.kt
new file mode 100644
index 0000000..1754d93
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/domain/interactor/BouncerMessageInteractor.kt
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.bouncer.domain.interactor
+
+import android.os.CountDownTimer
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEFAULT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags.REVAMPED_BOUNCER_MESSAGES
+import com.android.systemui.keyguard.bouncer.data.factory.BouncerMessageFactory
+import com.android.systemui.keyguard.bouncer.data.repository.BouncerMessageRepository
+import com.android.systemui.keyguard.bouncer.shared.model.BouncerMessageModel
+import com.android.systemui.user.data.repository.UserRepository
+import javax.inject.Inject
+import kotlin.math.roundToInt
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
+
+@SysUISingleton
+class BouncerMessageInteractor
+@Inject
+constructor(
+    private val repository: BouncerMessageRepository,
+    private val factory: BouncerMessageFactory,
+    private val userRepository: UserRepository,
+    private val countDownTimerUtil: CountDownTimerUtil,
+    private val featureFlags: FeatureFlags,
+) {
+    fun onPrimaryAuthLockedOut(secondsBeforeLockoutReset: Long) {
+        if (!featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) return
+
+        val callback =
+            object : CountDownTimerCallback {
+                override fun onFinish() {
+                    repository.clearMessage()
+                }
+
+                override fun onTick(millisUntilFinished: Long) {
+                    val secondsRemaining = (millisUntilFinished / 1000.0).roundToInt()
+                    val message =
+                        factory.createFromPromptReason(
+                            reason = PROMPT_REASON_PRIMARY_AUTH_LOCKED_OUT,
+                            userId = userRepository.getSelectedUserInfo().id
+                        )
+                    message?.message?.animate = false
+                    message?.message?.formatterArgs =
+                        mutableMapOf<String, Any>(Pair("count", secondsRemaining))
+                    repository.setPrimaryAuthMessage(message)
+                }
+            }
+        countDownTimerUtil.startNewTimer(secondsBeforeLockoutReset * 1000, 1000, callback)
+    }
+
+    fun onPrimaryAuthIncorrectAttempt() {
+        if (!featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) return
+
+        repository.setPrimaryAuthMessage(
+            factory.createFromPromptReason(
+                PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
+                userRepository.getSelectedUserInfo().id
+            )
+        )
+    }
+
+    fun setFingerprintAcquisitionMessage(value: String?) {
+        if (!featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) return
+
+        repository.setFingerprintAcquisitionMessage(
+            if (value != null) {
+                factory.createFromString(secondaryMsg = value)
+            } else {
+                null
+            }
+        )
+    }
+
+    fun setFaceAcquisitionMessage(value: String?) {
+        if (!featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) return
+
+        repository.setFaceAcquisitionMessage(
+            if (value != null) {
+                factory.createFromString(secondaryMsg = value)
+            } else {
+                null
+            }
+        )
+    }
+
+    fun setCustomMessage(value: String?) {
+        if (!featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) return
+
+        repository.setCustomMessage(
+            if (value != null) {
+                factory.createFromString(secondaryMsg = value)
+            } else {
+                null
+            }
+        )
+    }
+
+    fun onPrimaryBouncerUserInput() {
+        if (!featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) return
+
+        repository.clearMessage()
+    }
+
+    fun onBouncerBeingHidden() {
+        if (!featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) return
+
+        repository.clearMessage()
+    }
+
+    private fun firstNonNullMessage(
+        oneMessageModel: Flow<BouncerMessageModel?>,
+        anotherMessageModel: Flow<BouncerMessageModel?>
+    ): Flow<BouncerMessageModel?> {
+        return oneMessageModel.combine(anotherMessageModel) { a, b -> a ?: b }
+    }
+
+    // Null if feature flag is enabled which gets ignored always or empty bouncer message model that
+    // always maps to an empty string.
+    private fun nullOrEmptyMessage() =
+        flowOf(
+            if (featureFlags.isEnabled(REVAMPED_BOUNCER_MESSAGES)) null
+            else factory.createFromString("", "")
+        )
+
+    val bouncerMessage =
+        listOf(
+                nullOrEmptyMessage(),
+                repository.primaryAuthMessage,
+                repository.biometricAuthMessage,
+                repository.fingerprintAcquisitionMessage,
+                repository.faceAcquisitionMessage,
+                repository.customMessage,
+                repository.authFlagsMessage,
+                repository.biometricLockedOutMessage,
+                userRepository.selectedUserInfo.map {
+                    factory.createFromPromptReason(PROMPT_REASON_DEFAULT, it.id)
+                },
+            )
+            .reduce(::firstNonNullMessage)
+            .distinctUntilChanged()
+}
+
+interface CountDownTimerCallback {
+    fun onFinish()
+    fun onTick(millisUntilFinished: Long)
+}
+
+@SysUISingleton
+open class CountDownTimerUtil @Inject constructor() {
+
+    /**
+     * Start a new count down timer that runs for [millisInFuture] with a tick every
+     * [millisInterval]
+     */
+    fun startNewTimer(
+        millisInFuture: Long,
+        millisInterval: Long,
+        callback: CountDownTimerCallback,
+    ): CountDownTimer {
+        return object : CountDownTimer(millisInFuture, millisInterval) {
+                override fun onFinish() = callback.onFinish()
+
+                override fun onTick(millisUntilFinished: Long) =
+                    callback.onTick(millisUntilFinished)
+            }
+            .start()
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/shared/model/BouncerMessageModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/shared/model/BouncerMessageModel.kt
new file mode 100644
index 0000000..46e8873
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/shared/model/BouncerMessageModel.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.bouncer.shared.model
+
+import android.content.res.ColorStateList
+
+/**
+ * Represents the message displayed on the bouncer. It has two parts, primary and a secondary
+ * message
+ */
+data class BouncerMessageModel(val message: Message? = null, val secondaryMessage: Message? = null)
+
+/**
+ * Representation of a single message on the bouncer. It can be either a string or a string resource
+ * ID
+ */
+data class Message(
+    val message: String? = null,
+    val messageResId: Int? = null,
+    val colorState: ColorStateList? = null,
+    /** Any plural formatter arguments that can used to format the [messageResId] */
+    var formatterArgs: Map<String, Any>? = null,
+    /** Specifies whether this text should be animated when it is shown. */
+    var animate: Boolean = true,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/ui/BouncerMessageView.kt b/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/ui/BouncerMessageView.kt
new file mode 100644
index 0000000..c0a5a51
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/bouncer/ui/BouncerMessageView.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.bouncer.ui
+
+import android.content.Context
+import android.util.AttributeSet
+import android.widget.LinearLayout
+import com.android.keyguard.BouncerKeyguardMessageArea
+import com.android.keyguard.KeyguardMessageArea
+import com.android.keyguard.KeyguardMessageAreaController
+import com.android.systemui.R
+
+class BouncerMessageView : LinearLayout {
+    constructor(context: Context?) : super(context)
+
+    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
+
+    init {
+        inflate(context, R.layout.bouncer_message_view, this)
+    }
+
+    var primaryMessageView: BouncerKeyguardMessageArea? = null
+    var secondaryMessageView: BouncerKeyguardMessageArea? = null
+    var primaryMessage: KeyguardMessageAreaController<KeyguardMessageArea>? = null
+    var secondaryMessage: KeyguardMessageAreaController<KeyguardMessageArea>? = null
+    override fun onFinishInflate() {
+        super.onFinishInflate()
+        primaryMessageView = findViewById(R.id.bouncer_primary_message_area)
+        secondaryMessageView = findViewById(R.id.bouncer_secondary_message_area)
+    }
+
+    fun init(factory: KeyguardMessageAreaController.Factory) {
+        primaryMessage = factory.create(primaryMessageView)
+        primaryMessage?.init()
+        secondaryMessage = factory.create(secondaryMessageView)
+        secondaryMessage?.init()
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
index deb8f5d..d7c039d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -64,6 +64,7 @@
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.util.DeviceConfigProxy;
+import com.android.wm.shell.keyguard.KeyguardTransitions;
 
 import dagger.Lazy;
 import dagger.Module;
@@ -86,6 +87,7 @@
             KeyguardRepositoryModule.class,
             KeyguardFaceAuthModule.class,
             StartKeyguardTransitionModule.class,
+            ResourceTrimmerModule.class,
         })
 public class KeyguardModule {
     /**
@@ -119,6 +121,7 @@
             ScreenOffAnimationController screenOffAnimationController,
             Lazy<NotificationShadeDepthController> notificationShadeDepthController,
             ScreenOnCoordinator screenOnCoordinator,
+            KeyguardTransitions keyguardTransitions,
             InteractionJankMonitor interactionJankMonitor,
             DreamOverlayStateController dreamOverlayStateController,
             Lazy<ShadeController> shadeController,
@@ -152,6 +155,7 @@
                 screenOffAnimationController,
                 notificationShadeDepthController,
                 screenOnCoordinator,
+                keyguardTransitions,
                 interactionJankMonitor,
                 dreamOverlayStateController,
                 shadeController,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/ResourceTrimmerModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/ResourceTrimmerModule.java
new file mode 100644
index 0000000..d693326
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/ResourceTrimmerModule.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.dagger;
+
+import com.android.systemui.CoreStartable;
+import com.android.systemui.keyguard.ResourceTrimmer;
+
+import dagger.Binds;
+import dagger.Module;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
+
+/**
+ * Binds {@link ResourceTrimmer} into {@link CoreStartable} set.
+ */
+@Module
+public abstract class ResourceTrimmerModule {
+
+    /** Bind ResourceTrimmer into CoreStarteables. */
+    @Binds
+    @IntoMap
+    @ClassKey(ResourceTrimmer.class)
+    public abstract CoreStartable bindResourceTrimmer(ResourceTrimmer resourceTrimmer);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt
index 0055f9a..0b6c7c4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt
@@ -25,7 +25,6 @@
 import android.os.UserHandle
 import android.util.Log
 import com.android.internal.widget.LockPatternUtils
-import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN
 import com.android.systemui.Dumpable
 import com.android.systemui.R
 import com.android.systemui.biometrics.AuthController
@@ -36,13 +35,14 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dump.DumpManager
-import com.android.systemui.keyguard.TAG
+import com.android.systemui.keyguard.shared.model.AuthenticationFlags
 import com.android.systemui.keyguard.shared.model.DevicePosture
 import com.android.systemui.user.data.repository.UserRepository
 import java.io.PrintWriter
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -108,10 +108,14 @@
      * lockdown.
      */
     val isCurrentUserInLockdown: Flow<Boolean>
+
+    /** Authentication flags set for the current user. */
+    val authenticationFlags: Flow<AuthenticationFlags>
 }
 
-const val TAG = "BiometricsRepositoryImpl"
+private const val TAG = "BiometricsRepositoryImpl"
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SysUISingleton
 class BiometricSettingsRepositoryImpl
 @Inject
@@ -129,6 +133,8 @@
     dumpManager: DumpManager,
 ) : BiometricSettingsRepository, Dumpable {
 
+    private val biometricsEnabledForUser = mutableMapOf<Int, Boolean>()
+
     override val isFaceAuthSupportedInCurrentPosture: Flow<Boolean>
 
     private val strongAuthTracker = StrongAuthTracker(userRepository, context)
@@ -136,6 +142,9 @@
     override val isCurrentUserInLockdown: Flow<Boolean> =
         strongAuthTracker.currentUserAuthFlags.map { it.isInUserLockdown }
 
+    override val authenticationFlags: Flow<AuthenticationFlags> =
+        strongAuthTracker.currentUserAuthFlags
+
     init {
         Log.d(TAG, "Registering StrongAuthTracker")
         lockPatternUtils.registerStrongAuthTracker(strongAuthTracker)
@@ -231,9 +240,14 @@
             }
         }
 
+    private val isFaceEnabledByBiometricsManagerForCurrentUser: Flow<Boolean> =
+        userRepository.selectedUserInfo.flatMapLatest { userInfo ->
+            isFaceEnabledByBiometricsManager.map { biometricsEnabledForUser[userInfo.id] ?: false }
+        }
+
     override val isFaceAuthenticationEnabled: Flow<Boolean>
         get() =
-            combine(isFaceEnabledByBiometricsManager, isFaceEnabledByDevicePolicy) {
+            combine(isFaceEnabledByBiometricsManagerForCurrentUser, isFaceEnabledByDevicePolicy) {
                 biometricsManagerSetting,
                 devicePolicySetting ->
                 biometricsManagerSetting && devicePolicySetting
@@ -249,13 +263,13 @@
             .flowOn(backgroundDispatcher)
             .distinctUntilChanged()
 
-    private val isFaceEnabledByBiometricsManager =
+    private val isFaceEnabledByBiometricsManager: Flow<Pair<Int, Boolean>> =
         conflatedCallbackFlow {
                 val callback =
                     object : IBiometricEnabledOnKeyguardCallback.Stub() {
                         override fun onChanged(enabled: Boolean, userId: Int) {
                             trySendWithFailureLogging(
-                                enabled,
+                                Pair(userId, enabled),
                                 TAG,
                                 "biometricsEnabled state changed"
                             )
@@ -264,9 +278,10 @@
                 biometricManager?.registerEnabledOnKeyguardCallback(callback)
                 awaitClose {}
             }
+            .onEach { biometricsEnabledForUser[it.first] = it.second }
             // This is because the callback is binder-based and we want to avoid multiple callbacks
             // being registered.
-            .stateIn(scope, SharingStarted.Eagerly, false)
+            .stateIn(scope, SharingStarted.Eagerly, Pair(0, false))
 
     override val isStrongBiometricAllowed: StateFlow<Boolean> =
         strongAuthTracker.isStrongBiometricAllowed.stateIn(
@@ -306,14 +321,13 @@
             )
 }
 
+@OptIn(ExperimentalCoroutinesApi::class)
 private class StrongAuthTracker(private val userRepository: UserRepository, context: Context?) :
     LockPatternUtils.StrongAuthTracker(context) {
 
     // Backing field for onStrongAuthRequiredChanged
-    private val _strongAuthFlags =
-        MutableStateFlow(
-            StrongAuthenticationFlags(currentUserId, getStrongAuthForUser(currentUserId))
-        )
+    private val _authFlags =
+        MutableStateFlow(AuthenticationFlags(currentUserId, getStrongAuthForUser(currentUserId)))
 
     // Backing field for onIsNonStrongBiometricAllowedChanged
     private val _nonStrongBiometricAllowed =
@@ -321,17 +335,15 @@
             Pair(currentUserId, isNonStrongBiometricAllowedAfterIdleTimeout(currentUserId))
         )
 
-    val currentUserAuthFlags: Flow<StrongAuthenticationFlags> =
+    val currentUserAuthFlags: Flow<AuthenticationFlags> =
         userRepository.selectedUserInfo
             .map { it.id }
             .distinctUntilChanged()
             .flatMapLatest { userId ->
-                _strongAuthFlags
-                    .filter { it.userId == userId }
+                _authFlags
+                    .map { AuthenticationFlags(userId, getStrongAuthForUser(userId)) }
                     .onEach { Log.d(TAG, "currentUser authFlags changed, new value: $it") }
-                    .onStart {
-                        emit(StrongAuthenticationFlags(userId, getStrongAuthForUser(userId)))
-                    }
+                    .onStart { emit(AuthenticationFlags(userId, getStrongAuthForUser(userId))) }
             }
 
     /** isStrongBiometricAllowed for the current user. */
@@ -356,7 +368,7 @@
 
     override fun onStrongAuthRequiredChanged(userId: Int) {
         val newFlags = getStrongAuthForUser(userId)
-        _strongAuthFlags.value = StrongAuthenticationFlags(userId, newFlags)
+        _authFlags.value = AuthenticationFlags(userId, newFlags)
         Log.d(TAG, "onStrongAuthRequiredChanged for userId: $userId, flag value: $newFlags")
     }
 
@@ -375,11 +387,3 @@
 
 private fun DevicePolicyManager.isNotActive(userId: Int, policy: Int): Boolean =
     (getKeyguardDisabledFeatures(null, userId) and policy) == 0
-
-private data class StrongAuthenticationFlags(val userId: Int, val flag: Int) {
-    val isInUserLockdown = containsFlag(flag, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN)
-}
-
-private fun containsFlag(haystack: Int, needle: Int): Boolean {
-    return haystack and needle != 0
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
index 7c14280..5d15e69 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
@@ -22,7 +22,7 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN
 import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
-import com.android.systemui.log.dagger.BouncerLog
+import com.android.systemui.log.dagger.BouncerTableLog
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.log.table.logDiffsForTable
 import com.android.systemui.util.time.SystemClock
@@ -105,7 +105,7 @@
 constructor(
     private val clock: SystemClock,
     @Application private val applicationScope: CoroutineScope,
-    @BouncerLog private val buffer: TableLogBuffer,
+    @BouncerTableLog private val buffer: TableLogBuffer,
 ) : KeyguardBouncerRepository {
     /** Values associated with the PrimaryBouncer (pin/pattern/password) input. */
     private val _primaryBouncerShow = MutableStateFlow(false)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt
new file mode 100644
index 0000000..641e20b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.data.repository
+
+import android.os.UserHandle
+import android.provider.Settings
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.keyguard.shared.model.SettingsClockSize
+import com.android.systemui.util.settings.SecureSettings
+import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.withContext
+
+@SysUISingleton
+class KeyguardClockRepository
+@Inject
+constructor(
+    private val secureSettings: SecureSettings,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+) {
+
+    val selectedClockSize: Flow<SettingsClockSize> =
+        secureSettings
+            .observerFlow(
+                names = arrayOf(Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK),
+                userId = UserHandle.USER_SYSTEM,
+            )
+            .onStart { emit(Unit) } // Forces an initial update.
+            .map { getClockSize() }
+
+    private suspend fun getClockSize(): SettingsClockSize {
+        return withContext(backgroundDispatcher) {
+            if (
+                secureSettings.getIntForUser(
+                    Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK,
+                    1,
+                    UserHandle.USER_CURRENT
+                ) == 1
+            ) {
+                SettingsClockSize.DYNAMIC
+            } else {
+                SettingsClockSize.SMALL
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt
index e7b9af6..4055fd0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt
@@ -16,8 +16,14 @@
 
 package com.android.systemui.keyguard.data.repository
 
+import com.android.systemui.CoreStartable
+import com.android.systemui.keyguard.bouncer.data.repository.BouncerMessageRepository
+import com.android.systemui.keyguard.bouncer.data.repository.BouncerMessageRepositoryImpl
+import com.android.systemui.keyguard.bouncer.domain.interactor.BouncerMessageAuditLogger
 import dagger.Binds
 import dagger.Module
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
 
 @Module
 interface KeyguardRepositoryModule {
@@ -46,5 +52,13 @@
     @Binds
     fun keyguardBouncerRepository(impl: KeyguardBouncerRepositoryImpl): KeyguardBouncerRepository
 
+    @Binds
+    fun bouncerMessageRepository(impl: BouncerMessageRepositoryImpl): BouncerMessageRepository
+
+    @Binds
+    @IntoMap
+    @ClassKey(BouncerMessageAuditLogger::class)
+    fun bind(impl: BouncerMessageAuditLogger): CoreStartable
+
     @Binds fun trustRepository(impl: TrustRepositoryImpl): TrustRepository
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
index f2f1c48..867675b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.shared.model.ActiveUnlockModel
 import com.android.systemui.keyguard.shared.model.TrustManagedModel
 import com.android.systemui.keyguard.shared.model.TrustModel
 import com.android.systemui.user.data.repository.UserRepository
@@ -29,7 +30,6 @@
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
@@ -45,8 +45,8 @@
     /** Flow representing whether the current user is trusted. */
     val isCurrentUserTrusted: Flow<Boolean>
 
-    /** Flow representing whether active unlock is available for the current user. */
-    val isCurrentUserActiveUnlockAvailable: StateFlow<Boolean>
+    /** Flow representing whether active unlock is running for the current user. */
+    val isCurrentUserActiveUnlockRunning: Flow<Boolean>
 
     /** Reports that whether trust is managed has changed for the current user. */
     val isCurrentUserTrustManaged: StateFlow<Boolean>
@@ -62,6 +62,7 @@
     private val logger: TrustRepositoryLogger,
 ) : TrustRepository {
     private val latestTrustModelForUser = mutableMapOf<Int, TrustModel>()
+    private val activeUnlockRunningForUser = mutableMapOf<Int, ActiveUnlockModel>()
     private val trustManagedForUser = mutableMapOf<Int, TrustManagedModel>()
 
     private val trust =
@@ -87,6 +88,17 @@
 
                         override fun onEnabledTrustAgentsChanged(userId: Int) = Unit
 
+                        override fun onIsActiveUnlockRunningChanged(
+                            isRunning: Boolean,
+                            userId: Int
+                        ) {
+                            trySendWithFailureLogging(
+                                ActiveUnlockModel(isRunning, userId),
+                                TrustRepositoryLogger.TAG,
+                                "onActiveUnlockRunningChanged"
+                            )
+                        }
+
                         override fun onTrustManagedChanged(isTrustManaged: Boolean, userId: Int) {
                             logger.onTrustManagedChanged(isTrustManaged, userId)
                             trySendWithFailureLogging(
@@ -95,11 +107,6 @@
                                 "onTrustManagedChanged"
                             )
                         }
-
-                        override fun onIsActiveUnlockRunningChanged(
-                            isRunning: Boolean,
-                            userId: Int
-                        ) = Unit
                     }
                 trustManager.registerTrustListener(callback)
                 logger.trustListenerRegistered()
@@ -114,6 +121,10 @@
                         latestTrustModelForUser[it.userId] = it
                         logger.trustModelEmitted(it)
                     }
+                    is ActiveUnlockModel -> {
+                        activeUnlockRunningForUser[it.userId] = it
+                        logger.activeUnlockModelEmitted(it)
+                    }
                     is TrustManagedModel -> {
                         trustManagedForUser[it.userId] = it
                         logger.trustManagedModelEmitted(it)
@@ -122,8 +133,17 @@
             }
             .shareIn(applicationScope, started = SharingStarted.Eagerly, replay = 1)
 
-    // TODO: Implement based on TrustManager callback b/267322286
-    override val isCurrentUserActiveUnlockAvailable: StateFlow<Boolean> = MutableStateFlow(true)
+    override val isCurrentUserActiveUnlockRunning: Flow<Boolean> =
+        combine(trust, userRepository.selectedUserInfo, ::Pair)
+            .map { activeUnlockRunningForUser[it.second.id]?.isRunning ?: false }
+            .distinctUntilChanged()
+            .onEach { logger.isCurrentUserActiveUnlockRunning(it) }
+            .onStart {
+                emit(
+                    activeUnlockRunningForUser[userRepository.getSelectedUserInfo().id]?.isRunning
+                        ?: false
+                )
+            }
 
     override val isCurrentUserTrustManaged: StateFlow<Boolean>
         get() =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt
new file mode 100644
index 0000000..98f445c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt
@@ -0,0 +1,34 @@
+/*
+ *  Copyright (C) 2023 The Android Open Source Project
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.data.repository.KeyguardClockRepository
+import com.android.systemui.keyguard.shared.model.SettingsClockSize
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+
+/** Encapsulates business-logic related to the keyguard clock. */
+@SysUISingleton
+class KeyguardClockInteractor
+@Inject
+constructor(
+    repository: KeyguardClockRepository,
+) {
+    val selectedClockSize: Flow<SettingsClockSize> = repository.selectedClockSize
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt
index ea6700e..ca430da 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt
@@ -17,12 +17,14 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
+import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
 import android.view.accessibility.AccessibilityManager
 import androidx.annotation.VisibleForTesting
 import com.android.internal.logging.UiEvent
 import com.android.internal.logging.UiEventLogger
+import com.android.systemui.R
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
@@ -55,6 +57,7 @@
 class KeyguardLongPressInteractor
 @Inject
 constructor(
+    @Application private val appContext: Context,
     @Application private val scope: CoroutineScope,
     transitionInteractor: KeyguardTransitionInteractor,
     repository: KeyguardRepository,
@@ -169,7 +172,8 @@
 
     private fun isFeatureEnabled(): Boolean {
         return featureFlags.isEnabled(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED) &&
-            featureFlags.isEnabled(Flags.REVAMPED_WALLPAPER_UI)
+            featureFlags.isEnabled(Flags.REVAMPED_WALLPAPER_UI) &&
+            appContext.resources.getBoolean(R.bool.long_press_keyguard_customize_lockscreen_enabled)
     }
 
     /** Updates application state to ask to show the menu. */
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
index 8e65c4d..2275337 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
@@ -19,12 +19,15 @@
 
 import android.app.AlertDialog
 import android.app.admin.DevicePolicyManager
+import android.content.Context
 import android.content.Intent
 import android.util.Log
 import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.R
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.animation.Expandable
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
 import com.android.systemui.dock.DockManager
@@ -75,6 +78,7 @@
     private val devicePolicyManager: DevicePolicyManager,
     private val dockManager: DockManager,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
+    @Application private val appContext: Context,
 ) {
     private val isUsingRepository: Boolean
         get() = featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)
@@ -408,7 +412,8 @@
                 name = Contract.FlagsTable.FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED,
                 value =
                     !isFeatureDisabledByDevicePolicy() &&
-                        featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES),
+                        featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES) &&
+                        appContext.resources.getBoolean(R.bool.custom_lockscreen_shortcuts_enabled),
             ),
             KeyguardPickerFlag(
                 name = Contract.FlagsTable.FLAG_NAME_CUSTOM_CLOCKS_ENABLED,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockScreenSceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt
similarity index 87%
rename from packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockScreenSceneInteractor.kt
rename to packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt
index 6170180..d0bc25f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockScreenSceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt
@@ -36,8 +36,8 @@
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
 
-/** Hosts business and application state accessing logic for the lock screen scene. */
-class LockScreenSceneInteractor
+/** Hosts business and application state accessing logic for the lockscreen scene. */
+class LockscreenSceneInteractor
 @AssistedInject
 constructor(
     @Application applicationScope: CoroutineScope,
@@ -59,7 +59,7 @@
                 initialValue = !authenticationInteractor.isUnlocked.value,
             )
 
-    /** Whether it's currently possible to swipe up to dismiss the lock screen. */
+    /** Whether it's currently possible to swipe up to dismiss the lockscreen. */
     val isSwipeToDismissEnabled: StateFlow<Boolean> =
         combine(
                 authenticationInteractor.isUnlocked,
@@ -81,9 +81,9 @@
             )
 
     init {
-        // LOCKING SHOWS LOCK SCREEN.
+        // LOCKING SHOWS Lockscreen.
         //
-        // Move to the lock screen scene if the device becomes locked while in any scene.
+        // Move to the lockscreen scene if the device becomes locked while in any scene.
         applicationScope.launch {
             authenticationInteractor.isUnlocked
                 .map { !it }
@@ -92,7 +92,7 @@
                     if (isLocked) {
                         sceneInteractor.setCurrentScene(
                             containerName = containerName,
-                            scene = SceneModel(SceneKey.LockScreen),
+                            scene = SceneModel(SceneKey.Lockscreen),
                         )
                     }
                 }
@@ -101,7 +101,7 @@
         // BYPASS UNLOCK.
         //
         // Moves to the gone scene if bypass is enabled and the device becomes unlocked while in the
-        // lock screen scene.
+        // lockscreen scene.
         applicationScope.launch {
             combine(
                     authenticationInteractor.isBypassEnabled,
@@ -110,7 +110,7 @@
                     ::Triple,
                 )
                 .collect { (isBypassEnabled, isUnlocked, currentScene) ->
-                    if (isBypassEnabled && isUnlocked && currentScene.key == SceneKey.LockScreen) {
+                    if (isBypassEnabled && isUnlocked && currentScene.key == SceneKey.Lockscreen) {
                         sceneInteractor.setCurrentScene(
                             containerName = containerName,
                             scene = SceneModel(SceneKey.Gone),
@@ -119,9 +119,9 @@
                 }
         }
 
-        // SWIPE TO DISMISS LOCK SCREEN.
+        // SWIPE TO DISMISS Lockscreen.
         //
-        // If switched from the lock screen to the gone scene and the auth method was a swipe,
+        // If switched from the lockscreen to the gone scene and the auth method was a swipe,
         // unlocks the device.
         applicationScope.launch {
             combine(
@@ -133,7 +133,7 @@
                     val (previousScene, currentScene) = scenes
                     if (
                         authMethod is AuthenticationMethodModel.Swipe &&
-                            previousScene.key == SceneKey.LockScreen &&
+                            previousScene.key == SceneKey.Lockscreen &&
                             currentScene.key == SceneKey.Gone
                     ) {
                         authenticationInteractor.unlockDevice()
@@ -141,9 +141,9 @@
                 }
         }
 
-        // DISMISS LOCK SCREEN IF AUTH METHOD IS REMOVED.
+        // DISMISS Lockscreen IF AUTH METHOD IS REMOVED.
         //
-        // If the auth method becomes None while on the lock screen scene, dismisses the lock
+        // If the auth method becomes None while on the lockscreen scene, dismisses the lock
         // screen.
         applicationScope.launch {
             combine(
@@ -153,7 +153,7 @@
                 )
                 .collect { (authMethod, scene) ->
                     if (
-                        scene.key == SceneKey.LockScreen &&
+                        scene.key == SceneKey.Lockscreen &&
                             authMethod == AuthenticationMethodModel.None
                     ) {
                         sceneInteractor.setCurrentScene(
@@ -165,8 +165,8 @@
         }
     }
 
-    /** Attempts to dismiss the lock screen. This will cause the bouncer to show, if needed. */
-    fun dismissLockScreen() {
+    /** Attempts to dismiss the lockscreen. This will cause the bouncer to show, if needed. */
+    fun dismissLockscreen() {
         bouncerInteractor.showOrUnlockDevice(containerName = containerName)
     }
 
@@ -181,6 +181,6 @@
     interface Factory {
         fun create(
             containerName: String,
-        ): LockScreenSceneInteractor
+        ): LockscreenSceneInteractor
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
index 110bcd7..54bc349 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
@@ -31,6 +31,7 @@
 import com.android.systemui.R
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
@@ -39,15 +40,19 @@
 import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
 import com.android.systemui.keyguard.data.repository.TrustRepository
 import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN
 import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.shared.system.SysUiStatsLog
 import com.android.systemui.statusbar.policy.KeyguardStateController
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
 import javax.inject.Inject
 
 /**
@@ -58,18 +63,19 @@
 class PrimaryBouncerInteractor
 @Inject
 constructor(
-        private val repository: KeyguardBouncerRepository,
-        private val primaryBouncerView: BouncerView,
-        @Main private val mainHandler: Handler,
-        private val keyguardStateController: KeyguardStateController,
-        private val keyguardSecurityModel: KeyguardSecurityModel,
-        private val primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor,
-        private val falsingCollector: FalsingCollector,
-        private val dismissCallbackRegistry: DismissCallbackRegistry,
-        private val context: Context,
-        private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
-        private val trustRepository: TrustRepository,
-        private val featureFlags: FeatureFlags,
+    private val repository: KeyguardBouncerRepository,
+    private val primaryBouncerView: BouncerView,
+    @Main private val mainHandler: Handler,
+    private val keyguardStateController: KeyguardStateController,
+    private val keyguardSecurityModel: KeyguardSecurityModel,
+    private val primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor,
+    private val falsingCollector: FalsingCollector,
+    private val dismissCallbackRegistry: DismissCallbackRegistry,
+    private val context: Context,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+    private val trustRepository: TrustRepository,
+    private val featureFlags: FeatureFlags,
+    @Application private val applicationScope: CoroutineScope,
 ) {
     private val passiveAuthBouncerDelay = context.resources.getInteger(
             R.integer.primary_bouncer_passive_auth_delay).toLong()
@@ -104,6 +110,7 @@
     /** Allow for interaction when just about fully visible */
     val isInteractable: Flow<Boolean> = bouncerExpansion.map { it > 0.9 }
     val sideFpsShowing: Flow<Boolean> = repository.sideFpsShowing
+    private var currentUserActiveUnlockRunning = false
 
     /** This callback needs to be a class field so it does not get garbage collected. */
     val keyguardUpdateMonitorCallback =
@@ -122,6 +129,13 @@
 
     init {
         keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
+        if (featureFlags.isEnabled(Flags.DELAY_BOUNCER)) {
+            applicationScope.launch {
+                trustRepository.isCurrentUserActiveUnlockRunning.collect {
+                    currentUserActiveUnlockRunning = it
+                }
+            }
+        }
     }
 
     // TODO(b/243685699): Move isScrimmed logic to data layer.
@@ -183,6 +197,7 @@
         cancelShowRunnable()
         repository.setPrimaryShowingSoon(false)
         repository.setPrimaryShow(false)
+        repository.setPanelExpansion(EXPANSION_HIDDEN)
         primaryBouncerCallbackInteractor.dispatchVisibilityChanged(View.INVISIBLE)
         Trace.endSection()
     }
@@ -377,8 +392,9 @@
     private fun usePrimaryBouncerPassiveAuthDelay(): Boolean {
         val canRunFaceAuth = keyguardStateController.isFaceAuthEnabled &&
                 keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE)
-        val canRunActiveUnlock = trustRepository.isCurrentUserActiveUnlockAvailable.value &&
+        val canRunActiveUnlock = currentUserActiveUnlockRunning &&
                 keyguardUpdateMonitor.canTriggerActiveUnlockBasedOnDeviceState()
+
         return featureFlags.isEnabled(Flags.DELAY_BOUNCER) &&
                 !needsFullscreenBouncer() &&
                 (canRunFaceAuth || canRunActiveUnlock)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/ActiveUnlockModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/ActiveUnlockModel.kt
new file mode 100644
index 0000000..7309072
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/ActiveUnlockModel.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.shared.model
+
+/** Represents the active unlock state */
+data class ActiveUnlockModel(
+    /** If true, the system believes active unlock is available and can be usd to unlock. */
+    val isRunning: Boolean,
+    /** The user, for which active unlock may be running. */
+    val userId: Int,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/AuthenticationFlags.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/AuthenticationFlags.kt
new file mode 100644
index 0000000..cf5b88f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/AuthenticationFlags.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.shared.model
+
+import com.android.internal.widget.LockPatternUtils
+
+/** Authentication flags corresponding to a user. */
+data class AuthenticationFlags(val userId: Int, val flag: Int) {
+    val isInUserLockdown =
+        containsFlag(
+            flag,
+            LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN
+        )
+
+    val isPrimaryAuthRequiredAfterReboot =
+        containsFlag(flag, LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT)
+
+    val isPrimaryAuthRequiredAfterTimeout =
+        containsFlag(flag, LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT)
+
+    val isPrimaryAuthRequiredAfterDpmLockdown =
+        containsFlag(
+            flag,
+            LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW
+        )
+
+    val someAuthRequiredAfterUserRequest =
+        containsFlag(flag, LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST)
+
+    val someAuthRequiredAfterTrustAgentExpired =
+        containsFlag(
+            flag,
+            LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED
+        )
+
+    val primaryAuthRequiredForUnattendedUpdate =
+        containsFlag(
+            flag,
+            LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE
+        )
+
+    /** Either Class 3 biometrics or primary auth can be used to unlock the device. */
+    val strongerAuthRequiredAfterNonStrongBiometricsTimeout =
+        containsFlag(
+            flag,
+            LockPatternUtils.StrongAuthTracker
+                .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT
+        )
+}
+
+private fun containsFlag(haystack: Int, needle: Int): Boolean {
+    return haystack and needle != 0
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt
index c8bd958..9e7dec4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt
@@ -38,7 +38,8 @@
 object FailedAuthenticationStatus : AuthenticationStatus()
 
 /** Face authentication error message */
-data class ErrorAuthenticationStatus(val msgId: Int, val msg: String?) : AuthenticationStatus() {
+data class ErrorAuthenticationStatus(val msgId: Int, val msg: String? = null) :
+    AuthenticationStatus() {
     /**
      * Method that checks if [msgId] is a lockout error. A lockout error means that face
      * authentication is locked out.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/SettingsClockSize.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/SettingsClockSize.kt
new file mode 100644
index 0000000..c6b0f58
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/SettingsClockSize.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.shared.model
+
+enum class SettingsClockSize {
+    DYNAMIC,
+    SMALL,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockSmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockSmartspaceViewBinder.kt
new file mode 100644
index 0000000..57c32b3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockSmartspaceViewBinder.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.ui.binder
+
+import android.view.View
+import androidx.core.view.isVisible
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewClockSmartspaceViewModel
+import com.android.systemui.lifecycle.repeatWhenAttached
+import kotlinx.coroutines.flow.collect
+
+/** Binder for the small clock view, large clock view and smartspace. */
+object KeyguardPreviewClockSmartspaceViewBinder {
+
+    @JvmStatic
+    fun bind(
+        largeClockHostView: View,
+        smallClockHostView: View,
+        smartspace: View?,
+        viewModel: KeyguardPreviewClockSmartspaceViewModel,
+    ) {
+        largeClockHostView.repeatWhenAttached {
+            repeatOnLifecycle(Lifecycle.State.STARTED) {
+                viewModel.isLargeClockVisible.collect { largeClockHostView.isVisible = it }
+            }
+        }
+
+        smallClockHostView.repeatWhenAttached {
+            repeatOnLifecycle(Lifecycle.State.STARTED) {
+                viewModel.isSmallClockVisible.collect { smallClockHostView.isVisible = it }
+            }
+        }
+
+        smartspace?.repeatWhenAttached {
+            repeatOnLifecycle(Lifecycle.State.STARTED) {
+                viewModel.smartSpaceTopPadding.collect { smartspace.setTopPadding(it) }
+            }
+        }
+    }
+
+    private fun View.setTopPadding(padding: Int) {
+        setPaddingRelative(paddingStart, padding, paddingEnd, paddingBottom)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 3aa57dd..4308d84 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -22,9 +22,11 @@
 import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
+import android.content.res.Resources
 import android.graphics.Rect
 import android.hardware.display.DisplayManager
 import android.os.Bundle
+import android.os.Handler
 import android.os.IBinder
 import android.view.LayoutInflater
 import android.view.SurfaceControlViewHost
@@ -32,6 +34,7 @@
 import android.view.ViewGroup
 import android.view.WindowManager
 import android.widget.FrameLayout
+import androidx.core.view.isInvisible
 import com.android.keyguard.ClockEventController
 import com.android.keyguard.KeyguardClockSwitch
 import com.android.systemui.R
@@ -39,8 +42,12 @@
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.keyguard.ui.binder.KeyguardPreviewClockSmartspaceViewBinder
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewClockSmartspaceViewModel
+import com.android.systemui.plugins.ClockController
 import com.android.systemui.shared.clocks.ClockRegistry
+import com.android.systemui.shared.clocks.DefaultClockController
 import com.android.systemui.shared.clocks.shared.model.ClockPreviewConstants
 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants
 import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController
@@ -57,6 +64,8 @@
 constructor(
     @Application private val context: Context,
     @Main private val mainDispatcher: CoroutineDispatcher,
+    @Main private val mainHandler: Handler,
+    private val clockSmartspaceViewModel: KeyguardPreviewClockSmartspaceViewModel,
     private val bottomAreaViewModel: KeyguardBottomAreaViewModel,
     displayManager: DisplayManager,
     private val windowManager: WindowManager,
@@ -76,6 +85,7 @@
             KeyguardPreviewConstants.KEY_HIGHLIGHT_QUICK_AFFORDANCES,
             false,
         )
+    /** [shouldHideClock] here means that we never create and bind the clock views */
     private val shouldHideClock: Boolean =
         bundle.getBoolean(ClockPreviewConstants.KEY_HIDE_CLOCK, false)
 
@@ -84,7 +94,8 @@
     val surfacePackage: SurfaceControlViewHost.SurfacePackage
         get() = host.surfacePackage
 
-    private var clockView: View? = null
+    private lateinit var largeClockHostView: FrameLayout
+    private lateinit var smallClockHostView: FrameLayout
     private var smartSpaceView: View? = null
     private var colorOverride: Int? = null
 
@@ -112,7 +123,7 @@
     }
 
     fun render() {
-        runBlocking(mainDispatcher) {
+        mainHandler.post {
             val rootView = FrameLayout(context)
 
             setUpBottomArea(rootView)
@@ -121,7 +132,15 @@
 
             setUpUdfps(rootView)
 
-            setUpClock(rootView)
+            if (!shouldHideClock) {
+                setUpClock(rootView)
+                KeyguardPreviewClockSmartspaceViewBinder.bind(
+                    largeClockHostView,
+                    smallClockHostView,
+                    smartSpaceView,
+                    clockSmartspaceViewModel,
+                )
+            }
 
             rootView.measure(
                 View.MeasureSpec.makeMeasureSpec(
@@ -168,14 +187,12 @@
      * @param hide TRUE hides smartspace, FALSE shows smartspace
      */
     fun hideSmartspace(hide: Boolean) {
-        runBlocking(mainDispatcher) {
-            smartSpaceView?.visibility = if (hide) View.INVISIBLE else View.VISIBLE
-        }
+        mainHandler.post { smartSpaceView?.visibility = if (hide) View.INVISIBLE else View.VISIBLE }
     }
 
     /** Sets the clock's color to the overridden seed color. */
     fun onColorOverridden(@ColorInt color: Int?) {
-        runBlocking(mainDispatcher) {
+        mainHandler.post {
             colorOverride = color
             clockController.clock?.run { events.onSeedColorChanged(color) }
         }
@@ -202,11 +219,9 @@
         smartSpaceView = lockscreenSmartspaceController.buildAndConnectDateView(parentView)
 
         val topPadding: Int =
-            with(context.resources) {
-                getDimensionPixelSize(R.dimen.status_bar_header_height_keyguard) +
-                    getDimensionPixelSize(R.dimen.keyguard_smartspace_top_offset) +
-                    getDimensionPixelSize(R.dimen.keyguard_clock_top_margin)
-            }
+            KeyguardPreviewClockSmartspaceViewModel.getLargeClockSmartspaceTopPadding(
+                context.resources
+            )
 
         val startPadding: Int =
             with(context.resources) {
@@ -281,10 +296,19 @@
     }
 
     private fun setUpClock(parentView: ViewGroup) {
+        largeClockHostView = createLargeClockHostView()
+        largeClockHostView.isInvisible = true
+        parentView.addView(largeClockHostView)
+
+        smallClockHostView = createSmallClockHostView(parentView.resources)
+        smallClockHostView.isInvisible = true
+        parentView.addView(smallClockHostView)
+
+        // TODO (b/283465254): Move the listeners to KeyguardClockRepository
         val clockChangeListener =
             object : ClockRegistry.ClockChangeListener {
                 override fun onCurrentClockChanged() {
-                    onClockChanged(parentView)
+                    onClockChanged()
                 }
             }
         clockRegistry.registerClockChangeListener(clockChangeListener)
@@ -313,36 +337,88 @@
         )
         disposables.add(DisposableHandle { broadcastDispatcher.unregisterReceiver(receiver) })
 
-        onClockChanged(parentView)
+        val layoutChangeListener =
+            View.OnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
+                if (clockController.clock !is DefaultClockController) {
+                    clockController.clock
+                        ?.largeClock
+                        ?.events
+                        ?.onTargetRegionChanged(KeyguardClockSwitch.getLargeClockRegion(parentView))
+                }
+            }
+        parentView.addOnLayoutChangeListener(layoutChangeListener)
+        disposables.add(
+            DisposableHandle { parentView.removeOnLayoutChangeListener(layoutChangeListener) }
+        )
+
+        onClockChanged()
     }
 
-    private fun onClockChanged(parentView: ViewGroup) {
+    private fun createLargeClockHostView(): FrameLayout {
+        val hostView = FrameLayout(context)
+        hostView.layoutParams =
+            FrameLayout.LayoutParams(
+                FrameLayout.LayoutParams.MATCH_PARENT,
+                FrameLayout.LayoutParams.MATCH_PARENT,
+            )
+        return hostView
+    }
+
+    private fun createSmallClockHostView(resources: Resources): FrameLayout {
+        val hostView = FrameLayout(context)
+        val layoutParams =
+            FrameLayout.LayoutParams(
+                FrameLayout.LayoutParams.WRAP_CONTENT,
+                resources.getDimensionPixelSize(R.dimen.small_clock_height)
+            )
+        layoutParams.topMargin =
+            KeyguardPreviewClockSmartspaceViewModel.getStatusBarHeight(resources) +
+                resources.getDimensionPixelSize(R.dimen.small_clock_padding_top)
+        hostView.layoutParams = layoutParams
+
+        hostView.setPaddingRelative(
+            resources.getDimensionPixelSize(R.dimen.clock_padding_start),
+            0,
+            0,
+            0
+        )
+        hostView.clipChildren = false
+        return hostView
+    }
+
+    private fun onClockChanged() {
         val clock = clockRegistry.createCurrentClock()
         clockController.clock = clock
 
         colorOverride?.let { clock.events.onSeedColorChanged(it) }
-        if (!shouldHideClock) {
-            clock.largeClock.events.onTargetRegionChanged(
-                KeyguardClockSwitch.getLargeClockRegion(parentView)
-            )
 
-            clockView?.let { parentView.removeView(it) }
-            clockView =
-                clock.largeClock.view.apply {
-                    if (shouldHighlightSelectedAffordance) {
-                        alpha = DIM_ALPHA
-                    }
-                    parentView.addView(this)
-                    visibility = View.VISIBLE
-                }
-        } else {
-            clockView?.visibility = View.GONE
-        }
+        updateLargeClock(clock)
+        updateSmallClock(clock)
 
         // Hide smart space if the clock has weather display; otherwise show it
-        val hasCustomWeatherDataDisplay =
-            clock.largeClock.config.hasCustomWeatherDataDisplay == true
-        hideSmartspace(hasCustomWeatherDataDisplay)
+        hideSmartspace(clock.largeClock.config.hasCustomWeatherDataDisplay)
+    }
+
+    private fun updateLargeClock(clock: ClockController) {
+        clock.largeClock.events.onTargetRegionChanged(
+            KeyguardClockSwitch.getLargeClockRegion(largeClockHostView)
+        )
+        if (shouldHighlightSelectedAffordance) {
+            clock.largeClock.view.alpha = DIM_ALPHA
+        }
+        largeClockHostView.removeAllViews()
+        largeClockHostView.addView(clock.largeClock.view)
+    }
+
+    private fun updateSmallClock(clock: ClockController) {
+        clock.smallClock.events.onTargetRegionChanged(
+            KeyguardClockSwitch.getSmallClockRegion(smallClockHostView)
+        )
+        if (shouldHighlightSelectedAffordance) {
+            clock.smallClock.view.alpha = DIM_ALPHA
+        }
+        smallClockHostView.removeAllViews()
+        smallClockHostView.addView(clock.smallClock.view)
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockSmartspaceViewModel.kt
new file mode 100644
index 0000000..00c603b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockSmartspaceViewModel.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import android.content.Context
+import android.content.res.Resources
+import com.android.systemui.R
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
+import com.android.systemui.keyguard.shared.model.SettingsClockSize
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
+
+/** View model for the small clock view, large clock view and smartspace. */
+class KeyguardPreviewClockSmartspaceViewModel
+@Inject
+constructor(
+    @Application private val context: Context,
+    interactor: KeyguardClockInteractor,
+) {
+
+    val isLargeClockVisible: Flow<Boolean> =
+        interactor.selectedClockSize.map { it == SettingsClockSize.DYNAMIC }
+
+    val isSmallClockVisible: Flow<Boolean> =
+        interactor.selectedClockSize.map { it == SettingsClockSize.SMALL }
+
+    val smartSpaceTopPadding: Flow<Int> =
+        interactor.selectedClockSize.map {
+            when (it) {
+                SettingsClockSize.DYNAMIC -> getLargeClockSmartspaceTopPadding(context.resources)
+                SettingsClockSize.SMALL -> getSmallClockSmartspaceTopPadding(context.resources)
+            }
+        }
+
+    companion object {
+        fun getLargeClockSmartspaceTopPadding(resources: Resources): Int {
+            return with(resources) {
+                getDimensionPixelSize(R.dimen.status_bar_header_height_keyguard) +
+                    getDimensionPixelSize(R.dimen.keyguard_smartspace_top_offset) +
+                    getDimensionPixelSize(R.dimen.keyguard_clock_top_margin)
+            }
+        }
+
+        fun getSmallClockSmartspaceTopPadding(resources: Resources): Int {
+            return with(resources) {
+                getStatusBarHeight(this) +
+                    getDimensionPixelSize(R.dimen.small_clock_padding_top) +
+                    getDimensionPixelSize(R.dimen.small_clock_height)
+            }
+        }
+
+        fun getStatusBarHeight(resource: Resources): Int {
+            var result = 0
+            val resourceId: Int = resource.getIdentifier("status_bar_height", "dimen", "android")
+            if (resourceId > 0) {
+                result = resource.getDimensionPixelSize(resourceId)
+            }
+            return result
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockScreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
similarity index 88%
rename from packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockScreenSceneViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
index 08b9613..f212a55 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockScreenSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
@@ -20,7 +20,7 @@
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.keyguard.domain.interactor.LockScreenSceneInteractor
+import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
 import com.android.systemui.scene.shared.model.SceneKey
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
@@ -31,17 +31,17 @@
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 
-/** Models UI state and handles user input for the lock screen scene. */
-class LockScreenSceneViewModel
+/** Models UI state and handles user input for the lockscreen scene. */
+class LockscreenSceneViewModel
 @AssistedInject
 constructor(
     @Application applicationScope: CoroutineScope,
-    interactorFactory: LockScreenSceneInteractor.Factory,
+    interactorFactory: LockscreenSceneInteractor.Factory,
     @Assisted containerName: String,
 ) {
-    private val interactor: LockScreenSceneInteractor = interactorFactory.create(containerName)
+    private val interactor: LockscreenSceneInteractor = interactorFactory.create(containerName)
 
-    /** The icon for the "lock" button on the lock screen. */
+    /** The icon for the "lock" button on the lockscreen. */
     val lockButtonIcon: StateFlow<Icon> =
         interactor.isDeviceLocked
             .map { isLocked -> lockIcon(isLocked = isLocked) }
@@ -63,12 +63,12 @@
 
     /** Notifies that the lock button on the lock screen was clicked. */
     fun onLockButtonClicked() {
-        interactor.dismissLockScreen()
+        interactor.dismissLockscreen()
     }
 
     /** Notifies that some content on the lock screen was clicked. */
     fun onContentClicked() {
-        interactor.dismissLockScreen()
+        interactor.dismissLockscreen()
     }
 
     private fun upDestinationSceneKey(
@@ -103,6 +103,6 @@
     interface Factory {
         fun create(
             containerName: String,
-        ): LockScreenSceneViewModel
+        ): LockscreenSceneViewModel
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/log/BouncerLogger.kt b/packages/SystemUI/src/com/android/systemui/log/BouncerLogger.kt
new file mode 100644
index 0000000..3be4499
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/BouncerLogger.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.bouncer.shared.model.BouncerMessageModel
+import com.android.systemui.log.dagger.BouncerLog
+import javax.inject.Inject
+
+private const val TAG = "BouncerLog"
+
+/**
+ * Helper class for logging for classes in the [com.android.systemui.keyguard.bouncer] package.
+ *
+ * To enable logcat echoing for an entire buffer:
+ * ```
+ *   adb shell settings put global systemui/buffer/BouncerLog <logLevel>
+ *
+ * ```
+ */
+@SysUISingleton
+class BouncerLogger @Inject constructor(@BouncerLog private val buffer: LogBuffer) {
+    fun startBouncerMessageInteractor() {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            "Starting BouncerMessageInteractor.bouncerMessage collector"
+        )
+    }
+
+    fun bouncerMessageUpdated(bouncerMsg: BouncerMessageModel?) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                int1 = bouncerMsg?.message?.messageResId ?: -1
+                str1 = bouncerMsg?.message?.message
+                int2 = bouncerMsg?.secondaryMessage?.messageResId ?: -1
+                str2 = bouncerMsg?.secondaryMessage?.message
+            },
+            { "Bouncer message update received: $int1, $str1, $int2, $str2" }
+        )
+    }
+
+    fun bindingBouncerMessageView() {
+        buffer.log(TAG, LogLevel.DEBUG, "Binding BouncerMessageView")
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/BouncerLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/BouncerLog.kt
index 2251a7b..0c2e731 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/BouncerLog.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/BouncerLog.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,10 +16,7 @@
 
 package com.android.systemui.log.dagger
 
-import java.lang.annotation.Documented
-import java.lang.annotation.Retention
-import java.lang.annotation.RetentionPolicy
 import javax.inject.Qualifier
 
-/** Logger for the primary and alternative bouncers. */
-@Qualifier @Documented @Retention(RetentionPolicy.RUNTIME) annotation class BouncerLog
+/** A [com.android.systemui.log.LogBuffer] for bouncer and its child views. */
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class BouncerLog()
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/model/PromptKind.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/BouncerTableLog.kt
similarity index 64%
copy from packages/SystemUI/src/com/android/systemui/biometrics/data/model/PromptKind.kt
copy to packages/SystemUI/src/com/android/systemui/log/dagger/BouncerTableLog.kt
index e82646f..08df7db 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/data/model/PromptKind.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/BouncerTableLog.kt
@@ -14,15 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.systemui.biometrics.data.model
+package com.android.systemui.log.dagger
 
-import com.android.systemui.biometrics.Utils
+import java.lang.annotation.Documented
+import java.lang.annotation.Retention
+import java.lang.annotation.RetentionPolicy
+import javax.inject.Qualifier
 
-// TODO(b/251476085): this should eventually replace Utils.CredentialType
-/** Credential options for biometric prompt. Shadows [Utils.CredentialType]. */
-enum class PromptKind {
-    ANY_BIOMETRIC,
-    PIN,
-    PATTERN,
-    PASSWORD,
-}
+/** Logger for the primary and alternative bouncers. */
+@Qualifier @Documented @Retention(RetentionPolicy.RUNTIME) annotation class BouncerTableLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/CarrierTextManagerLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/CarrierTextManagerLog.kt
new file mode 100644
index 0000000..62b80b2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/CarrierTextManagerLog.kt
@@ -0,0 +1,9 @@
+package com.android.systemui.log.dagger
+
+import javax.inject.Qualifier
+
+/** A [LogBuffer] for detailed carrier text logs. */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class CarrierTextManagerLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 9be18ac..0261ee5 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -60,7 +60,7 @@
         if (Compile.IS_DEBUG && notifPipelineFlags.isDevLoggingEnabled()) {
             maxSize *= 10;
         }
-        return factory.create("NotifLog", maxSize, false /* systrace */);
+        return factory.create("NotifLog", maxSize, Compile.IS_DEBUG /* systrace */);
     }
 
     /** Provides a logging buffer for all logs related to notifications on the lockscreen. */
@@ -373,6 +373,16 @@
     }
 
     /**
+     * Provides a {@link LogBuffer} for use by {@link com.android.keyguard.KeyguardUpdateMonitor}.
+     */
+    @Provides
+    @SysUISingleton
+    @CarrierTextManagerLog
+    public static LogBuffer provideCarrierTextManagerLog(LogBufferFactory factory) {
+        return factory.create("CarrierTextManagerLog", 100);
+    }
+
+    /**
      * Provides a {@link LogBuffer} for use by {@link com.android.systemui.ScreenDecorations}.
      */
     @Provides
@@ -394,6 +404,17 @@
     }
 
     /**
+     * Provides a {@link LogBuffer} for use by classes in the
+     *  {@link com.android.systemui.keyguard.bouncer} package.
+     */
+    @Provides
+    @SysUISingleton
+    @BouncerLog
+    public static LogBuffer provideBouncerLog(LogBufferFactory factory) {
+        return factory.create("BouncerLog", 100);
+    }
+
+    /**
      * Provides a {@link LogBuffer} for Device State Auto-Rotation logs.
      */
     @Provides
@@ -416,9 +437,17 @@
     /** Provides a logging buffer for the primary bouncer. */
     @Provides
     @SysUISingleton
-    @BouncerLog
+    @BouncerTableLog
     public static TableLogBuffer provideBouncerLogBuffer(TableLogBufferFactory factory) {
-        return factory.create("BouncerLog", 250);
+        return factory.create("BouncerTableLog", 250);
+    }
+
+    /** Provides a table logging buffer for the Monitor. */
+    @Provides
+    @SysUISingleton
+    @MonitorLog
+    public static TableLogBuffer provideMonitorTableLogBuffer(TableLogBufferFactory factory) {
+        return factory.create("MonitorLog", 250);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/MonitorLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/MonitorLog.kt
new file mode 100644
index 0000000..b6a4ec9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/MonitorLog.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger
+
+import javax.inject.Qualifier
+import kotlin.annotation.Retention
+
+/** Logger for Monitor. */
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class MonitorLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt
index cabe319..8d622ae 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.log.LogLevel
 import com.android.systemui.log.LogcatEchoTracker
+import com.android.systemui.plugins.log.TableLogBufferBase
 import com.android.systemui.util.time.SystemClock
 import java.io.PrintWriter
 import java.util.Locale
@@ -84,7 +85,7 @@
     @Background private val bgDispatcher: CoroutineDispatcher,
     private val coroutineScope: CoroutineScope,
     private val localLogcat: LogProxy = LogProxyDefault(),
-) : Dumpable {
+) : Dumpable, TableLogBufferBase {
     init {
         if (maxSize <= 0) {
             throw IllegalArgumentException("maxSize must be > 0")
@@ -177,7 +178,7 @@
      *
      * @param isInitial see [TableLogBuffer.logChange(String, Boolean, (TableRowLogger) -> Unit].
      */
-    fun logChange(prefix: String, columnName: String, value: String?, isInitial: Boolean = false) {
+    override fun logChange(prefix: String, columnName: String, value: String?, isInitial: Boolean) {
         logChange(systemClock.currentTimeMillis(), prefix, columnName, value, isInitial)
     }
 
@@ -186,7 +187,7 @@
      *
      * @param isInitial see [TableLogBuffer.logChange(String, Boolean, (TableRowLogger) -> Unit].
      */
-    fun logChange(prefix: String, columnName: String, value: Boolean, isInitial: Boolean = false) {
+    override fun logChange(prefix: String, columnName: String, value: Boolean, isInitial: Boolean) {
         logChange(systemClock.currentTimeMillis(), prefix, columnName, value, isInitial)
     }
 
@@ -195,7 +196,7 @@
      *
      * @param isInitial see [TableLogBuffer.logChange(String, Boolean, (TableRowLogger) -> Unit].
      */
-    fun logChange(prefix: String, columnName: String, value: Int?, isInitial: Boolean = false) {
+    override fun logChange(prefix: String, columnName: String, value: Int?, isInitial: Boolean) {
         logChange(systemClock.currentTimeMillis(), prefix, columnName, value, isInitial)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
index fa42114..6b993ce 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
@@ -16,10 +16,12 @@
 
 package com.android.systemui.media.controls.pipeline
 
+import android.annotation.SuppressLint
 import android.app.BroadcastOptions
 import android.app.Notification
 import android.app.Notification.EXTRA_SUBSTITUTE_APP_NAME
 import android.app.PendingIntent
+import android.app.StatusBarManager
 import android.app.smartspace.SmartspaceConfig
 import android.app.smartspace.SmartspaceManager
 import android.app.smartspace.SmartspaceSession
@@ -51,6 +53,7 @@
 import android.util.Log
 import android.util.Pair as APair
 import androidx.media.utils.MediaConstants
+import com.android.internal.annotations.Keep
 import com.android.internal.logging.InstanceId
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.Dumpable
@@ -137,6 +140,8 @@
         expiryTimeMs = 0,
     )
 
+const val MEDIA_TITLE_ERROR_MESSAGE = "Invalid media data: title is null or blank."
+
 fun isMediaNotification(sbn: StatusBarNotification): Boolean {
     return sbn.notification.isMediaNotification()
 }
@@ -215,7 +220,7 @@
     private val mediaEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
     // There should ONLY be at most one Smartspace media recommendation.
     var smartspaceMediaData: SmartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA
-    private var smartspaceSession: SmartspaceSession? = null
+    @Keep private var smartspaceSession: SmartspaceSession? = null
     private var allowMediaRecommendations = allowMediaRecommendations(context)
 
     private val artworkWidth =
@@ -225,6 +230,10 @@
     private val artworkHeight =
         context.resources.getDimensionPixelSize(R.dimen.qs_media_session_height_expanded)
 
+    @SuppressLint("WrongConstant") // sysui allowed to call STATUS_BAR_SERVICE
+    private val statusBarManager =
+        context.getSystemService(Context.STATUS_BAR_SERVICE) as StatusBarManager
+
     /** Check whether this notification is an RCN */
     private fun isRemoteCastNotification(sbn: StatusBarNotification): Boolean {
         return sbn.notification.extras.containsKey(Notification.EXTRA_MEDIA_REMOTE_DEVICE)
@@ -373,26 +382,28 @@
 
     fun destroy() {
         smartspaceMediaDataProvider.unregisterListener(this)
+        smartspaceSession?.close()
+        smartspaceSession = null
         context.unregisterReceiver(appChangeReceiver)
     }
 
     fun onNotificationAdded(key: String, sbn: StatusBarNotification) {
         if (useQsMediaPlayer && isMediaNotification(sbn)) {
-            var logEvent = false
+            var isNewlyActiveEntry = false
             Assert.isMainThread()
             val oldKey = findExistingEntry(key, sbn.packageName)
             if (oldKey == null) {
                 val instanceId = logger.getNewInstanceId()
                 val temp = LOADING.copy(packageName = sbn.packageName, instanceId = instanceId)
                 mediaEntries.put(key, temp)
-                logEvent = true
+                isNewlyActiveEntry = true
             } else if (oldKey != key) {
                 // Resume -> active conversion; move to new key
                 val oldData = mediaEntries.remove(oldKey)!!
-                logEvent = true
+                isNewlyActiveEntry = true
                 mediaEntries.put(key, oldData)
             }
-            loadMediaData(key, sbn, oldKey, logEvent)
+            loadMediaData(key, sbn, oldKey, isNewlyActiveEntry)
         } else {
             onNotificationRemoved(key)
         }
@@ -475,9 +486,9 @@
         key: String,
         sbn: StatusBarNotification,
         oldKey: String?,
-        logEvent: Boolean = false
+        isNewlyActiveEntry: Boolean = false,
     ) {
-        backgroundExecutor.execute { loadMediaDataInBg(key, sbn, oldKey, logEvent) }
+        backgroundExecutor.execute { loadMediaDataInBg(key, sbn, oldKey, isNewlyActiveEntry) }
     }
 
     /** Add a listener for changes in this class */
@@ -601,9 +612,11 @@
         }
     }
 
-    private fun removeEntry(key: String) {
+    private fun removeEntry(key: String, logEvent: Boolean = true) {
         mediaEntries.remove(key)?.let {
-            logger.logMediaRemoved(it.appUid, it.packageName, it.instanceId)
+            if (logEvent) {
+                logger.logMediaRemoved(it.appUid, it.packageName, it.instanceId)
+            }
         }
         notifyMediaDataRemoved(key)
     }
@@ -751,7 +764,7 @@
         key: String,
         sbn: StatusBarNotification,
         oldKey: String?,
-        logEvent: Boolean = false
+        isNewlyActiveEntry: Boolean = false,
     ) {
         val token =
             sbn.notification.extras.getParcelable(
@@ -772,6 +785,27 @@
             )
                 ?: getAppInfoFromPackage(sbn.packageName)
 
+        // App name
+        val appName = getAppName(sbn, appInfo)
+
+        // Song name
+        var song: CharSequence? = metadata?.getString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE)
+        if (song.isNullOrBlank()) {
+            song = metadata?.getString(MediaMetadata.METADATA_KEY_TITLE)
+        }
+        if (song.isNullOrBlank()) {
+            song = HybridGroupManager.resolveTitle(notif)
+        }
+        if (song.isNullOrBlank()) {
+            // For apps that don't include a title, log and add a placeholder
+            song = context.getString(R.string.controls_media_empty_title, appName)
+            try {
+                statusBarManager.logBlankMediaTitle(sbn.packageName, sbn.user.identifier)
+            } catch (e: RuntimeException) {
+                Log.e(TAG, "Error reporting blank media title for package ${sbn.packageName}")
+            }
+        }
+
         // Album art
         var artworkBitmap = metadata?.let { loadBitmapFromUri(it) }
         if (artworkBitmap == null) {
@@ -787,21 +821,9 @@
                 Icon.createWithBitmap(artworkBitmap)
             }
 
-        // App name
-        val appName = getAppName(sbn, appInfo)
-
         // App Icon
         val smallIcon = sbn.notification.smallIcon
 
-        // Song name
-        var song: CharSequence? = metadata?.getString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE)
-        if (song == null) {
-            song = metadata?.getString(MediaMetadata.METADATA_KEY_TITLE)
-        }
-        if (song == null) {
-            song = HybridGroupManager.resolveTitle(notif)
-        }
-
         // Explicit Indicator
         var isExplicit = false
         if (mediaFlags.isExplicitIndicatorEnabled()) {
@@ -813,7 +835,7 @@
 
         // Artist name
         var artist: CharSequence? = metadata?.getString(MediaMetadata.METADATA_KEY_ARTIST)
-        if (artist == null) {
+        if (artist.isNullOrBlank()) {
             artist = HybridGroupManager.resolveText(notif)
         }
 
@@ -873,7 +895,7 @@
         val instanceId = currentEntry?.instanceId ?: logger.getNewInstanceId()
         val appUid = appInfo?.uid ?: Process.INVALID_UID
 
-        if (logEvent) {
+        if (isNewlyActiveEntry) {
             logSingleVsMultipleMediaAdded(appUid, sbn.packageName, instanceId)
             logger.logActiveMediaAdded(appUid, sbn.packageName, instanceId, playbackLocation)
         } else if (playbackLocation != currentEntry?.playbackLocation) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
index 8f0ac28..32a7935 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
@@ -244,9 +244,10 @@
     private MultiRippleController mMultiRippleController;
     private TurbulenceNoiseController mTurbulenceNoiseController;
     private final FeatureFlags mFeatureFlags;
+
+    // TODO(b/281032715): Consider making this as a final variable. For now having a null check
+    //  due to unit test failure. (Perhaps missing some setup)
     private TurbulenceNoiseAnimationConfig mTurbulenceNoiseAnimationConfig;
-    @VisibleForTesting
-    MultiRippleController.Companion.RipplesFinishedListener mRipplesFinishedListener;
 
     /**
      * Initialize a new control panel
@@ -433,18 +434,6 @@
         MultiRippleView multiRippleView = vh.getMultiRippleView();
         mMultiRippleController = new MultiRippleController(multiRippleView);
         mTurbulenceNoiseController = new TurbulenceNoiseController(vh.getTurbulenceNoiseView());
-        if (mFeatureFlags.isEnabled(Flags.UMO_TURBULENCE_NOISE)) {
-            mRipplesFinishedListener = () -> {
-                if (mTurbulenceNoiseAnimationConfig == null) {
-                    mTurbulenceNoiseAnimationConfig = createTurbulenceNoiseAnimation();
-                }
-                // Color will be correctly updated in ColorSchemeTransition.
-                mTurbulenceNoiseController.play(mTurbulenceNoiseAnimationConfig);
-                mMainExecutor.executeDelayed(
-                        mTurbulenceNoiseController::finish, TURBULENCE_NOISE_PLAY_DURATION);
-            };
-            mMultiRippleController.addRipplesFinishedListener(mRipplesFinishedListener);
-        }
 
         mColorSchemeTransition = new ColorSchemeTransition(
                 mContext, mMediaViewHolder, mMultiRippleController, mTurbulenceNoiseController);
@@ -628,10 +617,7 @@
         seamlessView.setContentDescription(deviceString);
         seamlessView.setOnClickListener(
                 v -> {
-                    if (mFalsingManager.isFalseTap(
-                            mFeatureFlags.isEnabled(Flags.MEDIA_FALSING_PENALTY)
-                                    ? FalsingManager.MODERATE_PENALTY :
-                                    FalsingManager.LOW_PENALTY)) {
+                    if (mFalsingManager.isFalseTap(FalsingManager.MODERATE_PENALTY)) {
                         return;
                     }
 
@@ -1141,15 +1127,24 @@
             } else {
                 button.setEnabled(true);
                 button.setOnClickListener(v -> {
-                    if (!mFalsingManager.isFalseTap(
-                            mFeatureFlags.isEnabled(Flags.MEDIA_FALSING_PENALTY)
-                                    ? FalsingManager.MODERATE_PENALTY :
-                                    FalsingManager.LOW_PENALTY)) {
+                    if (!mFalsingManager.isFalseTap(FalsingManager.MODERATE_PENALTY)) {
                         mLogger.logTapAction(button.getId(), mUid, mPackageName, mInstanceId);
                         logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT);
                         action.run();
                         if (mFeatureFlags.isEnabled(Flags.UMO_SURFACE_RIPPLE)) {
                             mMultiRippleController.play(createTouchRippleAnimation(button));
+                            if (mFeatureFlags.isEnabled(Flags.UMO_TURBULENCE_NOISE)) {
+                                if (mTurbulenceNoiseAnimationConfig == null) {
+                                    mTurbulenceNoiseAnimationConfig =
+                                            createTurbulenceNoiseAnimation();
+                                }
+                                // Color will be correctly updated in ColorSchemeTransition.
+                                mTurbulenceNoiseController.play(mTurbulenceNoiseAnimationConfig);
+                                mMainExecutor.executeDelayed(
+                                        mTurbulenceNoiseController::finish,
+                                        TURBULENCE_NOISE_PLAY_DURATION
+                                );
+                            }
                         }
 
                         if (icon instanceof Animatable) {
@@ -1203,10 +1198,8 @@
                 /* width= */ mMediaViewHolder.getMultiRippleView().getWidth(),
                 /* height= */ mMediaViewHolder.getMultiRippleView().getHeight(),
                 TurbulenceNoiseAnimationConfig.DEFAULT_MAX_DURATION_IN_MILLIS,
-                /* easeInDuration= */
-                TurbulenceNoiseAnimationConfig.DEFAULT_EASING_DURATION_IN_MILLIS,
-                /* easeOutDuration= */
-                TurbulenceNoiseAnimationConfig.DEFAULT_EASING_DURATION_IN_MILLIS,
+                /* easeInDuration= */ 2500f,
+                /* easeOutDuration= */ 2500f,
                 this.getContext().getResources().getDisplayMetrics().density,
                 BlendMode.PLUS,
                 /* onAnimationEnd= */ null
@@ -1235,6 +1228,8 @@
         if ((buttonId == R.id.actionPrev && semanticActions.getReservePrev())
                 || (buttonId == R.id.actionNext && semanticActions.getReserveNext())) {
             notVisibleValue = ConstraintSet.INVISIBLE;
+            mMediaViewHolder.getAction(buttonId).setFocusable(visible);
+            mMediaViewHolder.getAction(buttonId).setClickable(visible);
         } else {
             notVisibleValue = ConstraintSet.GONE;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index d949cf56f..316c903e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -72,102 +72,67 @@
     public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
             int viewType) {
         super.onCreateViewHolder(viewGroup, viewType);
-        if (mController.isAdvancedLayoutSupported()) {
-            switch (viewType) {
-                case MediaItem.MediaItemType.TYPE_GROUP_DIVIDER:
-                    return new MediaGroupDividerViewHolder(mHolderView);
-                case MediaItem.MediaItemType.TYPE_PAIR_NEW_DEVICE:
-                case MediaItem.MediaItemType.TYPE_DEVICE:
-                default:
-                    return new MediaDeviceViewHolder(mHolderView);
-            }
-        } else {
-            return new MediaDeviceViewHolder(mHolderView);
+        switch (viewType) {
+            case MediaItem.MediaItemType.TYPE_GROUP_DIVIDER:
+                return new MediaGroupDividerViewHolder(mHolderView);
+            case MediaItem.MediaItemType.TYPE_PAIR_NEW_DEVICE:
+            case MediaItem.MediaItemType.TYPE_DEVICE:
+            default:
+                return new MediaDeviceViewHolder(mHolderView);
         }
     }
 
     @Override
     public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
-        if (mController.isAdvancedLayoutSupported()) {
-            if (position >= mMediaItemList.size()) {
-                if (DEBUG) {
-                    Log.d(TAG, "Incorrect position: " + position + " list size: "
-                            + mMediaItemList.size());
-                }
-                return;
+        if (position >= mMediaItemList.size()) {
+            if (DEBUG) {
+                Log.d(TAG, "Incorrect position: " + position + " list size: "
+                        + mMediaItemList.size());
             }
-            MediaItem currentMediaItem = mMediaItemList.get(position);
-            switch (currentMediaItem.getMediaItemType()) {
-                case MediaItem.MediaItemType.TYPE_GROUP_DIVIDER:
-                    ((MediaGroupDividerViewHolder) viewHolder).onBind(currentMediaItem.getTitle());
-                    break;
-                case MediaItem.MediaItemType.TYPE_PAIR_NEW_DEVICE:
-                    ((MediaDeviceViewHolder) viewHolder).onBind(CUSTOMIZED_ITEM_PAIR_NEW);
-                    break;
-                case MediaItem.MediaItemType.TYPE_DEVICE:
-                    ((MediaDeviceViewHolder) viewHolder).onBind(
-                            currentMediaItem.getMediaDevice().get(),
-                            position);
-                    break;
-                default:
-                    Log.d(TAG, "Incorrect position: " + position);
-            }
-        } else {
-            final int size = mController.getMediaDevices().size();
-            if (position == size) {
+            return;
+        }
+        MediaItem currentMediaItem = mMediaItemList.get(position);
+        switch (currentMediaItem.getMediaItemType()) {
+            case MediaItem.MediaItemType.TYPE_GROUP_DIVIDER:
+                ((MediaGroupDividerViewHolder) viewHolder).onBind(currentMediaItem.getTitle());
+                break;
+            case MediaItem.MediaItemType.TYPE_PAIR_NEW_DEVICE:
                 ((MediaDeviceViewHolder) viewHolder).onBind(CUSTOMIZED_ITEM_PAIR_NEW);
-            } else if (position < size) {
+                break;
+            case MediaItem.MediaItemType.TYPE_DEVICE:
                 ((MediaDeviceViewHolder) viewHolder).onBind(
-                        ((List<MediaDevice>) (mController.getMediaDevices())).get(position),
+                        currentMediaItem.getMediaDevice().get(),
                         position);
-            } else if (DEBUG) {
+                break;
+            default:
                 Log.d(TAG, "Incorrect position: " + position);
-            }
         }
     }
 
     @Override
     public long getItemId(int position) {
-        if (mController.isAdvancedLayoutSupported()) {
-            if (position >= mMediaItemList.size()) {
-                Log.d(TAG, "Incorrect position for item id: " + position);
-                return position;
-            }
-            MediaItem currentMediaItem = mMediaItemList.get(position);
-            return currentMediaItem.getMediaDevice().isPresent()
-                    ? currentMediaItem.getMediaDevice().get().getId().hashCode()
-                    : position;
-        }
-        final int size = mController.getMediaDevices().size();
-        if (position == size) {
-            return -1;
-        } else if (position < size) {
-            return ((List<MediaDevice>) (mController.getMediaDevices()))
-                    .get(position).getId().hashCode();
-        } else if (DEBUG) {
+        if (position >= mMediaItemList.size()) {
             Log.d(TAG, "Incorrect position for item id: " + position);
+            return position;
         }
-        return position;
+        MediaItem currentMediaItem = mMediaItemList.get(position);
+        return currentMediaItem.getMediaDevice().isPresent()
+                ? currentMediaItem.getMediaDevice().get().getId().hashCode()
+                : position;
     }
 
     @Override
     public int getItemViewType(int position) {
-        if (mController.isAdvancedLayoutSupported()
-                && position >= mMediaItemList.size()) {
+        if (position >= mMediaItemList.size()) {
             Log.d(TAG, "Incorrect position for item type: " + position);
             return MediaItem.MediaItemType.TYPE_GROUP_DIVIDER;
         }
-        return mController.isAdvancedLayoutSupported()
-                ? mMediaItemList.get(position).getMediaItemType()
-                : super.getItemViewType(position);
+        return mMediaItemList.get(position).getMediaItemType();
     }
 
     @Override
     public int getItemCount() {
-        // Add extra one for "pair new"
-        return mController.isAdvancedLayoutSupported()
-                ? mMediaItemList.size()
-                : mController.getMediaDevices().size() + 1;
+        return mMediaItemList.size();
     }
 
     class MediaDeviceViewHolder extends MediaDeviceBaseViewHolder {
@@ -203,17 +168,14 @@
                 // Set different layout for each device
                 if (device.isMutingExpectedDevice()
                         && !mController.isCurrentConnectedDeviceRemote()) {
-                    if (!mController.isAdvancedLayoutSupported()) {
-                        updateTitleIcon(R.drawable.media_output_icon_volume,
-                                mController.getColorItemContent());
-                    }
-                    initMutingExpectedDevice();
+                    updateTitleIcon(R.drawable.media_output_icon_volume,
+                            mController.getColorItemContent());
                     mCurrentActivePosition = position;
                     updateFullItemClickListener(v -> onItemClick(v, device));
                     setSingleLineLayout(getItemTitle(device));
+                    initMutingExpectedDevice();
                 } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
-                        && mController.isSubStatusSupported()
-                        && mController.isAdvancedLayoutSupported() && device.hasSubtext()) {
+                        && device.hasSubtext()) {
                     boolean isActiveWithOngoingSession =
                             (device.hasOngoingSession() && (currentlyConnected || isDeviceIncluded(
                                     mController.getSelectedMediaDevice(), device)));
@@ -284,10 +246,8 @@
                     // selected device in group
                     boolean isDeviceDeselectable = isDeviceIncluded(
                             mController.getDeselectableMediaDevice(), device);
-                    if (!mController.isAdvancedLayoutSupported()) {
-                        updateTitleIcon(R.drawable.media_output_icon_volume,
-                                mController.getColorItemContent());
-                    }
+                    updateTitleIcon(R.drawable.media_output_icon_volume,
+                            mController.getColorItemContent());
                     updateGroupableCheckBox(true, isDeviceDeselectable, device);
                     updateEndClickArea(device, isDeviceDeselectable);
                     setUpContentDescriptionForView(mContainerLayout, false, device);
@@ -305,8 +265,7 @@
                         updateFullItemClickListener(v -> cancelMuteAwaitConnection());
                         setSingleLineLayout(getItemTitle(device));
                     } else if (mController.isCurrentConnectedDeviceRemote()
-                            && !mController.getSelectableMediaDevice().isEmpty()
-                            && mController.isAdvancedLayoutSupported()) {
+                            && !mController.getSelectableMediaDevice().isEmpty()) {
                         //If device is connected and there's other selectable devices, layout as
                         // one of selected devices.
                         updateTitleIcon(R.drawable.media_output_icon_volume,
@@ -334,36 +293,27 @@
                     //groupable device
                     setUpDeviceIcon(device);
                     updateGroupableCheckBox(false, true, device);
-                    if (mController.isAdvancedLayoutSupported()) {
-                        updateEndClickArea(device, true);
-                    }
-                    updateFullItemClickListener(mController.isAdvancedLayoutSupported()
-                            ? v -> onItemClick(v, device)
-                            : v -> onGroupActionTriggered(true, device));
+                    updateEndClickArea(device, true);
+                    updateFullItemClickListener(v -> onItemClick(v, device));
                     setSingleLineLayout(getItemTitle(device), false /* showSeekBar */,
                             false /* showProgressBar */, true /* showCheckBox */,
                             true /* showEndTouchArea */);
                 } else {
                     setUpDeviceIcon(device);
                     setSingleLineLayout(getItemTitle(device));
-                    if (mController.isAdvancedLayoutSupported()
-                            && mController.isSubStatusSupported()) {
-                        Drawable deviceStatusIcon =
-                                device.hasOngoingSession() ? mContext.getDrawable(
-                                        R.drawable.ic_sound_bars_anim)
-                                        : Api34Impl.getDeviceStatusIconBasedOnSelectionBehavior(
-                                                device,
-                                                mContext);
-                        if (deviceStatusIcon != null) {
-                            updateDeviceStatusIcon(deviceStatusIcon);
-                            mStatusIcon.setVisibility(View.VISIBLE);
-                        }
-                        updateSingleLineLayoutContentAlpha(
-                                updateClickActionBasedOnSelectionBehavior(device)
-                                        ? DEVICE_CONNECTED_ALPHA : DEVICE_DISCONNECTED_ALPHA);
-                    } else {
-                        updateFullItemClickListener(v -> onItemClick(v, device));
+                    Drawable deviceStatusIcon =
+                            device.hasOngoingSession() ? mContext.getDrawable(
+                                    R.drawable.ic_sound_bars_anim)
+                                    : Api34Impl.getDeviceStatusIconBasedOnSelectionBehavior(
+                                            device,
+                                            mContext);
+                    if (deviceStatusIcon != null) {
+                        updateDeviceStatusIcon(deviceStatusIcon);
+                        mStatusIcon.setVisibility(View.VISIBLE);
                     }
+                    updateSingleLineLayoutContentAlpha(
+                            updateClickActionBasedOnSelectionBehavior(device)
+                                    ? DEVICE_CONNECTED_ALPHA : DEVICE_DISCONNECTED_ALPHA);
                 }
             }
         }
@@ -400,10 +350,8 @@
         }
 
         public void updateEndClickAreaColor(int color) {
-            if (mController.isAdvancedLayoutSupported()) {
-                mEndTouchArea.setBackgroundTintList(
-                        ColorStateList.valueOf(color));
-            }
+            mEndTouchArea.setBackgroundTintList(
+                    ColorStateList.valueOf(color));
         }
 
         private boolean updateClickActionBasedOnSelectionBehavior(MediaDevice device) {
@@ -440,10 +388,8 @@
                     isDeviceDeselectable ? (v) -> mCheckBox.performClick() : null);
             mEndTouchArea.setImportantForAccessibility(
                     View.IMPORTANT_FOR_ACCESSIBILITY_YES);
-            if (mController.isAdvancedLayoutSupported()) {
-                mEndTouchArea.setBackgroundTintList(
-                        ColorStateList.valueOf(mController.getColorItemBackground()));
-            }
+            mEndTouchArea.setBackgroundTintList(
+                    ColorStateList.valueOf(mController.getColorItemBackground()));
             setUpContentDescriptionForView(mEndTouchArea, true, device);
         }
 
@@ -473,10 +419,8 @@
                 mTitleIcon.setImageDrawable(addDrawable);
                 mTitleIcon.setImageTintList(
                         ColorStateList.valueOf(mController.getColorItemContent()));
-                if (mController.isAdvancedLayoutSupported()) {
-                    mIconAreaLayout.setBackgroundTintList(
-                            ColorStateList.valueOf(mController.getColorItemBackground()));
-                }
+                mIconAreaLayout.setBackgroundTintList(
+                        ColorStateList.valueOf(mController.getColorItemBackground()));
                 mContainerLayout.setOnClickListener(mController::launchBluetoothPairing);
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index 151dbb2..01f7904 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -47,7 +47,6 @@
 import androidx.annotation.VisibleForTesting;
 import androidx.recyclerview.widget.RecyclerView;
 
-import com.android.settingslib.Utils;
 import com.android.settingslib.media.MediaDevice;
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.systemui.R;
@@ -90,9 +89,8 @@
     public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
             int viewType) {
         mContext = viewGroup.getContext();
-        mHolderView = LayoutInflater.from(mContext).inflate(
-                mController.isAdvancedLayoutSupported() ? MediaItem.getMediaLayoutId(viewType)
-                        : R.layout.media_output_list_item, viewGroup, false);
+        mHolderView = LayoutInflater.from(mContext).inflate(MediaItem.getMediaLayoutId(viewType),
+                viewGroup, false);
 
         return null;
     }
@@ -174,15 +172,9 @@
             mStatusIcon = view.requireViewById(R.id.media_output_item_status);
             mCheckBox = view.requireViewById(R.id.check_box);
             mEndTouchArea = view.requireViewById(R.id.end_action_area);
-            if (mController.isAdvancedLayoutSupported()) {
-                mEndClickIcon = view.requireViewById(R.id.media_output_item_end_click_icon);
-                mVolumeValueText = view.requireViewById(R.id.volume_value);
-                mIconAreaLayout = view.requireViewById(R.id.icon_area);
-            } else {
-                mVolumeValueText = null;
-                mIconAreaLayout = null;
-                mEndClickIcon = null;
-            }
+            mEndClickIcon = view.requireViewById(R.id.media_output_item_end_click_icon);
+            mVolumeValueText = view.requireViewById(R.id.volume_value);
+            mIconAreaLayout = view.requireViewById(R.id.icon_area);
             initAnimator();
         }
 
@@ -194,13 +186,10 @@
             mEndTouchArea.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
             mContainerLayout.setOnClickListener(null);
             mContainerLayout.setContentDescription(null);
-            mTitleIcon.setOnClickListener(null);
             mTitleText.setTextColor(mController.getColorItemContent());
             mSubTitleText.setTextColor(mController.getColorItemContent());
             mTwoLineTitleText.setTextColor(mController.getColorItemContent());
-            if (mController.isAdvancedLayoutSupported()) {
-                mVolumeValueText.setTextColor(mController.getColorItemContent());
-            }
+            mVolumeValueText.setTextColor(mController.getColorItemContent());
             mSeekBar.setProgressTintList(
                     ColorStateList.valueOf(mController.getColorSeekbarProgress()));
         }
@@ -231,12 +220,10 @@
             mItemLayout.setBackgroundTintList(
                     ColorStateList.valueOf(isActive ? mController.getColorConnectedItemBackground()
                             : mController.getColorItemBackground()));
-            if (mController.isAdvancedLayoutSupported()) {
-                mIconAreaLayout.setBackgroundTintList(
-                        ColorStateList.valueOf(showSeekBar ? mController.getColorSeekbarProgress()
-                                : showProgressBar ? mController.getColorConnectedItemBackground()
-                                        : mController.getColorItemBackground()));
-            }
+            mIconAreaLayout.setBackgroundTintList(
+                    ColorStateList.valueOf(showSeekBar ? mController.getColorSeekbarProgress()
+                            : showProgressBar ? mController.getColorConnectedItemBackground()
+                                    : mController.getColorItemBackground()));
             mProgressBar.setVisibility(showProgressBar ? View.VISIBLE : View.GONE);
             mSeekBar.setAlpha(1);
             mSeekBar.setVisibility(showSeekBar ? View.VISIBLE : View.GONE);
@@ -247,12 +234,10 @@
             mTitleText.setVisibility(View.VISIBLE);
             mCheckBox.setVisibility(showCheckBox ? View.VISIBLE : View.GONE);
             mEndTouchArea.setVisibility(showEndTouchArea ? View.VISIBLE : View.GONE);
-            if (mController.isAdvancedLayoutSupported()) {
-                ViewGroup.MarginLayoutParams params =
-                        (ViewGroup.MarginLayoutParams) mItemLayout.getLayoutParams();
-                params.rightMargin = showEndTouchArea ? mController.getItemMarginEndSelectable()
-                        : mController.getItemMarginEndDefault();
-            }
+            ViewGroup.MarginLayoutParams params =
+                    (ViewGroup.MarginLayoutParams) mItemLayout.getLayoutParams();
+            params.rightMargin = showEndTouchArea ? mController.getItemMarginEndSelectable()
+                    : mController.getItemMarginEndDefault();
             mTitleIcon.setBackgroundTintList(
                     ColorStateList.valueOf(mController.getColorItemContent()));
         }
@@ -273,34 +258,28 @@
             mSeekBar.setAlpha(1);
             mSeekBar.setVisibility(showSeekBar ? View.VISIBLE : View.GONE);
             final Drawable backgroundDrawable;
-            if (mController.isAdvancedLayoutSupported() && mController.isSubStatusSupported()) {
-                backgroundDrawable = mContext.getDrawable(
-                        showSeekBar || isFakeActive ? R.drawable.media_output_item_background_active
-                                : R.drawable.media_output_item_background).mutate();
-                backgroundDrawable.setTint(
-                        showSeekBar || isFakeActive ? mController.getColorConnectedItemBackground()
-                                : mController.getColorItemBackground());
-                mIconAreaLayout.setBackgroundTintList(
-                        ColorStateList.valueOf(showProgressBar || isFakeActive
-                                ? mController.getColorConnectedItemBackground()
-                                : showSeekBar ? mController.getColorSeekbarProgress()
-                                        : mController.getColorItemBackground()));
-                if (showSeekBar) {
-                    updateSeekbarProgressBackground();
-                }
-                //update end click area by isActive
-                mEndTouchArea.setVisibility(showEndTouchArea ? View.VISIBLE : View.GONE);
-                mEndClickIcon.setVisibility(showEndTouchArea ? View.VISIBLE : View.GONE);
-                ViewGroup.MarginLayoutParams params =
-                        (ViewGroup.MarginLayoutParams) mItemLayout.getLayoutParams();
-                params.rightMargin = showEndTouchArea ? mController.getItemMarginEndSelectable()
-                        : mController.getItemMarginEndDefault();
-            } else {
-                backgroundDrawable = mContext.getDrawable(
-                                R.drawable.media_output_item_background)
-                        .mutate();
-                backgroundDrawable.setTint(mController.getColorItemBackground());
+            backgroundDrawable = mContext.getDrawable(
+                    showSeekBar || isFakeActive ? R.drawable.media_output_item_background_active
+                            : R.drawable.media_output_item_background).mutate();
+            mItemLayout.setBackgroundTintList(ColorStateList.valueOf(
+                    showSeekBar || isFakeActive ? mController.getColorConnectedItemBackground()
+                            : mController.getColorItemBackground()
+            ));
+            mIconAreaLayout.setBackgroundTintList(
+                    ColorStateList.valueOf(showProgressBar || isFakeActive
+                            ? mController.getColorConnectedItemBackground()
+                            : showSeekBar ? mController.getColorSeekbarProgress()
+                                    : mController.getColorItemBackground()));
+            if (showSeekBar) {
+                updateSeekbarProgressBackground();
             }
+            //update end click area by isActive
+            mEndTouchArea.setVisibility(showEndTouchArea ? View.VISIBLE : View.GONE);
+            mEndClickIcon.setVisibility(showEndTouchArea ? View.VISIBLE : View.GONE);
+            ViewGroup.MarginLayoutParams params =
+                    (ViewGroup.MarginLayoutParams) mItemLayout.getLayoutParams();
+            params.rightMargin = showEndTouchArea ? mController.getItemMarginEndSelectable()
+                    : mController.getItemMarginEndDefault();
             mItemLayout.setBackground(backgroundDrawable);
             mProgressBar.setVisibility(showProgressBar ? View.VISIBLE : View.GONE);
             mSubTitleText.setVisibility(showSubtitle ? View.VISIBLE : View.GONE);
@@ -318,15 +297,11 @@
                             .findDrawableByLayerId(android.R.id.progress);
             final GradientDrawable progressDrawable =
                     (GradientDrawable) clipDrawable.getDrawable();
-            if (mController.isAdvancedLayoutSupported()) {
-                progressDrawable.setCornerRadii(
-                        new float[]{0, 0, mController.getActiveRadius(),
-                                mController.getActiveRadius(),
-                                mController.getActiveRadius(),
-                                mController.getActiveRadius(), 0, 0});
-            } else {
-                progressDrawable.setCornerRadius(mController.getActiveRadius());
-            }
+            progressDrawable.setCornerRadii(
+                    new float[]{0, 0, mController.getActiveRadius(),
+                            mController.getActiveRadius(),
+                            mController.getActiveRadius(),
+                            mController.getActiveRadius(), 0, 0});
         }
 
         void initSeekbar(MediaDevice device, boolean isCurrentSeekbarInvisible) {
@@ -337,19 +312,14 @@
             }
             mSeekBar.setMaxVolume(device.getMaxVolume());
             final int currentVolume = device.getCurrentVolume();
-            if (mSeekBar.getVolume() != currentVolume) {
-                if (isCurrentSeekbarInvisible && !mIsInitVolumeFirstTime) {
-                    if (mController.isAdvancedLayoutSupported()) {
+            if (!mIsDragging) {
+                if (mSeekBar.getVolume() != currentVolume) {
+                    if (isCurrentSeekbarInvisible && !mIsInitVolumeFirstTime) {
                         updateTitleIcon(currentVolume == 0 ? R.drawable.media_output_icon_volume_off
                                         : R.drawable.media_output_icon_volume,
                                 mController.getColorItemContent());
                     } else {
-                        animateCornerAndVolume(mSeekBar.getProgress(),
-                                MediaOutputSeekbar.scaleVolumeToProgress(currentVolume));
-                    }
-                } else {
-                    if (!mVolumeAnimator.isStarted()) {
-                        if (mController.isAdvancedLayoutSupported()) {
+                        if (!mVolumeAnimator.isStarted()) {
                             int percentage =
                                     (int) ((double) currentVolume * VOLUME_PERCENTAGE_SCALE_SIZE
                                             / (double) mSeekBar.getMax());
@@ -358,18 +328,19 @@
                             } else {
                                 updateUnmutedVolumeIcon();
                             }
+                            mSeekBar.setVolume(currentVolume);
                         }
-                        mSeekBar.setVolume(currentVolume);
                     }
+                } else if (currentVolume == 0) {
+                    mSeekBar.resetVolume();
+                    updateMutedVolumeIcon();
                 }
-            } else if (mController.isAdvancedLayoutSupported() && currentVolume == 0) {
-                mSeekBar.resetVolume();
-                updateMutedVolumeIcon();
             }
             if (mIsInitVolumeFirstTime) {
                 mIsInitVolumeFirstTime = false;
             }
             mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+                boolean mStartFromMute = false;
                 @Override
                 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                     if (device == null || !fromUser) {
@@ -377,48 +348,43 @@
                     }
                     int progressToVolume = MediaOutputSeekbar.scaleProgressToVolume(progress);
                     int deviceVolume = device.getCurrentVolume();
-                    if (mController.isAdvancedLayoutSupported()) {
-                        int percentage =
-                                (int) ((double) progressToVolume * VOLUME_PERCENTAGE_SCALE_SIZE
-                                        / (double) seekBar.getMax());
-                        mVolumeValueText.setText(mContext.getResources().getString(
-                                R.string.media_output_dialog_volume_percentage, percentage));
-                        mVolumeValueText.setVisibility(View.VISIBLE);
+                    int percentage =
+                            (int) ((double) progressToVolume * VOLUME_PERCENTAGE_SCALE_SIZE
+                                    / (double) seekBar.getMax());
+                    mVolumeValueText.setText(mContext.getResources().getString(
+                            R.string.media_output_dialog_volume_percentage, percentage));
+                    mVolumeValueText.setVisibility(View.VISIBLE);
+                    if (mStartFromMute) {
+                        updateUnmutedVolumeIcon();
+                        mStartFromMute = false;
                     }
                     if (progressToVolume != deviceVolume) {
                         mController.adjustVolume(device, progressToVolume);
-                        if (mController.isAdvancedLayoutSupported() && deviceVolume == 0) {
-                            updateUnmutedVolumeIcon();
-                        }
                     }
                 }
 
                 @Override
                 public void onStartTrackingTouch(SeekBar seekBar) {
-                    if (mController.isAdvancedLayoutSupported()) {
-                        mTitleIcon.setVisibility(View.INVISIBLE);
-                        mVolumeValueText.setVisibility(View.VISIBLE);
-                    }
+                    mTitleIcon.setVisibility(View.INVISIBLE);
+                    mVolumeValueText.setVisibility(View.VISIBLE);
+                    int currentVolume = MediaOutputSeekbar.scaleProgressToVolume(
+                            seekBar.getProgress());
+                    mStartFromMute = (currentVolume == 0);
                     mIsDragging = true;
                 }
 
                 @Override
                 public void onStopTrackingTouch(SeekBar seekBar) {
-                    if (mController.isAdvancedLayoutSupported()) {
-                        int currentVolume = MediaOutputSeekbar.scaleProgressToVolume(
-                                seekBar.getProgress());
-                        int percentage =
-                                (int) ((double) currentVolume * VOLUME_PERCENTAGE_SCALE_SIZE
-                                        / (double) seekBar.getMax());
-                        if (percentage == 0) {
-                            seekBar.setProgress(0);
-                            updateMutedVolumeIcon();
-                        } else {
-                            updateUnmutedVolumeIcon();
-                        }
-                        mTitleIcon.setVisibility(View.VISIBLE);
-                        mVolumeValueText.setVisibility(View.GONE);
+                    int currentVolume = MediaOutputSeekbar.scaleProgressToVolume(
+                            seekBar.getProgress());
+                    if (currentVolume == 0) {
+                        seekBar.setProgress(0);
+                        updateMutedVolumeIcon();
+                    } else {
+                        updateUnmutedVolumeIcon();
                     }
+                    mTitleIcon.setVisibility(View.VISIBLE);
+                    mVolumeValueText.setVisibility(View.GONE);
                     mController.logInteractionAdjustVolume(device);
                     mIsDragging = false;
                 }
@@ -443,23 +409,26 @@
         void updateTitleIcon(@DrawableRes int id, int color) {
             mTitleIcon.setImageDrawable(mContext.getDrawable(id));
             mTitleIcon.setImageTintList(ColorStateList.valueOf(color));
-            if (mController.isAdvancedLayoutSupported()) {
-                mIconAreaLayout.setBackgroundTintList(
-                        ColorStateList.valueOf(mController.getColorSeekbarProgress()));
-            }
+            mIconAreaLayout.setBackgroundTintList(
+                    ColorStateList.valueOf(mController.getColorSeekbarProgress()));
         }
 
         void updateIconAreaClickListener(View.OnClickListener listener) {
-            mTitleIcon.setOnClickListener(listener);
+            mIconAreaLayout.setOnClickListener(listener);
         }
 
         void initMutingExpectedDevice() {
             disableSeekBar();
+            updateTitleIcon(R.drawable.media_output_icon_volume,
+                    mController.getColorItemContent());
             final Drawable backgroundDrawable = mContext.getDrawable(
                                     R.drawable.media_output_item_background_active)
                             .mutate();
-            backgroundDrawable.setTint(mController.getColorConnectedItemBackground());
             mItemLayout.setBackground(backgroundDrawable);
+            mItemLayout.setBackgroundTintList(
+                    ColorStateList.valueOf(mController.getColorConnectedItemBackground()));
+            mIconAreaLayout.setBackgroundTintList(
+                    ColorStateList.valueOf(mController.getColorConnectedItemBackground()));
         }
 
         private void animateCornerAndVolume(int fromProgress, int toProgress) {
@@ -469,24 +438,18 @@
                     (ClipDrawable) ((LayerDrawable) mSeekBar.getProgressDrawable())
                             .findDrawableByLayerId(android.R.id.progress);
             final GradientDrawable targetBackgroundDrawable =
-                    (GradientDrawable) (mController.isAdvancedLayoutSupported()
-                            ? mIconAreaLayout.getBackground()
-                            : clipDrawable.getDrawable());
+                    (GradientDrawable) (mIconAreaLayout.getBackground());
             mCornerAnimator.addUpdateListener(animation -> {
                 float value = (float) animation.getAnimatedValue();
                 layoutBackgroundDrawable.setCornerRadius(value);
-                if (mController.isAdvancedLayoutSupported()) {
-                    if (toProgress == 0) {
-                        targetBackgroundDrawable.setCornerRadius(value);
-                    } else {
-                        targetBackgroundDrawable.setCornerRadii(new float[]{
-                                value,
-                                value,
-                                0, 0, 0, 0, value, value
-                        });
-                    }
-                } else {
+                if (toProgress == 0) {
                     targetBackgroundDrawable.setCornerRadius(value);
+                } else {
+                    targetBackgroundDrawable.setCornerRadii(new float[]{
+                            value,
+                            value,
+                            0, 0, 0, 0, value, value
+                    });
                 }
             });
             mVolumeAnimator.setIntValues(fromProgress, toProgress);
@@ -530,20 +493,10 @@
             });
         }
 
-        Drawable getSpeakerDrawable() {
-            final Drawable drawable = mContext.getDrawable(R.drawable.ic_speaker_group_black_24dp)
-                    .mutate();
-            drawable.setTint(Utils.getColorStateListDefaultColor(mContext,
-                    R.color.media_dialog_item_main_content));
-            return drawable;
-        }
-
         protected void disableSeekBar() {
             mSeekBar.setEnabled(false);
             mSeekBar.setOnTouchListener((v, event) -> true);
-            if (mController.isAdvancedLayoutSupported()) {
-                updateIconAreaClickListener(null);
-            }
+            updateIconAreaClickListener(null);
         }
 
         private void enableSeekBar(MediaDevice device) {
@@ -551,14 +504,15 @@
             mSeekBar.setOnTouchListener((v, event) -> false);
             updateIconAreaClickListener((v) -> {
                 if (device.getCurrentVolume() == 0) {
+                    mSeekBar.setVolume(UNMUTE_DEFAULT_VOLUME);
                     mController.adjustVolume(device, UNMUTE_DEFAULT_VOLUME);
                     updateUnmutedVolumeIcon();
-                    mTitleIcon.setOnTouchListener(((iconV, event) -> false));
+                    mIconAreaLayout.setOnTouchListener(((iconV, event) -> false));
                 } else {
                     mSeekBar.resetVolume();
                     mController.adjustVolume(device, 0);
                     updateMutedVolumeIcon();
-                    mTitleIcon.setOnTouchListener(((iconV, event) -> {
+                    mIconAreaLayout.setOnTouchListener(((iconV, event) -> {
                         mSeekBar.dispatchTouchEvent(event);
                         return false;
                     }));
@@ -574,7 +528,6 @@
                         return;
                     }
                     mTitleIcon.setImageIcon(icon);
-                    icon.setTint(mController.getColorItemContent());
                     mTitleIcon.setImageTintList(
                             ColorStateList.valueOf(mController.getColorItemContent()));
                 });
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index 770e4df..0a5b4b3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -101,6 +101,7 @@
     private Button mAppButton;
     private int mListMaxHeight;
     private int mItemHeight;
+    private int mListPaddingTop;
     private WallpaperColors mWallpaperColors;
     private boolean mShouldLaunchLeBroadcastDialog;
     private boolean mIsLeBroadcastCallbackRegistered;
@@ -111,7 +112,8 @@
 
     private final ViewTreeObserver.OnGlobalLayoutListener mDeviceListLayoutListener = () -> {
         ViewGroup.LayoutParams params = mDeviceListLayout.getLayoutParams();
-        int totalItemsHeight = mAdapter.getItemCount() * mItemHeight;
+        int totalItemsHeight = mAdapter.getItemCount() * mItemHeight
+                + mListPaddingTop;
         int correctHeight = Math.min(totalItemsHeight, mListMaxHeight);
         // Set max height for list
         if (correctHeight != params.height) {
@@ -220,6 +222,8 @@
                 R.dimen.media_output_dialog_list_max_height);
         mItemHeight = context.getResources().getDimensionPixelSize(
                 R.dimen.media_output_dialog_list_item_height);
+        mListPaddingTop = mContext.getResources().getDimensionPixelSize(
+                R.dimen.media_output_dialog_list_padding_top);
         mExecutor = Executors.newSingleThreadExecutor();
     }
 
@@ -266,10 +270,8 @@
             dismiss();
         });
         mAppButton.setOnClickListener(mMediaOutputController::tryToLaunchMediaApplication);
-        if (mMediaOutputController.isAdvancedLayoutSupported()) {
-            mMediaMetadataSectionLayout.setOnClickListener(
-                    mMediaOutputController::tryToLaunchMediaApplication);
-        }
+        mMediaMetadataSectionLayout.setOnClickListener(
+                mMediaOutputController::tryToLaunchMediaApplication);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt
index cdd00f9..a1e9995 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.media.nearby.NearbyMediaDevicesManager
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
 import java.util.Optional
 import javax.inject.Inject
@@ -49,7 +50,8 @@
     private val audioManager: AudioManager,
     private val powerExemptionManager: PowerExemptionManager,
     private val keyGuardManager: KeyguardManager,
-    private val featureFlags: FeatureFlags
+    private val featureFlags: FeatureFlags,
+    private val userTracker: UserTracker
 ) {
     var mediaOutputBroadcastDialog: MediaOutputBroadcastDialog? = null
 
@@ -61,7 +63,7 @@
         val controller = MediaOutputController(context, packageName,
                 mediaSessionManager, lbm, starter, notifCollection,
                 dialogLaunchAnimator, nearbyMediaDevicesManagerOptional, audioManager,
-                powerExemptionManager, keyGuardManager, featureFlags)
+                powerExemptionManager, keyGuardManager, featureFlags, userTracker)
         val dialog =
                 MediaOutputBroadcastDialog(context, aboveStatusBar, broadcastSender, controller)
         mediaOutputBroadcastDialog = dialog
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 822644b..cc75478 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -49,6 +49,7 @@
 import android.media.NearbyDevice;
 import android.media.RoutingSessionInfo;
 import android.media.session.MediaController;
+import android.media.session.MediaSession;
 import android.media.session.MediaSessionManager;
 import android.media.session.PlaybackState;
 import android.os.IBinder;
@@ -82,10 +83,10 @@
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
 import com.android.systemui.monet.ColorScheme;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
@@ -130,8 +131,6 @@
     private final Object mMediaDevicesLock = new Object();
     @VisibleForTesting
     final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>();
-    @VisibleForTesting
-    final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
     final List<MediaDevice> mCachedMediaDevices = new CopyOnWriteArrayList<>();
     private final List<MediaItem> mMediaItemList = new CopyOnWriteArrayList<>();
     private final AudioManager mAudioManager;
@@ -165,6 +164,7 @@
     private float mInactiveRadius;
     private float mActiveRadius;
     private FeatureFlags mFeatureFlags;
+    private UserTracker mUserTracker;
 
     public enum BroadcastNotifyDialog {
         ACTION_FIRST_LAUNCH,
@@ -181,7 +181,8 @@
             AudioManager audioManager,
             PowerExemptionManager powerExemptionManager,
             KeyguardManager keyGuardManager,
-            FeatureFlags featureFlags) {
+            FeatureFlags featureFlags,
+            UserTracker userTracker) {
         mContext = context;
         mPackageName = packageName;
         mMediaSessionManager = mediaSessionManager;
@@ -192,6 +193,7 @@
         mPowerExemptionManager = powerExemptionManager;
         mKeyGuardManager = keyGuardManager;
         mFeatureFlags = featureFlags;
+        mUserTracker = userTracker;
         InfoMediaManager imm = new InfoMediaManager(mContext, packageName, null, lbm);
         mLocalMediaManager = new LocalMediaManager(mContext, lbm, imm, packageName);
         mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
@@ -224,7 +226,6 @@
     void start(@NonNull Callback cb) {
         synchronized (mMediaDevicesLock) {
             mCachedMediaDevices.clear();
-            mMediaDevices.clear();
             mMediaItemList.clear();
         }
         mNearbyDeviceInfoMap.clear();
@@ -232,16 +233,13 @@
             mNearbyMediaDevicesManager.registerNearbyDevicesCallback(this);
         }
         if (!TextUtils.isEmpty(mPackageName)) {
-            for (MediaController controller : mMediaSessionManager.getActiveSessions(null)) {
-                if (TextUtils.equals(controller.getPackageName(), mPackageName)) {
-                    mMediaController = controller;
-                    mMediaController.unregisterCallback(mCb);
-                    if (mMediaController.getPlaybackState() != null) {
-                        mCurrentState = mMediaController.getPlaybackState().getState();
-                    }
-                    mMediaController.registerCallback(mCb);
-                    break;
+            mMediaController = getMediaController();
+            if (mMediaController != null) {
+                mMediaController.unregisterCallback(mCb);
+                if (mMediaController.getPlaybackState() != null) {
+                    mCurrentState = mMediaController.getPlaybackState().getState();
                 }
+                mMediaController.registerCallback(mCb);
             }
         }
         if (mMediaController == null) {
@@ -275,7 +273,6 @@
         mLocalMediaManager.stopScan();
         synchronized (mMediaDevicesLock) {
             mCachedMediaDevices.clear();
-            mMediaDevices.clear();
             mMediaItemList.clear();
         }
         if (mNearbyMediaDevicesManager != null) {
@@ -284,12 +281,31 @@
         mNearbyDeviceInfoMap.clear();
     }
 
+    private MediaController getMediaController() {
+        for (NotificationEntry entry : mNotifCollection.getAllNotifs()) {
+            final Notification notification = entry.getSbn().getNotification();
+            if (notification.isMediaNotification()
+                    && TextUtils.equals(entry.getSbn().getPackageName(), mPackageName)) {
+                MediaSession.Token token = notification.extras.getParcelable(
+                        Notification.EXTRA_MEDIA_SESSION,
+                        MediaSession.Token.class);
+                return new MediaController(mContext, token);
+            }
+        }
+        for (MediaController controller : mMediaSessionManager.getActiveSessionsForUser(null,
+                mUserTracker.getUserHandle())) {
+            if (TextUtils.equals(controller.getPackageName(), mPackageName)) {
+                return controller;
+            }
+        }
+        return null;
+    }
+
     @Override
     public void onDeviceListUpdate(List<MediaDevice> devices) {
-        boolean isListEmpty =
-                isAdvancedLayoutSupported() ? mMediaItemList.isEmpty() : mMediaDevices.isEmpty();
+        boolean isListEmpty = mMediaItemList.isEmpty();
         if (isListEmpty || !mIsRefreshing) {
-            buildMediaDevices(devices);
+            buildMediaItems(devices);
             mCallback.onDeviceListChanged();
         } else {
             synchronized (mMediaDevicesLock) {
@@ -304,11 +320,7 @@
     public void onSelectedDeviceStateChanged(MediaDevice device,
             @LocalMediaManager.MediaDeviceState int state) {
         mCallback.onRouteChanged();
-        if (isAdvancedLayoutSupported()) {
-            mMetricLogger.logOutputItemSuccess(device.toString(), new ArrayList<>(mMediaItemList));
-        } else {
-            mMetricLogger.logOutputSuccess(device.toString(), new ArrayList<>(mMediaDevices));
-        }
+        mMetricLogger.logOutputItemSuccess(device.toString(), new ArrayList<>(mMediaItemList));
     }
 
     @Override
@@ -319,11 +331,7 @@
     @Override
     public void onRequestFailed(int reason) {
         mCallback.onRouteChanged();
-        if (isAdvancedLayoutSupported()) {
-            mMetricLogger.logOutputItemFailure(new ArrayList<>(mMediaItemList), reason);
-        } else {
-            mMetricLogger.logOutputFailure(new ArrayList<>(mMediaDevices), reason);
-        }
+        mMetricLogger.logOutputItemFailure(new ArrayList<>(mMediaItemList), reason);
     }
 
     /**
@@ -342,7 +350,6 @@
         }
         try {
             synchronized (mMediaDevicesLock) {
-                mMediaDevices.removeIf(MediaDevice::isMutingExpectedDevice);
                 mMediaItemList.removeIf((MediaItem::isMutingExpectedDevice));
             }
             mAudioManager.cancelMuteAwaitConnection(mAudioManager.getMutingExpectedDevice());
@@ -547,7 +554,7 @@
 
     void refreshDataSetIfNeeded() {
         if (mNeedRefresh) {
-            buildMediaDevices(mCachedMediaDevices);
+            buildMediaItems(mCachedMediaDevices);
             mCallback.onDeviceListChanged();
             mNeedRefresh = false;
         }
@@ -597,75 +604,9 @@
         return mItemMarginEndSelectable;
     }
 
-    private void buildMediaDevices(List<MediaDevice> devices) {
-        if (isAdvancedLayoutSupported()) {
-            buildMediaItems(devices);
-        } else {
-            buildDefaultMediaDevices(devices);
-        }
-    }
-
-    private void buildDefaultMediaDevices(List<MediaDevice> devices) {
-        synchronized (mMediaDevicesLock) {
-            attachRangeInfo(devices);
-            Collections.sort(devices, Comparator.naturalOrder());
-            // For the first time building list, to make sure the top device is the connected
-            // device.
-            if (mMediaDevices.isEmpty()) {
-                boolean needToHandleMutingExpectedDevice =
-                        hasMutingExpectedDevice() && !isCurrentConnectedDeviceRemote();
-                final MediaDevice connectedMediaDevice =
-                        needToHandleMutingExpectedDevice ? null
-                                : getCurrentConnectedMediaDevice();
-                if (connectedMediaDevice == null) {
-                    if (DEBUG) {
-                        Log.d(TAG, "No connected media device or muting expected device exist.");
-                    }
-                    if (needToHandleMutingExpectedDevice) {
-                        for (MediaDevice device : devices) {
-                            if (device.isMutingExpectedDevice()) {
-                                mMediaDevices.add(0, device);
-                            } else {
-                                mMediaDevices.add(device);
-                            }
-                        }
-                    } else {
-                        mMediaDevices.addAll(devices);
-                    }
-                    return;
-                }
-                for (MediaDevice device : devices) {
-                    if (TextUtils.equals(device.getId(), connectedMediaDevice.getId())) {
-                        mMediaDevices.add(0, device);
-                    } else {
-                        mMediaDevices.add(device);
-                    }
-                }
-                return;
-            }
-            // To keep the same list order
-            final List<MediaDevice> targetMediaDevices = new ArrayList<>();
-            for (MediaDevice originalDevice : mMediaDevices) {
-                for (MediaDevice newDevice : devices) {
-                    if (TextUtils.equals(originalDevice.getId(), newDevice.getId())) {
-                        targetMediaDevices.add(newDevice);
-                        break;
-                    }
-                }
-            }
-            if (targetMediaDevices.size() != devices.size()) {
-                devices.removeAll(targetMediaDevices);
-                targetMediaDevices.addAll(devices);
-            }
-            mMediaDevices.clear();
-            mMediaDevices.addAll(targetMediaDevices);
-        }
-    }
-
     private void buildMediaItems(List<MediaDevice> devices) {
         synchronized (mMediaDevicesLock) {
-            if (!isRouteProcessSupported() || (isRouteProcessSupported()
-                    && !mLocalMediaManager.isPreferenceRouteListingExist())) {
+            if (!mLocalMediaManager.isPreferenceRouteListingExist()) {
                 attachRangeInfo(devices);
                 Collections.sort(devices, Comparator.naturalOrder());
             }
@@ -789,18 +730,6 @@
                 && (currentConnectedMediaDevice.isHostForOngoingSession());
     }
 
-    public boolean isAdvancedLayoutSupported() {
-        return mFeatureFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT);
-    }
-
-    public boolean isRouteProcessSupported() {
-        return mFeatureFlags.isEnabled(Flags.OUTPUT_SWITCHER_ROUTES_PROCESSING);
-    }
-
-    public boolean isSubStatusSupported() {
-        return mFeatureFlags.isEnabled(Flags.OUTPUT_SWITCHER_DEVICE_STATUS);
-    }
-
     List<MediaDevice> getGroupMediaDevices() {
         final List<MediaDevice> selectedDevices = getSelectedMediaDevice();
         final List<MediaDevice> selectableDevices = getSelectableMediaDevice();
@@ -845,10 +774,6 @@
         });
     }
 
-    Collection<MediaDevice> getMediaDevices() {
-        return mMediaDevices;
-    }
-
     public List<MediaItem> getMediaItemList() {
         return mMediaItemList;
     }
@@ -935,19 +860,11 @@
 
     boolean isAnyDeviceTransferring() {
         synchronized (mMediaDevicesLock) {
-            if (isAdvancedLayoutSupported()) {
-                for (MediaItem mediaItem : mMediaItemList) {
-                    if (mediaItem.getMediaDevice().isPresent()
-                            && mediaItem.getMediaDevice().get().getState()
-                            == LocalMediaManager.MediaDeviceState.STATE_CONNECTING) {
-                        return true;
-                    }
-                }
-            } else {
-                for (MediaDevice device : mMediaDevices) {
-                    if (device.getState() == LocalMediaManager.MediaDeviceState.STATE_CONNECTING) {
-                        return true;
-                    }
+            for (MediaItem mediaItem : mMediaItemList) {
+                if (mediaItem.getMediaDevice().isPresent()
+                        && mediaItem.getMediaDevice().get().getState()
+                        == LocalMediaManager.MediaDeviceState.STATE_CONNECTING) {
+                    return true;
                 }
             }
         }
@@ -1011,7 +928,8 @@
         MediaOutputController controller = new MediaOutputController(mContext, mPackageName,
                 mMediaSessionManager, mLocalBluetoothManager, mActivityStarter,
                 mNotifCollection, mDialogLaunchAnimator, Optional.of(mNearbyMediaDevicesManager),
-                mAudioManager, mPowerExemptionManager, mKeyGuardManager, mFeatureFlags);
+                mAudioManager, mPowerExemptionManager, mKeyGuardManager, mFeatureFlags,
+                mUserTracker);
         MediaOutputBroadcastDialog dialog = new MediaOutputBroadcastDialog(mContext, true,
                 broadcastSender, controller);
         dialog.show();
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
index 7dbf876..8024886 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
@@ -32,6 +32,7 @@
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
 import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.settings.UserTracker
 import java.util.Optional
 import javax.inject.Inject
 
@@ -51,7 +52,8 @@
     private val audioManager: AudioManager,
     private val powerExemptionManager: PowerExemptionManager,
     private val keyGuardManager: KeyguardManager,
-    private val featureFlags: FeatureFlags
+    private val featureFlags: FeatureFlags,
+    private val userTracker: UserTracker
 ) {
     companion object {
         private const val INTERACTION_JANK_TAG = "media_output"
@@ -67,7 +69,7 @@
             context, packageName,
             mediaSessionManager, lbm, starter, notifCollection,
             dialogLaunchAnimator, nearbyMediaDevicesManagerOptional, audioManager,
-            powerExemptionManager, keyGuardManager, featureFlags)
+            powerExemptionManager, keyGuardManager, featureFlags, userTracker)
         val dialog =
             MediaOutputDialog(context, aboveStatusBar, broadcastSender, controller, uiEventLogger)
         mediaOutputDialog = dialog
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
index 77ff036..bbd3d33 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
@@ -37,6 +37,7 @@
 import com.android.internal.widget.CachingIconView
 import com.android.systemui.R
 import com.android.app.animation.Interpolators
+import com.android.internal.logging.InstanceId
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.ui.binder.TintedIconViewBinder
 import com.android.systemui.dagger.SysUISingleton
@@ -49,6 +50,7 @@
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.temporarydisplay.TemporaryViewDisplayController
 import com.android.systemui.temporarydisplay.TemporaryViewInfo
+import com.android.systemui.temporarydisplay.TemporaryViewUiEventLogger
 import com.android.systemui.temporarydisplay.ViewPriority
 import com.android.systemui.util.animation.AnimationUtil.Companion.frames
 import com.android.systemui.util.concurrency.DelayableExecutor
@@ -82,6 +84,7 @@
         wakeLockBuilder: WakeLock.Builder,
         systemClock: SystemClock,
         private val rippleController: MediaTttReceiverRippleController,
+        private val temporaryViewUiEventLogger: TemporaryViewUiEventLogger,
 ) : TemporaryViewDisplayController<ChipReceiverInfo, MediaTttReceiverLogger>(
         context,
         logger,
@@ -94,6 +97,7 @@
         R.layout.media_ttt_chip_receiver,
         wakeLockBuilder,
         systemClock,
+        temporaryViewUiEventLogger,
 ) {
     @SuppressLint("WrongConstant") // We're allowed to use LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
     override val windowLayoutParams = commonWindowLayoutParams.apply {
@@ -125,6 +129,11 @@
         }
     }
 
+    // A map to store instance id per route info id.
+    private var instanceMap: MutableMap<String, InstanceId> = mutableMapOf()
+
+    private val displayListener = Listener { id, _ -> instanceMap.remove(id) }
+
     private fun updateMediaTapToTransferReceiverDisplay(
         @StatusBarManager.MediaTransferReceiverState displayState: Int,
         routeInfo: MediaRoute2Info,
@@ -139,12 +148,18 @@
             logger.logStateChangeError(displayState)
             return
         }
-        uiEventLogger.logReceiverStateChange(chipState)
+
+        val instanceId: InstanceId = instanceMap[routeInfo.id]
+                ?: temporaryViewUiEventLogger.getNewInstanceId()
+        uiEventLogger.logReceiverStateChange(chipState, instanceId)
 
         if (chipState != ChipStateReceiver.CLOSE_TO_SENDER) {
             removeView(routeInfo.id, removalReason = chipState.name)
             return
         }
+
+        // Save instance id to use for logging view events.
+        instanceMap[routeInfo.id] = instanceId
         if (appIcon == null) {
             displayView(
                 ChipReceiverInfo(
@@ -152,6 +167,7 @@
                     appIconDrawableOverride = null,
                     appName,
                     id = routeInfo.id,
+                    instanceId = instanceId,
                 )
             )
             return
@@ -166,6 +182,7 @@
                             drawable,
                             appName,
                             id = routeInfo.id,
+                            instanceId = instanceId,
                         )
                     )
                 },
@@ -180,6 +197,7 @@
         if (mediaTttFlags.isMediaTttEnabled()) {
             commandQueue.addCallback(commandQueueCallbacks)
         }
+        registerListener(displayListener)
     }
 
     override fun updateView(newInfo: ChipReceiverInfo, currentView: ViewGroup) {
@@ -342,4 +360,5 @@
     override val wakeReason: String = MediaTttUtils.WAKE_REASON_RECEIVER,
     override val id: String,
     override val priority: ViewPriority = ViewPriority.NORMAL,
+    override val instanceId: InstanceId,
 ) : TemporaryViewInfo()
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt
index 6e515f2..2294ce1 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLogger.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.media.taptotransfer.receiver
 
+import com.android.internal.logging.InstanceId
 import com.android.internal.logging.UiEvent
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.dagger.SysUISingleton
@@ -25,8 +26,8 @@
 @SysUISingleton
 class MediaTttReceiverUiEventLogger @Inject constructor(private val logger: UiEventLogger) {
     /** Logs that the receiver chip has changed states. */
-    fun logReceiverStateChange(chipState: ChipStateReceiver) {
-        logger.log(chipState.uiEvent)
+    fun logReceiverStateChange(chipState: ChipStateReceiver, instanceId: InstanceId) {
+        logger.log(chipState.uiEvent, instanceId)
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
index c7c72a9..f75f8b9 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
@@ -20,6 +20,7 @@
 import android.content.Context
 import android.media.MediaRoute2Info
 import android.view.View
+import com.android.internal.logging.InstanceId
 import com.android.internal.logging.UiEventLogger
 import com.android.internal.statusbar.IUndoMediaTransferCallback
 import com.android.systemui.CoreStartable
@@ -59,8 +60,8 @@
     // Since the media transfer display is similar to a heads-up notification, use the same timeout.
     private val defaultTimeout = context.resources.getInteger(R.integer.heads_up_notification_decay)
 
-    // A map to store current chip state per id.
-    private var stateMap: MutableMap<String, ChipStateSender> = mutableMapOf()
+    // A map to store instance id and current chip state per id.
+    private var stateMap: MutableMap<String, Pair<InstanceId, ChipStateSender>> = mutableMapOf()
 
     private val commandQueueCallbacks =
         object : CommandQueue.Callbacks {
@@ -98,7 +99,10 @@
             return
         }
 
-        val currentStateForId: ChipStateSender? = stateMap[routeInfo.id]
+        val currentStateForId: ChipStateSender? = stateMap[routeInfo.id]?.second
+        val instanceId: InstanceId =
+            stateMap[routeInfo.id]?.first
+                ?: chipbarCoordinator.tempViewUiEventLogger.getNewInstanceId()
         if (!ChipStateSender.isValidStateTransition(currentStateForId, chipState)) {
             // ChipStateSender.FAR_FROM_RECEIVER is the default state when there is no state.
             logger.logInvalidStateTransitionError(
@@ -107,7 +111,7 @@
             )
             return
         }
-        uiEventLogger.logSenderStateChange(chipState)
+        uiEventLogger.logSenderStateChange(chipState, instanceId)
 
         if (chipState == ChipStateSender.FAR_FROM_RECEIVER) {
             // Return early if we're not displaying a chip for this ID anyway
@@ -131,7 +135,7 @@
             removeIdFromStore(routeInfo.id, reason = removalReason)
             chipbarCoordinator.removeView(routeInfo.id, removalReason)
         } else {
-            stateMap[routeInfo.id] = chipState
+            stateMap[routeInfo.id] = Pair(instanceId, chipState)
             logger.logStateMap(stateMap)
             chipbarCoordinator.registerListener(displayListener)
             chipbarCoordinator.displayView(
@@ -141,6 +145,7 @@
                     undoCallback,
                     context,
                     logger,
+                    instanceId,
                 )
             )
         }
@@ -155,6 +160,7 @@
         undoCallback: IUndoMediaTransferCallback?,
         context: Context,
         logger: MediaTttSenderLogger,
+        instanceId: InstanceId,
     ): ChipbarInfo {
         val packageName = routeInfo.clientPackageName
         val otherDeviceName =
@@ -190,6 +196,7 @@
                                 chipStateSender.endItem.uiEventOnClick,
                                 chipStateSender.endItem.newState,
                                 routeInfo,
+                                instanceId,
                             )
                         } else {
                             null
@@ -203,6 +210,7 @@
             timeoutMs = timeout,
             id = routeInfo.id,
             priority = ViewPriority.NORMAL,
+            instanceId = instanceId,
         )
     }
 
@@ -217,10 +225,11 @@
         uiEvent: UiEventLogger.UiEventEnum,
         @StatusBarManager.MediaTransferSenderState newState: Int,
         routeInfo: MediaRoute2Info,
+        instanceId: InstanceId,
     ): ChipbarEndItem.Button {
         val onClickListener =
             View.OnClickListener {
-                uiEventLogger.logUndoClicked(uiEvent)
+                uiEventLogger.logUndoClicked(uiEvent, instanceId)
                 undoCallback.onUndoTriggered()
 
                 // The external service should eventually send us a new TransferTriggered state, but
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt
index 03bcfc8..206e5e3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.media.taptotransfer.sender
 
 import android.app.StatusBarManager
+import com.android.internal.logging.InstanceId
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogLevel
@@ -86,7 +87,7 @@
     }
 
     /** Logs the current contents of the state map. */
-    fun logStateMap(map: Map<String, ChipStateSender>) {
+    fun logStateMap(map: Map<String, Pair<InstanceId, ChipStateSender>>) {
         buffer.log(
             TAG,
             LogLevel.DEBUG,
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
index af3c1b6..56dbd7a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.media.taptotransfer.sender
 
 import android.util.Log
+import com.android.internal.logging.InstanceId
 import com.android.internal.logging.UiEvent
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.dagger.SysUISingleton
@@ -26,8 +27,8 @@
 @SysUISingleton
 class MediaTttSenderUiEventLogger @Inject constructor(private val logger: UiEventLogger) {
     /** Logs that the sender chip has changed states. */
-    fun logSenderStateChange(chipState: ChipStateSender) {
-        logger.log(chipState.uiEvent)
+    fun logSenderStateChange(chipState: ChipStateSender, instanceId: InstanceId) {
+        logger.log(chipState.uiEvent, instanceId)
     }
 
     /**
@@ -35,10 +36,11 @@
      *
      * @param undoUiEvent the uiEvent specific to which undo button was clicked.
      */
-    fun logUndoClicked(undoUiEvent: UiEventLogger.UiEventEnum) {
+    fun logUndoClicked(undoUiEvent: UiEventLogger.UiEventEnum, instanceId: InstanceId) {
         val isUndoEvent =
-            undoUiEvent == MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED
-                    || undoUiEvent ==
+            undoUiEvent ==
+                    MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED ||
+                    undoUiEvent ==
                     MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED
         if (!isUndoEvent) {
             Log.w(
@@ -47,7 +49,7 @@
             )
             return
         }
-        logger.log(undoUiEvent)
+        logger.log(undoUiEvent, instanceId)
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
index edab56e..77e2847 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -323,7 +323,6 @@
                         if (isFlungAwayFromEdge(endX = event.x) ||
                             previousXTranslation > params.staticTriggerThreshold
                         ) {
-                            updateArrowState(GestureState.ACTIVE)
                             updateArrowState(GestureState.FLUNG)
                         } else {
                             updateArrowState(GestureState.CANCELLED)
@@ -331,8 +330,11 @@
                     }
                     GestureState.INACTIVE -> {
                         if (isFlungAwayFromEdge(endX = event.x)) {
+                            // This is called outside of updateArrowState so that
+                            // BackAnimationController can immediately evaluate state
+                            // instead of after the flung delay
+                            backCallback.setTriggerBack(true)
                             mainHandler.postDelayed(MIN_DURATION_INACTIVE_BEFORE_FLUNG_ANIMATION) {
-                                updateArrowState(GestureState.ACTIVE)
                                 updateArrowState(GestureState.FLUNG)
                             }
                         } else {
@@ -605,7 +607,7 @@
         )
     }
 
-    private var previousPreThresholdWidthInterpolator = params.entryWidthTowardsEdgeInterpolator
+    private var previousPreThresholdWidthInterpolator = params.entryWidthInterpolator
     private fun preThresholdWidthStretchAmount(progress: Float): Float {
         val interpolator = run {
             val isPastSlop = totalTouchDeltaInactive > viewConfiguration.scaledTouchSlop
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 42de7f0..e524189 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -38,6 +38,7 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.hardware.input.InputManager;
+import android.icu.text.SimpleDateFormat;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -63,6 +64,8 @@
 import android.view.WindowManager;
 import android.window.BackEvent;
 
+import androidx.annotation.DimenRes;
+
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.policy.GestureNavigationSettingsObserver;
 import com.android.systemui.R;
@@ -97,7 +100,9 @@
 import java.io.PrintWriter;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.Executor;
@@ -225,7 +230,8 @@
     // The slop to distinguish between horizontal and vertical motion
     private float mTouchSlop;
     // The threshold for back swipe full progress.
-    private float mBackSwipeProgressThreshold;
+    private float mBackSwipeLinearThreshold;
+    private float mNonLinearFactor;
     // Duration after which we consider the event as longpress.
     private final int mLongPressTimeout;
     private int mStartingQuickstepRotation = -1;
@@ -278,6 +284,8 @@
     private LogArray mPredictionLog = new LogArray(MAX_NUM_LOGGED_PREDICTIONS);
     private LogArray mGestureLogInsideInsets = new LogArray(MAX_NUM_LOGGED_GESTURES);
     private LogArray mGestureLogOutsideInsets = new LogArray(MAX_NUM_LOGGED_GESTURES);
+    private SimpleDateFormat mLogDateFormat = new SimpleDateFormat("HH:mm:ss.SSS", Locale.US);
+    private Date mTmpLogDate = new Date();
 
     private final GestureNavigationSettingsObserver mGestureNavigationSettingsObserver;
 
@@ -471,11 +479,19 @@
         final float backGestureSlop = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_SYSTEMUI,
                         SystemUiDeviceConfigFlags.BACK_GESTURE_SLOP_MULTIPLIER, 0.75f);
         mTouchSlop = mViewConfiguration.getScaledTouchSlop() * backGestureSlop;
-        mBackSwipeProgressThreshold = res.getDimension(
+        mBackSwipeLinearThreshold = res.getDimension(
                 R.dimen.navigation_edge_action_progress_threshold);
+        mNonLinearFactor = getDimenFloat(res,
+                R.dimen.back_progress_non_linear_factor);
         updateBackAnimationThresholds();
     }
 
+    private float getDimenFloat(Resources res, @DimenRes int resId) {
+        TypedValue typedValue = new TypedValue();
+        res.getValue(resId, typedValue, true);
+        return typedValue.getFloat();
+    }
+
     public void updateNavigationBarOverlayExcludeRegion(Rect exclude) {
         mNavBarOverlayExcludedBounds.set(exclude);
     }
@@ -958,11 +974,17 @@
             }
 
             // For debugging purposes, only log edge points
+            long curTime = System.currentTimeMillis();
+            mTmpLogDate.setTime(curTime);
+            String curTimeStr = mLogDateFormat.format(mTmpLogDate);
             (isWithinInsets ? mGestureLogInsideInsets : mGestureLogOutsideInsets).log(String.format(
-                    "Gesture [%d,alw=%B,%B,%B,%B,%B,%B,disp=%s,wl=%d,il=%d,wr=%d,ir=%d,excl=%s]",
-                    System.currentTimeMillis(), isTrackpadMultiFingerSwipe, mAllowGesture,
+                    "Gesture [%d [%s],alw=%B, mltf=%B, left=%B, defLeft=%B, backAlw=%B, disbld=%B,"
+                            + " qsDisbld=%b, blkdAct=%B, pip=%B,"
+                            + " disp=%s, wl=%d, il=%d, wr=%d, ir=%d, excl=%s]",
+                    curTime, curTimeStr, mAllowGesture, isTrackpadMultiFingerSwipe,
                     mIsOnLeftEdge, mDeferSetIsOnLeftEdge, mIsBackGestureAllowed,
-                    QuickStepContract.isBackGestureDisabled(mSysUiFlags), mDisplaySize,
+                    QuickStepContract.isBackGestureDisabled(mSysUiFlags), mDisabledForQuickstep,
+                    mGestureBlockingActivityRunning, mIsInPip, mDisplaySize,
                     mEdgeWidthLeft, mLeftInset, mEdgeWidthRight, mRightInset, mExcludeRegion));
         } else if (mAllowGesture || mLogGesture) {
             if (!mThresholdCrossed) {
@@ -1116,8 +1138,9 @@
         if (mBackAnimation == null) {
             return;
         }
-        mBackAnimation.setSwipeThresholds(
-                Math.min(mDisplaySize.x, mBackSwipeProgressThreshold));
+        int maxDistance = mDisplaySize.x;
+        float linearDistance = Math.min(maxDistance, mBackSwipeLinearThreshold);
+        mBackAnimation.setSwipeThresholds(linearDistance, maxDistance, mNonLinearFactor);
     }
 
     private boolean sendEvent(int action, int code) {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
index 182ece7..9ddb78a 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
@@ -132,7 +132,7 @@
 
         entryWidthInterpolator = PathInterpolator(.19f, 1.27f, .71f, .86f)
         entryWidthTowardsEdgeInterpolator = PathInterpolator(1f, -3f, 1f, 1.2f)
-        activeWidthInterpolator = PathInterpolator(.56f, -0.39f, .18f, 1.46f)
+        activeWidthInterpolator = PathInterpolator(.7f, -0.24f, .48f, 1.21f)
         arrowAngleInterpolator = entryWidthInterpolator
         horizontalTranslationInterpolator = PathInterpolator(0.2f, 1.0f, 1.0f, 1.0f)
         verticalTranslationInterpolator = PathInterpolator(.5f, 1.15f, .41f, .94f)
@@ -147,8 +147,21 @@
         val flungCommittedWidthSpring = createSpring(10000f, 1f)
         val flungCommittedHeightSpring = createSpring(10000f, 1f)
 
-        val entryIndicatorAlphaThreshold = .23f
-        val entryIndicatorAlphaFactor = 1.05f
+        val commonArrowDimensAlphaThreshold = .165f
+        val commonArrowDimensAlphaFactor = 1.05f
+        val commonArrowDimensAlphaSpring = Step(
+            threshold = commonArrowDimensAlphaThreshold,
+            factor = commonArrowDimensAlphaFactor,
+            postThreshold = createSpring(180f, 0.9f),
+            preThreshold = createSpring(2000f, 0.6f)
+        )
+        val commonArrowDimensAlphaSpringInterpolator = Step(
+            threshold = commonArrowDimensAlphaThreshold,
+            factor = commonArrowDimensAlphaFactor,
+            postThreshold = 1f,
+            preThreshold = 0f
+        )
+
         entryIndicator = BackIndicatorDimens(
                 horizontalTranslation = getDimen(R.dimen.navigation_edge_entry_margin),
                 scale = getDimenFloat(R.dimen.navigation_edge_entry_scale),
@@ -162,18 +175,8 @@
                         alpha = 0f,
                         lengthSpring = createSpring(600f, 0.4f),
                         heightSpring = createSpring(600f, 0.4f),
-                        alphaSpring = Step(
-                                threshold = entryIndicatorAlphaThreshold,
-                                factor = entryIndicatorAlphaFactor,
-                                postThreshold = createSpring(200f, 1f),
-                                preThreshold = createSpring(2000f, 0.6f)
-                        ),
-                        alphaInterpolator = Step(
-                                threshold = entryIndicatorAlphaThreshold,
-                                factor = entryIndicatorAlphaFactor,
-                                postThreshold = 1f,
-                                preThreshold = 0f
-                        )
+                        alphaSpring = commonArrowDimensAlphaSpring,
+                        alphaInterpolator = commonArrowDimensAlphaSpringInterpolator
                 ),
                 backgroundDimens = BackgroundDimens(
                         alpha = 1f,
@@ -188,20 +191,6 @@
                 )
         )
 
-        val preThresholdAndActiveIndicatorAlphaThreshold = .355f
-        val preThresholdAndActiveIndicatorAlphaFactor = 1.05f
-        val preThresholdAndActiveAlphaSpring = Step(
-                threshold = preThresholdAndActiveIndicatorAlphaThreshold,
-                factor = preThresholdAndActiveIndicatorAlphaFactor,
-                postThreshold = createSpring(180f, 0.9f),
-                preThreshold = createSpring(2000f, 0.6f)
-        )
-        val preThresholdAndActiveAlphaSpringInterpolator = Step(
-                threshold = preThresholdAndActiveIndicatorAlphaThreshold,
-                factor = preThresholdAndActiveIndicatorAlphaFactor,
-                postThreshold = 1f,
-                preThreshold = 0f
-        )
         activeIndicator = BackIndicatorDimens(
                 horizontalTranslation = getDimen(R.dimen.navigation_edge_active_margin),
                 scale = getDimenFloat(R.dimen.navigation_edge_active_scale),
@@ -214,8 +203,8 @@
                         alpha = 1f,
                         lengthSpring = activeCommittedArrowLengthSpring,
                         heightSpring = activeCommittedArrowHeightSpring,
-                        alphaSpring = preThresholdAndActiveAlphaSpring,
-                        alphaInterpolator = preThresholdAndActiveAlphaSpringInterpolator
+                        alphaSpring = commonArrowDimensAlphaSpring,
+                        alphaInterpolator = commonArrowDimensAlphaSpringInterpolator
                 ),
                 backgroundDimens = BackgroundDimens(
                         alpha = 1f,
@@ -242,8 +231,8 @@
                         alpha = 1f,
                         lengthSpring = createSpring(100f, 0.6f),
                         heightSpring = createSpring(100f, 0.6f),
-                        alphaSpring = preThresholdAndActiveAlphaSpring,
-                        alphaInterpolator = preThresholdAndActiveAlphaSpringInterpolator
+                        alphaSpring = commonArrowDimensAlphaSpring,
+                        alphaInterpolator = commonArrowDimensAlphaSpringInterpolator
                 ),
                 backgroundDimens = BackgroundDimens(
                         alpha = 1f,
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index 9eb3d2d..25272ae 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -250,6 +250,11 @@
      * Widget Picker to all users.
      */
     fun setNoteTaskShortcutEnabled(value: Boolean, user: UserHandle) {
+        if (!userManager.isUserUnlocked(user)) {
+            debugLog { "setNoteTaskShortcutEnabled call but user locked: user=$user" }
+            return
+        }
+
         val componentName = ComponentName(context, CreateNoteTaskShortcutActivity::class.java)
 
         val enabledState =
@@ -305,6 +310,10 @@
     /** @see OnRoleHoldersChangedListener */
     fun onRoleHoldersChanged(roleName: String, user: UserHandle) {
         if (roleName != ROLE_NOTES) return
+        if (!userManager.isUserUnlocked(user)) {
+            debugLog { "onRoleHoldersChanged call but user locked: role=$roleName, user=$user" }
+            return
+        }
 
         if (user == userTracker.userHandle) {
             updateNoteTaskAsUser(user)
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt
index 7bb615b..221ff65 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt
@@ -18,8 +18,13 @@
 import android.app.role.RoleManager
 import android.os.UserHandle
 import android.view.KeyEvent
-import androidx.annotation.VisibleForTesting
+import android.view.KeyEvent.KEYCODE_N
+import android.view.KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.notetask.NoteTaskEntryPoint.KEYBOARD_SHORTCUT
+import com.android.systemui.notetask.NoteTaskEntryPoint.TAIL_BUTTON
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.CommandQueue
 import com.android.wm.shell.bubbles.Bubbles
@@ -35,35 +40,82 @@
     private val roleManager: RoleManager,
     private val commandQueue: CommandQueue,
     private val optionalBubbles: Optional<Bubbles>,
+    private val userTracker: UserTracker,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
     @Background private val backgroundExecutor: Executor,
     @NoteTaskEnabledKey private val isEnabled: Boolean,
-    private val userTracker: UserTracker,
 ) {
 
-    @VisibleForTesting
-    val callbacks =
-        object : CommandQueue.Callbacks {
-            override fun handleSystemKey(key: KeyEvent) {
-                if (key.keyCode == KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL) {
-                    controller.showNoteTask(NoteTaskEntryPoint.TAIL_BUTTON)
-                } else if (
-                    key.keyCode == KeyEvent.KEYCODE_N && key.isMetaPressed && key.isCtrlPressed
-                ) {
-                    controller.showNoteTask(NoteTaskEntryPoint.KEYBOARD_SHORTCUT)
-                }
-            }
-        }
-
+    /** Initializes note task related features and glue it with other parts of the SystemUI. */
     fun initialize() {
         // Guard against feature not being enabled or mandatory dependencies aren't available.
         if (!isEnabled || optionalBubbles.isEmpty) return
 
-        controller.setNoteTaskShortcutEnabled(true, userTracker.userHandle)
+        initializeHandleSystemKey()
+        initializeOnRoleHoldersChanged()
+        initializeOnUserUnlocked()
+    }
+
+    /**
+     * Initializes a callback for [CommandQueue] which will redirect [KeyEvent] from a Stylus to
+     * [NoteTaskController], ensure custom actions can be triggered (i.e., keyboard shortcut).
+     */
+    private fun initializeHandleSystemKey() {
+        val callbacks =
+            object : CommandQueue.Callbacks {
+                override fun handleSystemKey(key: KeyEvent) {
+                    key.toNoteTaskEntryPointOrNull()?.let(controller::showNoteTask)
+                }
+            }
         commandQueue.addCallback(callbacks)
+    }
+
+    /**
+     * Initializes the [RoleManager] role holder changed listener to ensure [NoteTaskController]
+     * will always update whenever the role holder app changes. Keep in mind that a role may change
+     * by direct user interaction (i.e., user goes to settings and change it) or by indirect
+     * interaction (i.e., the current role holder app is uninstalled).
+     */
+    private fun initializeOnRoleHoldersChanged() {
         roleManager.addOnRoleHoldersChangedListenerAsUser(
             backgroundExecutor,
             controller::onRoleHoldersChanged,
             UserHandle.ALL,
         )
     }
+
+    /**
+     * Initializes a [KeyguardUpdateMonitor] listener that will ensure [NoteTaskController] is in
+     * correct state during system initialization (after a direct boot user unlocked event).
+     *
+     * Once the system is unlocked, we will force trigger [NoteTaskController.onRoleHoldersChanged]
+     * with a hardcoded [RoleManager.ROLE_NOTES] for the current user.
+     */
+    private fun initializeOnUserUnlocked() {
+        if (keyguardUpdateMonitor.isUserUnlocked(userTracker.userId)) {
+            controller.setNoteTaskShortcutEnabled(true, userTracker.userHandle)
+        } else {
+            keyguardUpdateMonitor.registerCallback(onUserUnlockedCallback)
+        }
+    }
+
+    // KeyguardUpdateMonitor.registerCallback uses a weak reference, so we need a hard reference.
+    private val onUserUnlockedCallback =
+        object : KeyguardUpdateMonitorCallback() {
+            override fun onUserUnlocked() {
+                controller.setNoteTaskShortcutEnabled(true, userTracker.userHandle)
+                keyguardUpdateMonitor.removeCallback(this)
+            }
+        }
 }
+
+/**
+ * Maps a [KeyEvent] to a [NoteTaskEntryPoint]. If the [KeyEvent] does not represent a
+ * [NoteTaskEntryPoint], returns null.
+ */
+private fun KeyEvent.toNoteTaskEntryPointOrNull(): NoteTaskEntryPoint? =
+    when {
+        keyCode == KEYCODE_STYLUS_BUTTON_TAIL -> TAIL_BUTTON
+        keyCode == KEYCODE_N && isMetaPressed && isCtrlPressed -> KEYBOARD_SHORTCUT
+        else -> null
+    }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index b476521..b936c41 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -522,7 +522,7 @@
         return mExpanded;
     }
 
-    void addTile(QSPanelControllerBase.TileRecord tileRecord) {
+    final void addTile(QSPanelControllerBase.TileRecord tileRecord) {
         final QSTile.Callback callback = new QSTile.Callback() {
             @Override
             public void onStateChanged(QSTile.State state) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index fdab9b1..20f0352 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -199,7 +199,7 @@
         mMediaHost.removeVisibilityChangeListener(mMediaHostVisibilityListener);
 
         for (TileRecord record : mRecords) {
-            record.tile.removeCallbacks();
+            record.tile.removeCallback(record.callback);
         }
         mRecords.clear();
         mDumpManager.unregisterDumpable(mView.getDumpableTag());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 46724ad..d889979 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -24,6 +24,7 @@
 import android.widget.LinearLayout;
 
 import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.qs.QSTile.SignalState;
@@ -198,13 +199,23 @@
 
         @Override
         public boolean updateResources() {
-            mCellHeightResId = R.dimen.qs_quick_tile_size;
+            mResourceCellHeightResId = R.dimen.qs_quick_tile_size;
             boolean b = super.updateResources();
             mMaxAllowedRows = getResources().getInteger(R.integer.quick_qs_panel_max_rows);
             return b;
         }
 
         @Override
+        protected void estimateCellHeight() {
+            FontSizeUtils.updateFontSize(mTempTextView, R.dimen.qs_tile_text_size);
+            int unspecifiedSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+            mTempTextView.measure(unspecifiedSpec, unspecifiedSpec);
+            int padding = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_padding);
+            // the QQS only have 1 label
+            mEstimatedCellHeight = mTempTextView.getMeasuredHeight() + padding * 2;
+        }
+
+        @Override
         protected void onConfigurationChanged(Configuration newConfig) {
             super.onConfigurationChanged(newConfig);
             updateResources();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 269a158..19bf018 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -9,10 +9,12 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.TextView;
 
 import androidx.annotation.Nullable;
 
 import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSPanel.QSTileLayout;
 import com.android.systemui.qs.QSPanelControllerBase.TileRecord;
@@ -29,9 +31,10 @@
 
     protected int mColumns;
     protected int mCellWidth;
-    protected int mCellHeightResId = R.dimen.qs_tile_height;
+    protected int mResourceCellHeightResId = R.dimen.qs_tile_height;
+    protected int mResourceCellHeight;
+    protected int mEstimatedCellHeight;
     protected int mCellHeight;
-    protected int mMaxCellHeight;
     protected int mCellMarginHorizontal;
     protected int mCellMarginVertical;
     protected int mSidePadding;
@@ -49,6 +52,8 @@
     private float mSquishinessFraction = 1f;
     protected int mLastTileBottom;
 
+    protected TextView mTempTextView;
+
     public TileLayout(Context context) {
         this(context, null);
     }
@@ -57,6 +62,7 @@
         super(context, attrs);
         mLessRows = ((Settings.System.getInt(context.getContentResolver(), "qs_less_rows", 0) != 0)
                 || useQsMediaPlayer(context));
+        mTempTextView = new TextView(context);
         updateResources();
     }
 
@@ -120,14 +126,19 @@
     }
 
     public boolean updateResources() {
-        final Resources res = mContext.getResources();
+        Resources res = getResources();
         mResourceColumns = Math.max(1, res.getInteger(R.integer.quick_settings_num_columns));
-        mMaxCellHeight = mContext.getResources().getDimensionPixelSize(mCellHeightResId);
+        mResourceCellHeight = res.getDimensionPixelSize(mResourceCellHeightResId);
         mCellMarginHorizontal = res.getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal);
         mSidePadding = useSidePadding() ? mCellMarginHorizontal / 2 : 0;
         mCellMarginVertical= res.getDimensionPixelSize(R.dimen.qs_tile_margin_vertical);
         mMaxAllowedRows = Math.max(1, getResources().getInteger(R.integer.quick_settings_max_rows));
-        if (mLessRows) mMaxAllowedRows = Math.max(mMinRows, mMaxAllowedRows - 1);
+        if (mLessRows) {
+            mMaxAllowedRows = Math.max(mMinRows, mMaxAllowedRows - 1);
+        }
+        // update estimated cell height under current font scaling
+        mTempTextView.dispatchConfigurationChanged(mContext.getResources().getConfiguration());
+        estimateCellHeight();
         if (updateColumns()) {
             requestLayout();
             return true;
@@ -211,8 +222,23 @@
         return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
     }
 
+    // Estimate the height for the tile with 2 labels (general case) under current font scaling.
+    protected void estimateCellHeight() {
+        FontSizeUtils.updateFontSize(mTempTextView, R.dimen.qs_tile_text_size);
+        int unspecifiedSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+        mTempTextView.measure(unspecifiedSpec, unspecifiedSpec);
+        int padding = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_padding);
+        mEstimatedCellHeight = mTempTextView.getMeasuredHeight() * 2 + padding * 2;
+    }
+
     protected int getCellHeight() {
-        return mMaxCellHeight;
+        // Compare estimated height with resource height and return the larger one.
+        // If estimated height > resource height, it means the resource height is not enough
+        // for the tile content under current font scaling. Therefore, we need to use the estimated
+        // height to have a full tile content view.
+        // If estimated height <= resource height, we can use the resource height for tile to keep
+        // the same UI as original behavior.
+        return Math.max(mResourceCellHeight, mEstimatedCellHeight);
     }
 
     private void layoutTileRecords(int numRecords, boolean forLayout) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt
index 91c6e8b..c579f5c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt
@@ -318,7 +318,6 @@
             // We have a handful of different cases
             qsTile !is CustomTile -> {
                 // The tile is not a custom tile. Make sure they are reset to the correct user
-                qsTile.removeCallbacks()
                 if (userChanged) {
                     qsTile.userSwitch(user)
                     logger.logTileUserChanged(tileSpec, user)
@@ -327,7 +326,6 @@
             }
             qsTile.user == user -> {
                 // The tile is a custom tile for the same user, just return it
-                qsTile.removeCallbacks()
                 qsTile
             }
             else -> {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index f7e7366..abeb5af 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -153,14 +153,16 @@
     @VisibleForTesting
     /** Should be accessible only to the main thread. */
     final Map<Integer, TelephonyDisplayInfo> mSubIdTelephonyDisplayInfoMap = new HashMap<>();
+    @VisibleForTesting
+    /** Should be accessible only to the main thread. */
+    final Map<Integer, TelephonyManager> mSubIdTelephonyManagerMap = new HashMap<>();
+    @VisibleForTesting
+    /** Should be accessible only to the main thread. */
+    final Map<Integer, TelephonyCallback> mSubIdTelephonyCallbackMap = new HashMap<>();
 
     private WifiManager mWifiManager;
     private Context mContext;
     private SubscriptionManager mSubscriptionManager;
-    /** Should be accessible only to the main thread. */
-    private Map<Integer, TelephonyManager> mSubIdTelephonyManagerMap = new HashMap<>();
-    /** Should be accessible only to the main thread. */
-    private Map<Integer, TelephonyCallback> mSubIdTelephonyCallbackMap = new HashMap<>();
     private TelephonyManager mTelephonyManager;
     private ConnectivityManager mConnectivityManager;
     private CarrierConfigTracker mCarrierConfigTracker;
@@ -320,6 +322,9 @@
                 Log.e(TAG, "Unexpected null telephony call back for Sub " + tm.getSubscriptionId());
             }
         }
+        mSubIdTelephonyManagerMap.clear();
+        mSubIdTelephonyCallbackMap.clear();
+        mSubIdTelephonyDisplayInfoMap.clear();
         mSubscriptionManager.removeOnSubscriptionsChangedListener(
                 mOnSubscriptionsChangedListener);
         mAccessPointController.removeAccessPointCallback(this);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
index 6525a98..36dec1d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
@@ -16,7 +16,7 @@
 
 package com.android.systemui.qs.ui.viewmodel
 
-import com.android.systemui.keyguard.domain.interactor.LockScreenSceneInteractor
+import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
@@ -25,15 +25,15 @@
 class QuickSettingsSceneViewModel
 @AssistedInject
 constructor(
-    lockScreenSceneInteractorFactory: LockScreenSceneInteractor.Factory,
+    lockscreenSceneInteractorFactory: LockscreenSceneInteractor.Factory,
     @Assisted containerName: String,
 ) {
-    private val lockScreenSceneInteractor: LockScreenSceneInteractor =
-        lockScreenSceneInteractorFactory.create(containerName)
+    private val lockscreenSceneInteractor: LockscreenSceneInteractor =
+        lockscreenSceneInteractorFactory.create(containerName)
 
     /** Notifies that some content in quick settings was clicked. */
     fun onContentClicked() {
-        lockScreenSceneInteractor.dismissLockScreen()
+        lockscreenSceneInteractor.dismissLockscreen()
     }
 
     @AssistedFactory
diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
new file mode 100644
index 0000000..752471d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene
+
+import com.android.systemui.scene.data.model.SceneContainerConfigModule
+import com.android.systemui.scene.ui.composable.SceneModule
+import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModelModule
+import dagger.Module
+
+@Module(
+    includes =
+        [
+            SceneContainerConfigModule::class,
+            SceneContainerViewModelModule::class,
+            SceneModule::class,
+        ],
+)
+object SceneContainerFrameworkModule
diff --git a/packages/SystemUI/src/com/android/systemui/scene/data/model/SceneContainerConfigModule.kt b/packages/SystemUI/src/com/android/systemui/scene/data/model/SceneContainerConfigModule.kt
new file mode 100644
index 0000000..0af8094
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/data/model/SceneContainerConfigModule.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene.data.model
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.scene.shared.model.SceneContainerNames
+import com.android.systemui.scene.shared.model.SceneKey
+import dagger.Module
+import dagger.Provides
+import javax.inject.Named
+
+@Module
+object SceneContainerConfigModule {
+
+    @Provides
+    fun containerConfigs(): Map<String, SceneContainerConfig> {
+        return mapOf(
+            SceneContainerNames.SYSTEM_UI_DEFAULT to
+                SceneContainerConfig(
+                    name = SceneContainerNames.SYSTEM_UI_DEFAULT,
+                    // Note that this list is in z-order. The first one is the bottom-most and the
+                    // last
+                    // one is top-most.
+                    sceneKeys =
+                        listOf(
+                            SceneKey.Gone,
+                            SceneKey.Lockscreen,
+                            SceneKey.Bouncer,
+                            SceneKey.Shade,
+                            SceneKey.QuickSettings,
+                        ),
+                    initialSceneKey = SceneKey.Lockscreen,
+                ),
+        )
+    }
+
+    @Provides
+    @SysUISingleton
+    @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
+    fun provideDefaultSceneContainerConfig(
+        configs: Map<String, SceneContainerConfig>,
+    ): SceneContainerConfig {
+        return checkNotNull(configs[SceneContainerNames.SYSTEM_UI_DEFAULT]) {
+            "No SceneContainerConfig named \"${SceneContainerNames.SYSTEM_UI_DEFAULT}\"."
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
index 435ff4b..354de8a 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
@@ -59,7 +59,7 @@
      * The API is designed such that it's possible to emit ever-changing values for each
      * [UserAction] to enable, disable, or change the destination scene of a given user action.
      */
-    fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
+    fun destinationScenes(containerName: String): StateFlow<Map<UserAction, SceneModel>> =
         MutableStateFlow(emptyMap<UserAction, SceneModel>()).asStateFlow()
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerNames.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerNames.kt
new file mode 100644
index 0000000..64f5087
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerNames.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene.shared.model
+
+object SceneContainerNames {
+    const val SYSTEM_UI_DEFAULT = "system_ui"
+}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt
index 9ef439d..e7811e3 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt
@@ -32,8 +32,8 @@
      */
     object Gone : SceneKey("gone")
 
-    /** The lock screen is the scene that shows when the device is locked. */
-    object LockScreen : SceneKey("lockscreen")
+    /** The lockscreen is the scene that shows when the device is locked. */
+    object Lockscreen : SceneKey("lockscreen")
 
     /**
      * The shade is the scene whose primary purpose is to show a scrollable list of notifications.
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
index afc0531..8c1ad9b 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
@@ -19,17 +19,12 @@
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
-import dagger.assisted.Assisted
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
 import kotlinx.coroutines.flow.StateFlow
 
 /** Models UI state for a single scene container. */
-class SceneContainerViewModel
-@AssistedInject
-constructor(
+class SceneContainerViewModel(
     private val interactor: SceneInteractor,
-    @Assisted private val containerName: String,
+    val containerName: String,
 ) {
     /**
      * Keys of all scenes in the container.
@@ -54,11 +49,4 @@
     fun setSceneTransitionProgress(progress: Float) {
         interactor.setSceneTransitionProgress(containerName, progress)
     }
-
-    @AssistedFactory
-    interface Factory {
-        fun create(
-            containerName: String,
-        ): SceneContainerViewModel
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelModule.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelModule.kt
new file mode 100644
index 0000000..100f427
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelModule.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.SceneContainerNames
+import dagger.Module
+import dagger.Provides
+import javax.inject.Named
+
+@Module
+object SceneContainerViewModelModule {
+
+    @Provides
+    @SysUISingleton
+    @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
+    fun defaultSceneContainerViewModel(
+        interactor: SceneInteractor,
+    ): SceneContainerViewModel {
+        return SceneContainerViewModel(
+            interactor = interactor,
+            containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index 84f358c..e1ac0fd 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -453,9 +453,9 @@
                 postGroupNotification(currentUser);
                 mNotificationManager.notifyAsUser(null, mNotificationId,  notification,
                         currentUser);
-            } catch (IOException e) {
+            } catch (IOException | IllegalStateException e) {
                 Log.e(TAG, "Error saving screen recording: " + e.getMessage());
-                showErrorToast(R.string.screenrecord_delete_error);
+                showErrorToast(R.string.screenrecord_save_error);
                 mNotificationManager.cancelAsUser(null, mNotificationId, currentUser);
             }
         });
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
index b8d96f7..b80a01212 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
@@ -52,8 +52,9 @@
 import android.view.WindowManager;
 
 import com.android.systemui.media.MediaProjectionCaptureTarget;
-import java.io.File;
+
 import java.io.Closeable;
+import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.file.Files;
@@ -321,7 +322,7 @@
     /**
      * Store recorded video
      */
-    protected SavedRecording save() throws IOException {
+    protected SavedRecording save() throws IOException, IllegalStateException {
         String fileName = new SimpleDateFormat("'screen-'yyyyMMdd-HHmmss'.mp4'")
                 .format(new Date());
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordingMuxer.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordingMuxer.java
index 7ffcfd4..dc3310d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordingMuxer.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordingMuxer.java
@@ -52,9 +52,8 @@
     /**
      * RUN IN THE BACKGROUND THREAD!
      */
-    public void mux() throws IOException {
-        MediaMuxer muxer = null;
-        muxer = new MediaMuxer(mOutFile, mFormat);
+    public void mux() throws IOException, IllegalStateException {
+        MediaMuxer muxer = new MediaMuxer(mOutFile, mFormat);
         // Add extractors
         for (String file: mFiles) {
             MediaExtractor extractor = new MediaExtractor();
@@ -74,7 +73,10 @@
             }
         }
 
+        // This may throw IllegalStateException if no tracks were added above
+        // Let the error propagate up so we can notify the user.
         muxer.start();
+
         for (Pair<MediaExtractor, Integer> pair: mExtractorIndexToMuxerIndex.keySet()) {
             MediaExtractor extractor = pair.first;
             extractor.selectTrack(pair.second);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt
index 67e9a87..2e47ab6 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt
@@ -48,7 +48,9 @@
     }
 
     override suspend fun captureTask(taskId: Int): Bitmap? {
-        val snapshot = withContext(bgContext) { atmService.takeTaskSnapshot(taskId) } ?: return null
+        val snapshot = withContext(bgContext) {
+            atmService.takeTaskSnapshot(taskId, false /* updateCache */)
+        } ?: return null
         return Bitmap.wrapHardwareBuffer(snapshot.hardwareBuffer, snapshot.colorSpace)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java b/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java
index 8c01bae..5ad16f0 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java
@@ -293,10 +293,9 @@
             final ContentValues values = createMetadata(time, format, fileName);
 
             Uri baseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
-            if (UserHandle.myUserId() != owner.getIdentifier()) {
-                baseUri = ContentProvider.maybeAddUserId(baseUri, owner.getIdentifier());
-            }
-            Uri uri = resolver.insert(baseUri, values);
+            Uri uriWithUserId = ContentProvider.maybeAddUserId(baseUri, owner.getIdentifier());
+
+            Uri uri = resolver.insert(uriWithUserId, values);
             if (uri == null) {
                 throw new ImageExportException(RESOLVER_INSERT_RETURNED_NULL);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
index 7261324..2f96f6c 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
@@ -247,7 +247,7 @@
         }
 
         updateImageDimensions();
-        mViewModel.saveScreenshotThenFinish(drawable, bounds);
+        mViewModel.saveScreenshotThenFinish(drawable, bounds, getUser());
     }
 
     private void setResultThenFinish(Uri uri) {
@@ -255,6 +255,11 @@
             return;
         }
 
+        // Grant permission here instead of in the trampoline activity because this activity can run
+        // as work profile user so the URI can belong to the work profile user while the trampoline
+        // activity always runs as main user.
+        grantUriPermission(mCallingPackageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
         Bundle data = new Bundle();
         data.putInt(Intent.EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE,
                 Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.java
index e1619dc..afc8bff 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.java
@@ -19,7 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
-import android.view.Display;
+import android.os.UserManager;
 
 import androidx.annotation.Nullable;
 
@@ -27,6 +27,7 @@
 import com.android.internal.infra.ServiceConnector;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Application;
+import com.android.systemui.settings.DisplayTracker;
 
 import javax.inject.Inject;
 
@@ -35,14 +36,20 @@
 class AppClipsCrossProcessHelper {
 
     private final ServiceConnector<IAppClipsScreenshotHelperService> mProxyConnector;
+    private final DisplayTracker mDisplayTracker;
 
     @Inject
-    AppClipsCrossProcessHelper(@Application Context context) {
-        mProxyConnector = new ServiceConnector.Impl<IAppClipsScreenshotHelperService>(context,
+    AppClipsCrossProcessHelper(@Application Context context, UserManager userManager,
+            DisplayTracker displayTracker) {
+        // Start a service as main user so that even if the app clips activity is running as work
+        // profile user the service is able to use correct instance of Bubbles to grab a screenshot
+        // excluding the bubble layer.
+        mProxyConnector = new ServiceConnector.Impl<>(context,
                 new Intent(context, AppClipsScreenshotHelperService.class),
                 Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY
-                        | Context.BIND_NOT_VISIBLE, context.getUserId(),
+                        | Context.BIND_NOT_VISIBLE, userManager.getMainUser().getIdentifier(),
                 IAppClipsScreenshotHelperService.Stub::asInterface);
+        mDisplayTracker = displayTracker;
     }
 
     /**
@@ -56,7 +63,9 @@
         try {
             AndroidFuture<ScreenshotHardwareBufferInternal> future =
                     mProxyConnector.postForResult(
-                            service -> service.takeScreenshot(Display.DEFAULT_DISPLAY));
+                            service ->
+                                    // Take a screenshot of the default display of the user.
+                                    service.takeScreenshot(mDisplayTracker.getDefaultDisplayId()));
             return future.get().createBitmapThenCloseBuffer();
         } catch (Exception e) {
             return null;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
index 0487cbc..f00803c 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
@@ -21,7 +21,6 @@
 import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS;
 import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_WINDOW_MODE_UNSUPPORTED;
 import static android.content.Intent.EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE;
-import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
 
 import static com.android.systemui.flags.Flags.SCREENSHOT_APP_CLIPS;
 import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_TRIGGERED;
@@ -34,6 +33,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.ApplicationInfoFlags;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.net.Uri;
 import android.os.Bundle;
@@ -82,6 +82,8 @@
     private static final String TAG = AppClipsTrampolineActivity.class.getSimpleName();
     static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
     static final String EXTRA_SCREENSHOT_URI = TAG + "SCREENSHOT_URI";
+    @VisibleForTesting
+    static final String EXTRA_USE_WP_USER = TAG + "USE_WP_USER";
     static final String ACTION_FINISH_FROM_TRAMPOLINE = TAG + "FINISH_FROM_TRAMPOLINE";
     static final String EXTRA_RESULT_RECEIVER = TAG + "RESULT_RECEIVER";
     static final String EXTRA_CALLING_PACKAGE_NAME = TAG + "CALLING_PACKAGE_NAME";
@@ -98,6 +100,7 @@
     private final ResultReceiver mResultReceiver;
 
     private Intent mKillAppClipsBroadcastIntent;
+    private UserHandle mNotesAppUser;
 
     @Inject
     public AppClipsTrampolineActivity(DevicePolicyManager devicePolicyManager, FeatureFlags flags,
@@ -165,15 +168,21 @@
             return;
         }
 
+        mNotesAppUser = getUser();
+        if (getIntent().getBooleanExtra(EXTRA_USE_WP_USER, /* defaultValue= */ false)) {
+            // Get the work profile user internally instead of passing around via intent extras as
+            // this activity is exported apps could potentially mess around with intent extras.
+            mNotesAppUser = getWorkProfileUser().orElse(mNotesAppUser);
+        }
+
         String callingPackageName = getCallingPackage();
         Intent intent = new Intent().setComponent(componentName)
                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                 .putExtra(EXTRA_RESULT_RECEIVER, mResultReceiver)
                 .putExtra(EXTRA_CALLING_PACKAGE_NAME, callingPackageName);
-
         try {
-            // Start the App Clips activity.
-            startActivity(intent);
+            // Start the App Clips activity for the user corresponding to the notes app user.
+            startActivityAsUser(intent, mNotesAppUser);
 
             // Set up the broadcast intent that will inform the above App Clips activity to finish
             // when this trampoline activity is finished.
@@ -198,6 +207,13 @@
         }
     }
 
+    private Optional<UserHandle> getWorkProfileUser() {
+        return mUserTracker.getUserProfiles().stream()
+                .filter(profile -> mUserManager.isManagedProfile(profile.id))
+                .findFirst()
+                .map(UserInfo::getUserHandle);
+    }
+
     private void maybeStartActivityForWPUser() {
         UserHandle mainUser = mUserManager.getMainUser();
         if (mainUser == null) {
@@ -205,9 +221,13 @@
             return;
         }
 
-        // Start the activity as the main user with activity result forwarding.
+        // Start the activity as the main user with activity result forwarding. Set the intent extra
+        // so that the newly started trampoline activity starts the actual app clips activity as the
+        // work profile user. Starting the app clips activity as the work profile user is required
+        // to save the screenshot in work profile user storage and grant read permission to the URI.
         startActivityAsUser(
                 new Intent(this, AppClipsTrampolineActivity.class)
+                        .putExtra(EXTRA_USE_WP_USER, /* value= */ true)
                         .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT), mainUser);
     }
 
@@ -221,7 +241,7 @@
         int callingPackageUid = 0;
         try {
             callingPackageUid = mPackageManager.getApplicationInfoAsUser(callingPackageName,
-                    APPLICATION_INFO_FLAGS, mUserTracker.getUserId()).uid;
+                    APPLICATION_INFO_FLAGS, mNotesAppUser.getIdentifier()).uid;
         } catch (NameNotFoundException e) {
             Log.d(TAG, "Couldn't find notes app UID " + e);
         }
@@ -254,14 +274,14 @@
 
             if (statusCode == CAPTURE_CONTENT_FOR_NOTE_SUCCESS) {
                 Uri uri = resultData.getParcelable(EXTRA_SCREENSHOT_URI, Uri.class);
-                convertedData.setData(uri).addFlags(FLAG_GRANT_READ_URI_PERMISSION);
+                convertedData.setData(uri);
             }
 
             // Broadcast no longer required, setting it to null.
             mKillAppClipsBroadcastIntent = null;
 
             // Expand the note bubble before returning the result.
-            mNoteTaskController.showNoteTask(NoteTaskEntryPoint.APP_CLIPS);
+            mNoteTaskController.showNoteTaskAsUser(NoteTaskEntryPoint.APP_CLIPS, mNotesAppUser);
             setResult(RESULT_OK, convertedData);
             finish();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
index 4cbca28a..b0e4cc9 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
@@ -26,7 +26,7 @@
 import android.graphics.RenderNode;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
-import android.os.Process;
+import android.os.UserHandle;
 
 import androidx.annotation.NonNull;
 import androidx.lifecycle.LiveData;
@@ -110,16 +110,14 @@
      * Saves the provided {@link Drawable} to storage then informs the result {@link Uri} to
      * {@link LiveData}.
      */
-    void saveScreenshotThenFinish(Drawable screenshotDrawable, Rect bounds) {
+    void saveScreenshotThenFinish(Drawable screenshotDrawable, Rect bounds, UserHandle user) {
         mBgExecutor.execute(() -> {
             // Render the screenshot bitmap in background.
             Bitmap screenshotBitmap = renderBitmap(screenshotDrawable, bounds);
 
             // Export and save the screenshot in background.
-            // TODO(b/267310185): Save to work profile UserHandle.
             ListenableFuture<ImageExporter.Result> exportFuture = mImageExporter.export(
-                    mBgExecutor, UUID.randomUUID(), screenshotBitmap,
-                    Process.myUserHandle());
+                    mBgExecutor, UUID.randomUUID(), screenshotBitmap, user);
 
             // Get the result and update state on main thread.
             exportFuture.addListener(() -> {
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
index fbf134d..5fb3c01 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
@@ -166,21 +166,19 @@
             }
 
             override fun onUserSwitching(newUserId: Int, reply: IRemoteCallback?) {
-                backgroundHandler.run {
-                    handleUserSwitching(newUserId)
-                    reply?.sendResult(null)
-                }
+                handleUserSwitching(newUserId)
+                reply?.sendResult(null)
             }
 
             override fun onUserSwitchComplete(newUserId: Int) {
-                backgroundHandler.run {
-                    handleUserSwitchComplete(newUserId)
-                }
+                handleUserSwitchComplete(newUserId)
             }
         }, TAG)
     }
 
+    @WorkerThread
     protected open fun handleBeforeUserSwitching(newUserId: Int) {
+        Assert.isNotMainThread()
         setUserIdInternal(newUserId)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java b/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
index 2336673..9235fcc 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
@@ -84,7 +84,7 @@
                 Color.YELLOW, "calculatePanelHeightShade()");
         drawDebugInfo(canvas,
                 (int) mQsController.calculateNotificationsTopPadding(
-                        mNotificationPanelViewController.isExpanding(),
+                        mNotificationPanelViewController.isExpandingOrCollapsing(),
                         mNotificationPanelViewController.getKeyguardNotificationStaticPadding(),
                         mNotificationPanelViewController.getExpandedFraction()),
                 Color.MAGENTA, "calculateNotificationsTopPadding()");
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index af12bc2..784a360 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -233,7 +233,6 @@
 import javax.inject.Provider;
 
 import kotlin.Unit;
-
 import kotlinx.coroutines.CoroutineDispatcher;
 
 @CentralSurfacesComponent.CentralSurfacesScope
@@ -415,7 +414,11 @@
     private final KeyguardClockPositionAlgorithm.Result
             mClockPositionResult =
             new KeyguardClockPositionAlgorithm.Result();
-    private boolean mIsExpanding;
+    /**
+     * Indicates shade (or just QS) is expanding or collapsing but doesn't fully cover KEYGUARD
+     * state when shade can be expanded with swipe down or swipe down from the top to full QS.
+     */
+    private boolean mIsExpandingOrCollapsing;
 
     /**
      * Indicates drag starting height when swiping down or up on heads-up notifications.
@@ -1567,6 +1570,12 @@
             // When media is visible, it overlaps with the large clock. Use small clock instead.
             return SMALL;
         }
+        // To prevent the weather clock from overlapping with the notification shelf on AOD, we use
+        // the small clock here
+        if (mKeyguardStatusViewController.isLargeClockBlockingNotificationShelf()
+                && hasVisibleNotifications() && isOnAod()) {
+            return SMALL;
+        }
         return LARGE;
     }
 
@@ -1862,7 +1871,7 @@
 
     @Override
     public void expandToNotifications() {
-        if (mSplitShadeEnabled && (isShadeFullyExpanded() || isExpanding())) {
+        if (mSplitShadeEnabled && (isShadeFullyExpanded() || isExpandingOrCollapsing())) {
             return;
         }
         if (mQsController.getExpanded()) {
@@ -2109,6 +2118,9 @@
                     ? QUICK_SETTINGS : (
                     mKeyguardStateController.canDismissLockScreen() ? UNLOCK : BOUNCER_UNLOCK);
             if (!isFalseTouch(x, y, interactionType)) {
+                mShadeLog.logFlingExpands(vel, vectorVel, interactionType,
+                        this.mFlingAnimationUtils.getMinVelocityPxPerSecond(),
+                        mExpandedFraction > 0.5f, mAllowExpandForSmallExpansion);
                 if (Math.abs(vectorVel) < this.mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
                     expands = shouldExpandWhenNotFlinging();
                 } else {
@@ -2269,7 +2281,7 @@
 
     void requestScrollerTopPaddingUpdate(boolean animate) {
         mNotificationStackScrollLayoutController.updateTopPadding(
-                mQsController.calculateNotificationsTopPadding(mIsExpanding,
+                mQsController.calculateNotificationsTopPadding(mIsExpandingOrCollapsing,
                         getKeyguardNotificationStaticPadding(), mExpandedFraction), animate);
         if (isKeyguardShowing()
                 && mKeyguardBypassController.getBypassEnabled()) {
@@ -2322,7 +2334,7 @@
         }
         int maxHeight;
         if (mQsController.isExpandImmediate() || mQsController.getExpanded()
-                || mIsExpanding && mQsController.getExpandedWhenExpandingStarted()
+                || mIsExpandingOrCollapsing && mQsController.getExpandedWhenExpandingStarted()
                 || mPulsing || mSplitShadeEnabled) {
             maxHeight = mQsController.calculatePanelHeightExpanded(
                     mClockPositionResult.stackScrollerPadding);
@@ -2342,8 +2354,11 @@
         return maxHeight;
     }
 
-    public boolean isExpanding() {
-        return mIsExpanding;
+    @Override
+    public boolean isExpandingOrCollapsing() {
+        float lockscreenExpansionProgress = mQsController.getLockscreenShadeDragProgress();
+        return mIsExpandingOrCollapsing
+                || (0 < lockscreenExpansionProgress && lockscreenExpansionProgress < 1);
     }
 
     private void onHeightUpdated(float expandedHeight) {
@@ -2355,7 +2370,7 @@
                     mExpandedFraction, isExpanded(), mTracking, mExpansionDragDownAmountPx);
         }
         if (!mQsController.getExpanded() || mQsController.isExpandImmediate()
-                || mIsExpanding && mQsController.getExpandedWhenExpandingStarted()) {
+                || mIsExpandingOrCollapsing && mQsController.getExpandedWhenExpandingStarted()) {
             // Updating the clock position will set the top padding which might
             // trigger a new panel height and re-position the clock.
             // This is a circular dependency and should be avoided, otherwise we'll have
@@ -2493,7 +2508,7 @@
         mNotificationStackScrollLayoutController.onExpansionStopped();
         mHeadsUpManager.onExpandingFinished();
         mConversationNotificationManager.onNotificationPanelExpandStateChanged(isFullyCollapsed());
-        mIsExpanding = false;
+        mIsExpandingOrCollapsing = false;
         mMediaHierarchyManager.setCollapsingShadeFromQS(false);
         mMediaHierarchyManager.setQsExpanded(mQsController.getExpanded());
         if (isFullyCollapsed()) {
@@ -2908,6 +2923,10 @@
                 && mBarState == StatusBarState.SHADE;
     }
 
+    private boolean isPanelVisibleBecauseScrimIsAnimatingOff() {
+        return mUnlockedScreenOffAnimationController.isAnimationPlaying();
+    }
+
     @Override
     public boolean shouldHideStatusBarIconsWhenExpanded() {
         if (mIsLaunchAnimationRunning) {
@@ -3199,7 +3218,7 @@
         ipw.print("mDisplayTopInset="); ipw.println(mDisplayTopInset);
         ipw.print("mDisplayRightInset="); ipw.println(mDisplayRightInset);
         ipw.print("mDisplayLeftInset="); ipw.println(mDisplayLeftInset);
-        ipw.print("mIsExpanding="); ipw.println(mIsExpanding);
+        ipw.print("mIsExpandingOrCollapsing="); ipw.println(mIsExpandingOrCollapsing);
         ipw.print("mHeadsUpStartHeight="); ipw.println(mHeadsUpStartHeight);
         ipw.print("mListenForHeadsUp="); ipw.println(mListenForHeadsUp);
         ipw.print("mNavigationBarBottomHeight="); ipw.println(mNavigationBarBottomHeight);
@@ -3431,7 +3450,7 @@
     void notifyExpandingStarted() {
         if (!mExpanding) {
             mExpanding = true;
-            mIsExpanding = true;
+            mIsExpandingOrCollapsing = true;
             mQsController.onExpandingStarted(mQsController.getFullyExpanded());
         }
     }
@@ -3492,7 +3511,7 @@
      *                         gesture), we always play haptic.
      */
     private void maybeVibrateOnOpening(boolean openingWithTouch) {
-        if (mVibrateOnOpening) {
+        if (mVibrateOnOpening && mBarState != KEYGUARD && mBarState != SHADE_LOCKED) {
             if (!openingWithTouch || !mHasVibratedOnOpen) {
                 mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
                 mHasVibratedOnOpen = true;
@@ -3792,7 +3811,7 @@
         } else if (mBarState == SHADE_LOCKED) {
             return true;
         } else {
-            // case of two finger swipe from the top of keyguard
+            // case of swipe from the top of keyguard to expanded QS
             return mQsController.computeExpansionFraction() == 1;
         }
     }
@@ -3967,6 +3986,7 @@
                 || isPanelVisibleBecauseOfHeadsUp()
                 || mTracking
                 || mHeightAnimator != null
+                || isPanelVisibleBecauseScrimIsAnimatingOff()
                 && !mIsSpringBackAnimation;
     }
 
@@ -4044,7 +4064,7 @@
      * shade QS are always expanded
      */
     private void closeQsIfPossible() {
-        boolean openOrOpening = isShadeFullyExpanded() || isExpanding();
+        boolean openOrOpening = isShadeFullyExpanded() || isExpandingOrCollapsing();
         if (!(mSplitShadeEnabled && openOrOpening)) {
             mQsController.closeQs();
         }
@@ -4767,7 +4787,7 @@
 
             // If pulse is expanding already, let's give it the touch. There are situations
             // where the panel starts expanding even though we're also pulsing
-            boolean pulseShouldGetTouch = (!mIsExpanding
+            boolean pulseShouldGetTouch = (!mIsExpandingOrCollapsing
                     && !mQsController.shouldQuickSettingsIntercept(mDownX, mDownY, 0))
                     || mPulseExpansionHandler.isExpanding();
             if (pulseShouldGetTouch && mPulseExpansionHandler.onTouchEvent(event)) {
@@ -4933,7 +4953,7 @@
                         mShadeLog.logHasVibrated(mHasVibratedOnOpen, mExpandedFraction);
                     }
                     addMovement(event);
-                    if (!isFullyCollapsed() && !isOnKeyguard()) {
+                    if (!isFullyCollapsed()) {
                         maybeVibrateOnOpening(true /* openingWithTouch */);
                     }
                     float h = y - mInitialExpandY;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index cb3fa15..2f7644e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -397,19 +397,15 @@
                     return true;
                 }
 
-                if (handled) {
-                    return true;
-                }
-
                 if (mMultiShadeMotionEventInteractor != null) {
                     // This interactor is not null only if the dual shade feature is enabled.
                     return mMultiShadeMotionEventInteractor.onTouchEvent(ev, mView.getWidth());
                 } else if (mDragDownHelper.isDragDownEnabled()
                         || mDragDownHelper.isDraggingDown()) {
                     // we still want to finish our drag down gesture when locking the screen
-                    return mDragDownHelper.onTouchEvent(ev);
+                    return mDragDownHelper.onTouchEvent(ev) || handled;
                 } else {
-                    return false;
+                    return handled;
                 }
             }
 
@@ -480,7 +476,9 @@
         setDragDownHelper(mLockscreenShadeTransitionController.getTouchHelper());
 
         mDepthController.setRoot(mView);
-        mShadeExpansionStateManager.addExpansionListener(mDepthController);
+        ShadeExpansionChangeEvent currentState =
+                mShadeExpansionStateManager.addExpansionListener(mDepthController);
+        mDepthController.onPanelExpansionChanged(currentState);
     }
 
     public NotificationShadeWindowView getView() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
index 31b361f..81fe3ca 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
@@ -218,7 +218,7 @@
             containerPadding = 0
             stackScrollMargin = bottomStableInsets + notificationsBottomMargin
         }
-        val qsContainerPadding = if (!(isQSCustomizing || isQSDetailShowing)) {
+        val qsContainerPadding = if (!isQSDetailShowing) {
             // We also want this padding in the bottom in these cases
             if (splitShadeEnabled) {
                 stackScrollMargin - scrimShadeBottomMargin - footerActionsOffset
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
index abdd1a9..8672260 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
@@ -28,6 +28,7 @@
 import static com.android.systemui.shade.NotificationPanelViewController.QS_PARALLAX_AMOUNT;
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
 import static com.android.systemui.statusbar.StatusBarState.SHADE;
+import static com.android.systemui.util.DumpUtilsKt.asIndenting;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -37,6 +38,7 @@
 import android.graphics.Insets;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.util.IndentingPrintWriter;
 import android.util.Log;
 import android.util.MathUtils;
 import android.view.MotionEvent;
@@ -50,6 +52,8 @@
 import android.view.accessibility.AccessibilityManager;
 import android.widget.FrameLayout;
 
+import androidx.annotation.NonNull;
+
 import com.android.app.animation.Interpolators;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.jank.InteractionJankMonitor;
@@ -59,9 +63,11 @@
 import com.android.internal.policy.SystemBarUtils;
 import com.android.keyguard.FaceAuthApiRequestReason;
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.Dumpable;
 import com.android.systemui.R;
 import com.android.systemui.classifier.Classifier;
 import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor;
@@ -97,13 +103,15 @@
 
 import dagger.Lazy;
 
+import java.io.PrintWriter;
+
 import javax.inject.Inject;
 
 /** Handles QuickSettings touch handling, expansion and animation state
  * TODO (b/264460656) make this dumpable
  */
 @CentralSurfacesComponent.CentralSurfacesScope
-public class QuickSettingsController {
+public class QuickSettingsController implements Dumpable {
     public static final String TAG = "QuickSettingsController";
 
     private QS mQs;
@@ -328,6 +336,7 @@
             FeatureFlags featureFlags,
             InteractionJankMonitor interactionJankMonitor,
             ShadeLogger shadeLog,
+            DumpManager dumpManager,
             KeyguardFaceAuthInteractor keyguardFaceAuthInteractor,
             ShadeRepository shadeRepository,
             CastController castController
@@ -377,6 +386,7 @@
         mShadeRepository = shadeRepository;
 
         mLockscreenShadeTransitionController.addCallback(new LockscreenShadeTransitionCallback());
+        dumpManager.registerDumpable(this);
     }
 
     @VisibleForTesting
@@ -1903,6 +1913,7 @@
                 if (mSplitShadeEnabled) { // TODO:(b/269742565) remove below log
                     Log.wtfStack(TAG, "FLING_COLLAPSE called in split shade");
                 }
+                setExpandImmediate(false);
                 target = getMinExpansionHeight();
                 break;
             case FLING_HIDE:
@@ -2014,6 +2025,143 @@
                 (int) ((y - getInitialTouchY()) / displayDensity), (int) (vel / displayDensity));
     }
 
+    @Override
+    public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
+        pw.println(TAG + ":");
+        IndentingPrintWriter ipw = asIndenting(pw);
+        ipw.increaseIndent();
+        ipw.print("mIsFullWidth=");
+        ipw.println(mIsFullWidth);
+        ipw.print("mTouchSlop=");
+        ipw.println(mTouchSlop);
+        ipw.print("mSlopMultiplier=");
+        ipw.println(mSlopMultiplier);
+        ipw.print("mBarState=");
+        ipw.println(mBarState);
+        ipw.print("mStatusBarMinHeight=");
+        ipw.println(mStatusBarMinHeight);
+        ipw.print("mScrimEnabled=");
+        ipw.println(mScrimEnabled);
+        ipw.print("mScrimCornerRadius=");
+        ipw.println(mScrimCornerRadius);
+        ipw.print("mScreenCornerRadius=");
+        ipw.println(mScreenCornerRadius);
+        ipw.print("mUseLargeScreenShadeHeader=");
+        ipw.println(mUseLargeScreenShadeHeader);
+        ipw.print("mLargeScreenShadeHeaderHeight=");
+        ipw.println(mLargeScreenShadeHeaderHeight);
+        ipw.print("mDisplayRightInset=");
+        ipw.println(mDisplayRightInset);
+        ipw.print("mDisplayLeftInset=");
+        ipw.println(mDisplayLeftInset);
+        ipw.print("mSplitShadeEnabled=");
+        ipw.println(mSplitShadeEnabled);
+        ipw.print("mLockscreenNotificationPadding=");
+        ipw.println(mLockscreenNotificationPadding);
+        ipw.print("mSplitShadeNotificationsScrimMarginBottom=");
+        ipw.println(mSplitShadeNotificationsScrimMarginBottom);
+        ipw.print("mDozing=");
+        ipw.println(mDozing);
+        ipw.print("mEnableClipping=");
+        ipw.println(mEnableClipping);
+        ipw.print("mFalsingThreshold=");
+        ipw.println(mFalsingThreshold);
+        ipw.print("mTransitionToFullShadePosition=");
+        ipw.println(mTransitionToFullShadePosition);
+        ipw.print("mCollapsedOnDown=");
+        ipw.println(mCollapsedOnDown);
+        ipw.print("mShadeExpandedHeight=");
+        ipw.println(mShadeExpandedHeight);
+        ipw.print("mLastShadeFlingWasExpanding=");
+        ipw.println(mLastShadeFlingWasExpanding);
+        ipw.print("mInitialHeightOnTouch=");
+        ipw.println(mInitialHeightOnTouch);
+        ipw.print("mInitialTouchX=");
+        ipw.println(mInitialTouchX);
+        ipw.print("mInitialTouchY=");
+        ipw.println(mInitialTouchY);
+        ipw.print("mTouchAboveFalsingThreshold=");
+        ipw.println(mTouchAboveFalsingThreshold);
+        ipw.print("mTracking=");
+        ipw.println(mTracking);
+        ipw.print("mTrackingPointer=");
+        ipw.println(mTrackingPointer);
+        ipw.print("mExpanded=");
+        ipw.println(mExpanded);
+        ipw.print("mFullyExpanded=");
+        ipw.println(mFullyExpanded);
+        ipw.print("mExpandImmediate=");
+        ipw.println(mExpandImmediate);
+        ipw.print("mExpandedWhenExpandingStarted=");
+        ipw.println(mExpandedWhenExpandingStarted);
+        ipw.print("mAnimatingHiddenFromCollapsed=");
+        ipw.println(mAnimatingHiddenFromCollapsed);
+        ipw.print("mVisible=");
+        ipw.println(mVisible);
+        ipw.print("mExpansionHeight=");
+        ipw.println(mExpansionHeight);
+        ipw.print("mMinExpansionHeight=");
+        ipw.println(mMinExpansionHeight);
+        ipw.print("mMaxExpansionHeight=");
+        ipw.println(mMaxExpansionHeight);
+        ipw.print("mShadeExpandedFraction=");
+        ipw.println(mShadeExpandedFraction);
+        ipw.print("mPeekHeight=");
+        ipw.println(mPeekHeight);
+        ipw.print("mLastOverscroll=");
+        ipw.println(mLastOverscroll);
+        ipw.print("mExpansionFromOverscroll=");
+        ipw.println(mExpansionFromOverscroll);
+        ipw.print("mExpansionEnabledPolicy=");
+        ipw.println(mExpansionEnabledPolicy);
+        ipw.print("mExpansionEnabledAmbient=");
+        ipw.println(mExpansionEnabledAmbient);
+        ipw.print("mQuickQsHeaderHeight=");
+        ipw.println(mQuickQsHeaderHeight);
+        ipw.print("mTwoFingerExpandPossible=");
+        ipw.println(mTwoFingerExpandPossible);
+        ipw.print("mConflictingExpansionGesture=");
+        ipw.println(mConflictingExpansionGesture);
+        ipw.print("mAnimatorExpand=");
+        ipw.println(mAnimatorExpand);
+        ipw.print("mCachedGestureInsets=");
+        ipw.println(mCachedGestureInsets);
+        ipw.print("mTransitioningToFullShadeProgress=");
+        ipw.println(mTransitioningToFullShadeProgress);
+        ipw.print("mDistanceForFullShadeTransition=");
+        ipw.println(mDistanceForFullShadeTransition);
+        ipw.print("mStackScrollerOverscrolling=");
+        ipw.println(mStackScrollerOverscrolling);
+        ipw.print("mAnimating=");
+        ipw.println(mAnimating);
+        ipw.print("mIsTranslationResettingAnimator=");
+        ipw.println(mIsTranslationResettingAnimator);
+        ipw.print("mIsPulseExpansionResettingAnimator=");
+        ipw.println(mIsPulseExpansionResettingAnimator);
+        ipw.print("mTranslationForFullShadeTransition=");
+        ipw.println(mTranslationForFullShadeTransition);
+        ipw.print("mAnimateNextNotificationBounds=");
+        ipw.println(mAnimateNextNotificationBounds);
+        ipw.print("mNotificationBoundsAnimationDelay=");
+        ipw.println(mNotificationBoundsAnimationDelay);
+        ipw.print("mNotificationBoundsAnimationDuration=");
+        ipw.println(mNotificationBoundsAnimationDuration);
+        ipw.print("mLastClippingTopBound=");
+        ipw.println(mLastClippingTopBound);
+        ipw.print("mLastNotificationsTopPadding=");
+        ipw.println(mLastNotificationsTopPadding);
+        ipw.print("mLastNotificationsClippingTopBound=");
+        ipw.println(mLastNotificationsClippingTopBound);
+        ipw.print("mLastNotificationsClippingTopBoundNssl=");
+        ipw.println(mLastNotificationsClippingTopBoundNssl);
+        ipw.print("mInterceptRegion=");
+        ipw.println(mInterceptRegion);
+        ipw.print("mClippingAnimationEndBounds=");
+        ipw.println(mClippingAnimationEndBounds);
+        ipw.print("mLastClipBounds=");
+        ipw.println(mLastClipBounds);
+    }
+
     /** */
     public FragmentHostManager.FragmentListener getQsFragmentListener() {
         return new QsFragmentListener();
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
index e08bc33..d0a3cbb 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
@@ -78,6 +78,11 @@
     boolean isShadeFullyOpen();
 
     /**
+     * Returns whether shade or QS are currently opening or collapsing.
+     */
+    boolean isExpandingOrCollapsing();
+
+    /**
      * Add a runnable for NotificationPanelView to post when the panel is expanded.
      *
      * @param action the action to post
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
index c71467b..d00dab6 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
@@ -164,6 +164,11 @@
     }
 
     @Override
+    public boolean isExpandingOrCollapsing() {
+        return mNotificationPanelViewController.isExpandingOrCollapsing();
+    }
+
+    @Override
     public void postOnShadeExpanded(Runnable executable) {
         mNotificationPanelViewController.addOnGlobalLayoutListener(
                 new ViewTreeObserver.OnGlobalLayoutListener() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
index a048f54..2db47ae 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
@@ -49,23 +49,14 @@
     private var dragDownPxAmount: Float = 0f
 
     /**
-     * Adds a listener that will be notified when the panel expansion fraction has changed.
+     * Adds a listener that will be notified when the panel expansion fraction has changed and
+     * returns the current state in a ShadeExpansionChangeEvent for legacy purposes (b/23035507).
      *
-     * Listener will also be immediately notified with the current values.
-     */
-    fun addExpansionListener(listener: ShadeExpansionListener) {
-        addShadeExpansionListener(listener)
-        listener.onPanelExpansionChanged(
-            ShadeExpansionChangeEvent(fraction, expanded, tracking, dragDownPxAmount)
-        )
-    }
-
-    /**
-     * Adds a listener that will be notified when the panel expansion fraction has changed.
      * @see #addExpansionListener
      */
-    fun addShadeExpansionListener(listener: ShadeExpansionListener) {
+    fun addExpansionListener(listener: ShadeExpansionListener): ShadeExpansionChangeEvent {
         expansionListeners.add(listener)
+        return ShadeExpansionChangeEvent(fraction, expanded, tracking, dragDownPxAmount)
     }
 
     /** Removes an expansion listener. */
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
index 25073c1b..2b772e3 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
@@ -253,6 +253,31 @@
         )
     }
 
+    fun logFlingExpands(
+            vel: Float,
+            vectorVel: Float,
+            interactionType: Int,
+            minVelocityPxPerSecond: Float,
+            expansionOverHalf: Boolean,
+            allowExpandForSmallExpansion: Boolean
+    ) {
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                int1 = interactionType
+                long1 = vel.toLong()
+                long2 = vectorVel.toLong()
+                double1 = minVelocityPxPerSecond.toDouble()
+                bool1 = expansionOverHalf
+                bool2 = allowExpandForSmallExpansion
+            },
+            { "NPVC flingExpands called with vel: $long1, vectorVel: $long2, " +
+                    "interactionType: $int1, minVelocityPxPerSecond: $double1 " +
+                    "expansionOverHalf: $bool1, allowExpandForSmallExpansion: $bool2" }
+        )
+    }
+
     fun flingQs(flingType: Int, isClick: Boolean) {
         buffer.log(
             TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
index d5a9e95..f75047c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
@@ -48,7 +48,7 @@
     fun expandToNotifications()
 
     /** Returns whether the shade is expanding or collapsing itself or quick settings. */
-    val isExpanding: Boolean
+    val isExpandingOrCollapsing: Boolean
 
     /**
      * Returns whether the shade height is greater than zero (i.e. partially or fully expanded),
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 0ebcfa2..fc1e87a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
@@ -141,6 +141,7 @@
         mCarrierTextManager = carrierTextManagerBuilder
                 .setShowAirplaneMode(false)
                 .setShowMissingSim(false)
+                .setDebugLocationString("Shade")
                 .build();
         mCarrierConfigTracker = carrierConfigTracker;
         mSlotIndexResolver = slotIndexResolver;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
index 44c8e48..ebb9935 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
@@ -67,7 +67,8 @@
                         }
                     }
 
-                shadeExpansionStateManager.addExpansionListener(callback)
+                val currentState = shadeExpansionStateManager.addExpansionListener(callback)
+                callback.onPanelExpansionChanged(currentState)
                 trySendWithFailureLogging(ShadeModel(), TAG, "initial shade expansion info")
 
                 awaitClose { shadeExpansionStateManager.removeExpansionListener(callback) }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
index 41be526..ec16109 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
@@ -63,7 +63,9 @@
                     updateResources()
                 }
             })
-        shadeExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged)
+        val currentState =
+            shadeExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged)
+        onPanelExpansionChanged(currentState)
         shadeExpansionStateManager.addStateListener(this::onPanelStateChanged)
         dumpManager.registerCriticalDumpable("ShadeTransitionController") { printWriter, _ ->
             dump(printWriter)
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
index dcae258..8a96a47 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.shade.ui.viewmodel
 
 import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.keyguard.domain.interactor.LockScreenSceneInteractor
+import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
 import com.android.systemui.scene.shared.model.SceneKey
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
@@ -33,11 +33,11 @@
 @AssistedInject
 constructor(
     @Application private val applicationScope: CoroutineScope,
-    lockScreenSceneInteractorFactory: LockScreenSceneInteractor.Factory,
+    lockscreenSceneInteractorFactory: LockscreenSceneInteractor.Factory,
     @Assisted private val containerName: String,
 ) {
-    private val lockScreenInteractor: LockScreenSceneInteractor =
-        lockScreenSceneInteractorFactory.create(containerName)
+    private val lockScreenInteractor: LockscreenSceneInteractor =
+        lockscreenSceneInteractorFactory.create(containerName)
 
     /** The key of the scene we should switch to when swiping up. */
     val upDestinationSceneKey: StateFlow<SceneKey> =
@@ -54,13 +54,13 @@
 
     /** Notifies that some content in the shade was clicked. */
     fun onContentClicked() {
-        lockScreenInteractor.dismissLockScreen()
+        lockScreenInteractor.dismissLockscreen()
     }
 
     private fun upDestinationSceneKey(
         isLocked: Boolean,
     ): SceneKey {
-        return if (isLocked) SceneKey.LockScreen else SceneKey.Gone
+        return if (isLocked) SceneKey.Lockscreen else SceneKey.Gone
     }
 
     @AssistedFactory
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index fb4feb8..a532195 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -33,7 +33,6 @@
 import android.content.Context;
 import android.graphics.drawable.Icon;
 import android.hardware.biometrics.BiometricAuthenticator.Modality;
-import android.hardware.biometrics.BiometricManager.BiometricMultiSensorMode;
 import android.hardware.biometrics.IBiometricContextListener;
 import android.hardware.biometrics.IBiometricSysuiReceiver;
 import android.hardware.biometrics.PromptInfo;
@@ -317,7 +316,7 @@
                 IBiometricSysuiReceiver receiver,
                 int[] sensorIds, boolean credentialAllowed,
                 boolean requireConfirmation, int userId, long operationId, String opPackageName,
-                long requestId, @BiometricMultiSensorMode int multiSensorConfig) {
+                long requestId) {
         }
 
         /** @see IStatusBar#onBiometricAuthenticated(int) */
@@ -956,8 +955,7 @@
     @Override
     public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver,
             int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
-            int userId, long operationId, String opPackageName, long requestId,
-            @BiometricMultiSensorMode int multiSensorConfig) {
+            int userId, long operationId, String opPackageName, long requestId) {
         synchronized (mLock) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = promptInfo;
@@ -969,7 +967,6 @@
             args.arg6 = opPackageName;
             args.argl1 = operationId;
             args.argl2 = requestId;
-            args.argi2 = multiSensorConfig;
             mHandler.obtainMessage(MSG_BIOMETRIC_SHOW, args)
                     .sendToTarget();
         }
@@ -1573,8 +1570,7 @@
                                 someArgs.argi1 /* userId */,
                                 someArgs.argl1 /* operationId */,
                                 (String) someArgs.arg6 /* opPackageName */,
-                                someArgs.argl2 /* requestId */,
-                                someArgs.argi2 /* multiSensorConfig */);
+                                someArgs.argl2 /* requestId */);
                     }
                     someArgs.recycle();
                     break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 0ea2570..12420ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -186,7 +186,7 @@
     private boolean mPowerPluggedInDock;
 
     private boolean mPowerCharged;
-    private boolean mBatteryOverheated;
+    private boolean mBatteryDefender;
     private boolean mEnableBatteryDefender;
     private boolean mIncompatibleCharger;
     private int mChargingSpeed;
@@ -921,7 +921,7 @@
      */
     protected String computePowerIndication() {
         int chargingId;
-        if (mBatteryOverheated) {
+        if (mBatteryDefender) {
             chargingId = R.string.keyguard_plugged_in_charging_limited;
             String percentage = NumberFormat.getPercentInstance().format(mBatteryLevel / 100f);
             return mContext.getResources().getString(chargingId, percentage);
@@ -1093,9 +1093,9 @@
             mChargingSpeed = status.getChargingSpeed(mContext);
             mBatteryLevel = status.level;
             mBatteryPresent = status.present;
-            mBatteryOverheated = status.isOverheated();
+            mBatteryDefender = status.isBatteryDefender();
             // when the battery is overheated, device doesn't charge so only guard on pluggedIn:
-            mEnableBatteryDefender = mBatteryOverheated && status.isPluggedIn();
+            mEnableBatteryDefender = mBatteryDefender && status.isPluggedIn();
             mIncompatibleCharger = status.incompatibleCharger.orElse(false);
             try {
                 mChargingTimeRemaining = mPowerPluggedIn
@@ -1106,7 +1106,7 @@
             }
 
             mKeyguardLogger.logRefreshBatteryInfo(isChargingOrFull, mPowerPluggedIn, mBatteryLevel,
-                    mBatteryOverheated);
+                    mBatteryDefender);
             updateDeviceEntryIndication(!wasPluggedIn && mPowerPluggedInWired);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
index 43f78c3..e5849c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
@@ -87,7 +87,8 @@
     }
 }
 
-class PrivacyEvent(override val showAnimation: Boolean = true) : StatusEvent {
+/** open only for testing purposes. (See [FakeStatusEvent.kt]) */
+open class PrivacyEvent(override val showAnimation: Boolean = true) : StatusEvent {
     override var contentDescription: String? = null
     override val priority = 100
     override var forceVisible = true
@@ -107,9 +108,9 @@
     }
 
     override fun shouldUpdateFromEvent(other: StatusEvent?): Boolean {
-        return other is PrivacyEvent &&
-                (other.privacyItems != privacyItems ||
-                other.contentDescription != contentDescription)
+        return other is PrivacyEvent && (other.privacyItems != privacyItems ||
+                other.contentDescription != contentDescription ||
+                (other.forceVisible && !forceVisible))
     }
 
     override fun updateFromEvent(other: StatusEvent?) {
@@ -122,5 +123,7 @@
 
         privacyChip?.contentDescription = other.contentDescription
         privacyChip?.privacyList = other.privacyItems
+
+        if (other.forceVisible) forceVisible = true
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt
index f7a4fea..0a18f2d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt
@@ -153,6 +153,7 @@
                 )
             }
             currentlyDisplayedEvent?.updateFromEvent(event)
+            if (event.forceVisible) hasPersistentDot = true
         } else if (scheduledEvent.value?.shouldUpdateFromEvent(event) == true) {
             if (DEBUG) {
                 Log.d(
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 950dbd9..7cc917f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.lockscreen
 
 import android.app.PendingIntent
-import android.app.WallpaperManager
 import android.app.smartspace.SmartspaceConfig
 import android.app.smartspace.SmartspaceManager
 import android.app.smartspace.SmartspaceSession
@@ -56,7 +55,6 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.shared.regionsampling.RegionSampler
-import com.android.systemui.shared.regionsampling.UpdateColorCallback
 import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DATE_SMARTSPACE_DATA_PLUGIN
 import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.WEATHER_SMARTSPACE_DATA_PLUGIN
 import com.android.systemui.statusbar.phone.KeyguardBypassController
@@ -120,7 +118,7 @@
 
     private val regionSamplingEnabled =
             featureFlags.isEnabled(Flags.REGION_SAMPLING)
-    private var isContentUpdatedOnce = false
+    private var isRegionSamplersCreated = false
     private var showNotifications = false
     private var showSensitiveContentForCurrentUser = false
     private var showSensitiveContentForManagedUser = false
@@ -128,7 +126,6 @@
 
     // TODO(b/202758428): refactor so that we can test color updates via region samping, similar to
     //  how we test color updates when theme changes (See testThemeChangeUpdatesTextColor).
-    private val updateFun: UpdateColorCallback = { updateTextColorFromRegionSampler() }
 
     // TODO: Move logic into SmartspaceView
     var stateChangeListener = object : View.OnAttachStateChangeListener {
@@ -144,6 +141,9 @@
         override fun onViewDetachedFromWindow(v: View) {
             smartspaceViews.remove(v as SmartspaceView)
 
+            regionSamplers[v]?.stopRegionSampler()
+            regionSamplers.remove(v as SmartspaceView)
+
             if (smartspaceViews.isEmpty()) {
                 disconnect()
             }
@@ -170,7 +170,7 @@
 
         val filteredTargets = targets.filter(::filterSmartspaceTarget)
         plugin?.onTargetsAvailable(filteredTargets)
-        if (!isContentUpdatedOnce) {
+        if (!isRegionSamplersCreated) {
             for (v in smartspaceViews) {
                 if (regionSamplingEnabled) {
                     var regionSampler = RegionSampler(
@@ -178,15 +178,14 @@
                         uiExecutor,
                         bgExecutor,
                         regionSamplingEnabled,
-                        updateFun
-                    )
+                        isLockscreen = true,
+                    ) { updateTextColorFromRegionSampler() }
                     initializeTextColors(regionSampler)
                     regionSamplers[v] = regionSampler
                     regionSampler.startRegionSampler()
                 }
-                updateTextColorFromWallpaper()
             }
-            isContentUpdatedOnce = true
+            isRegionSamplersCreated = true
         }
     }
 
@@ -504,18 +503,16 @@
     }
 
     private fun updateTextColorFromRegionSampler() {
-        smartspaceViews.forEach {
-            val textColor = regionSamplers.get(it)?.currentForegroundColor()
+        regionSamplers.forEach { (view, region) ->
+            val textColor = region.currentForegroundColor()
             if (textColor != null) {
-                it.setPrimaryTextColor(textColor)
+                view.setPrimaryTextColor(textColor)
             }
         }
     }
 
     private fun updateTextColorFromWallpaper() {
-        val wallpaperManager = WallpaperManager.getInstance(context)
-        if (!regionSamplingEnabled || wallpaperManager.lockScreenWallpaperExists() ||
-            regionSamplers.isEmpty()) {
+        if (!regionSamplingEnabled || regionSamplers.isEmpty()) {
             val wallpaperTextColor =
                     Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColor)
             smartspaceViews.forEach { it.setPrimaryTextColor(wallpaperTextColor) }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
index 18ee481..59fc387 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
@@ -67,7 +67,10 @@
     fun getViewLabel(view: View): String =
             nodes.values.firstOrNull { node -> node.view === view }?.label ?: view.toString()
 
-    private fun detachChildren(parentNode: ShadeNode, specMap: Map<NodeController, NodeSpec>) {
+    private fun detachChildren(
+        parentNode: ShadeNode,
+        specMap: Map<NodeController, NodeSpec>
+    ) = traceSection("detachChildren") {
         val views = nodes.values.associateBy { it.view }
         fun detachRecursively(parentNode: ShadeNode, specMap: Map<NodeController, NodeSpec>) {
             val parentSpec = specMap[parentNode.controller]
@@ -124,7 +127,10 @@
         }
     }
 
-    private fun attachChildren(parentNode: ShadeNode, specMap: Map<NodeController, NodeSpec>) {
+    private fun attachChildren(
+        parentNode: ShadeNode,
+        specMap: Map<NodeController, NodeSpec>
+    ): Unit = traceSection("attachChildren") {
         val parentSpec = checkNotNull(specMap[parentNode.controller])
 
         for ((index, childSpec) in parentSpec.children.withIndex()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 8af488e..417d4ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -321,7 +321,8 @@
     protected void setBackgroundTintColor(int color) {
         if (color != mCurrentBackgroundTint) {
             mCurrentBackgroundTint = color;
-            if (color == mNormalColor) {
+            // TODO(282173943): re-enable this tinting optimization when Resources are thread-safe
+            if (false && color == mNormalColor) {
                 // We don't need to tint a normal notification
                 color = 0;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
index 6bbeebf..0989df6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
@@ -16,11 +16,15 @@
 
 package com.android.systemui.statusbar.notification.row;
 
+import static android.graphics.PorterDuff.Mode.SRC_ATOP;
+
 import android.annotation.ColorInt;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.ColorFilter;
+import android.graphics.PorterDuffColorFilter;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.IndentingPrintWriter;
@@ -157,10 +161,20 @@
      */
     public void updateColors() {
         Resources.Theme theme = mContext.getTheme();
-        int textColor = getResources().getColor(R.color.notif_pill_text, theme);
-        mClearAllButton.setBackground(theme.getDrawable(R.drawable.notif_footer_btn_background));
+        final @ColorInt int textColor = getResources().getColor(R.color.notif_pill_text, theme);
+        final Drawable clearAllBg = theme.getDrawable(R.drawable.notif_footer_btn_background);
+        final Drawable manageBg = theme.getDrawable(R.drawable.notif_footer_btn_background);
+        // TODO(b/282173943): Remove redundant tinting once Resources are thread-safe
+        final @ColorInt int buttonBgColor =
+                Utils.getColorAttrDefaultColor(mContext, com.android.internal.R.attr.colorSurface);
+        final ColorFilter bgColorFilter = new PorterDuffColorFilter(buttonBgColor, SRC_ATOP);
+        if (buttonBgColor != 0) {
+            clearAllBg.setColorFilter(bgColorFilter);
+            manageBg.setColorFilter(bgColorFilter);
+        }
+        mClearAllButton.setBackground(clearAllBg);
         mClearAllButton.setTextColor(textColor);
-        mManageButton.setBackground(theme.getDrawable(R.drawable.notif_footer_btn_background));
+        mManageButton.setBackground(manageBg);
         mManageButton.setTextColor(textColor);
         final @ColorInt int labelTextColor =
                 Utils.getColorAttrDefaultColor(mContext, android.R.attr.textColorPrimary);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index ae7c216..b0f3f59 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -93,6 +93,12 @@
     private boolean mAppearing;
     private float mPulseHeight = MAX_PULSE_HEIGHT;
 
+    /**
+     * The ExpandableNotificationRow that is pulsing, or the one that was pulsing
+     * when the device started to transition from AOD to LockScreen.
+     */
+    private ExpandableNotificationRow mPulsingRow;
+
     /** Fraction of lockscreen to shade animation (on lockscreen swipe down). */
     private float mFractionToShade;
 
@@ -564,6 +570,19 @@
         return mPulsing && entry.isAlerting();
     }
 
+    public void setPulsingRow(ExpandableNotificationRow row) {
+        mPulsingRow = row;
+    }
+
+    /**
+     * @param row The row to check
+     * @return true if row is the pulsing row when the device started to transition from AOD to lock
+     * screen
+     */
+    public boolean isPulsingRow(ExpandableView row) {
+        return mPulsingRow == row;
+    }
+
     public boolean isPanelTracking() {
         return mPanelTracking;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
index 993c3801..b956207 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
@@ -354,7 +354,11 @@
 
     @Override
     protected void snapChild(final View animView, final float targetLeft, float velocity) {
-        superSnapChild(animView, targetLeft, velocity);
+        if (animView instanceof SwipeableView) {
+            // only perform the snapback animation on views that are swipeable inside the shade.
+            superSnapChild(animView, targetLeft, velocity);
+        }
+
         mCallback.onDragCancelled(animView);
         if (targetLeft == 0) {
             handleMenuCoveredOrDismissed();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 92d767a..6f1c378 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -548,7 +548,7 @@
         ExpandableViewState viewState = view.getViewState();
         viewState.location = ExpandableViewState.LOCATION_UNKNOWN;
 
-        final float expansionFraction = getExpansionFractionWithoutShelf(
+        float expansionFraction = getExpansionFractionWithoutShelf(
                 algorithmState, ambientState);
 
         // Add gap between sections.
@@ -619,6 +619,11 @@
                     updateViewWithShelf(view, viewState, shelfStart);
                 }
             }
+            // Avoid pulsing notification flicker during AOD to LS
+            // A pulsing notification is already expanded, no need to expand it again with animation
+            if (ambientState.isPulsingRow(view)) {
+                expansionFraction = 1.0f;
+            }
             // Clip height of view right before shelf.
             viewState.height = (int) (getMaxAllowedChildHeight(view) * expansionFraction);
         }
@@ -700,9 +705,11 @@
                 && !(child instanceof FooterView);
     }
 
-    private void updatePulsingStates(StackScrollAlgorithmState algorithmState,
+    @VisibleForTesting
+    void updatePulsingStates(StackScrollAlgorithmState algorithmState,
                                      AmbientState ambientState) {
         int childCount = algorithmState.visibleChildren.size();
+        ExpandableNotificationRow pulsingRow = null;
         for (int i = 0; i < childCount; i++) {
             View child = algorithmState.visibleChildren.get(i);
             if (!(child instanceof ExpandableNotificationRow)) {
@@ -714,6 +721,19 @@
             }
             ExpandableViewState viewState = row.getViewState();
             viewState.hidden = false;
+            pulsingRow = row;
+        }
+
+        // Set AmbientState#pulsingRow to the current pulsing row when on AOD.
+        // Set AmbientState#pulsingRow=null when on lockscreen, since AmbientState#pulsingRow
+        // is only used for skipping the unfurl animation for (the notification that was already
+        // showing at full height on AOD) during the AOD=>lockscreen transition, where
+        // dozeAmount=[1f, 0f). We also need to reset the pulsingRow once it is no longer used
+        // because it will interfere with future unfurling animations - for example, during the
+        // LS=>AOD animation, the pulsingRow may stay at full height when it should squish with the
+        // rest of the stack.
+        if (ambientState.getDozeAmount() == 0.0f || ambientState.getDozeAmount() == 1.0f) {
+            ambientState.setPulsingRow(pulsingRow);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
index bbb4f24..df1a47a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
@@ -306,6 +306,18 @@
         intent: Intent,
         onlyProvisioned: Boolean,
         dismissShade: Boolean,
+    ) {
+        activityStarterInternal.startActivityDismissingKeyguard(
+            intent = intent,
+            onlyProvisioned = onlyProvisioned,
+            dismissShade = dismissShade,
+        )
+    }
+
+    override fun startActivityDismissingKeyguard(
+        intent: Intent,
+        onlyProvisioned: Boolean,
+        dismissShade: Boolean,
         disallowEnterPictureInPictureWhileLaunching: Boolean,
         callback: ActivityStarter.Callback?,
         flags: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index 4e69069..86bf7cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -20,7 +20,6 @@
 
 import android.annotation.Nullable;
 import android.app.ActivityOptions;
-import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -32,6 +31,7 @@
 import android.view.RemoteAnimationAdapter;
 import android.view.View;
 import android.view.ViewGroup;
+import android.window.RemoteTransition;
 import android.window.SplashScreen;
 
 import androidx.annotation.NonNull;
@@ -43,15 +43,14 @@
 import com.android.keyguard.AuthKeyguardMessageArea;
 import com.android.systemui.Dumpable;
 import com.android.systemui.animation.ActivityLaunchAnimator;
-import com.android.systemui.animation.RemoteTransitionAdapter;
 import com.android.systemui.navigationbar.NavigationBarView;
-import com.android.systemui.plugins.ActivityStarter.Callback;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.qs.QSPanelController;
 import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.shade.NotificationShadeWindowViewController;
 import com.android.systemui.shade.ShadeViewController;
+import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
 import com.android.systemui.statusbar.LightRevealScrim;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -160,8 +159,9 @@
         if (animationAdapter != null) {
             if (ENABLE_SHELL_TRANSITIONS) {
                 options = ActivityOptions.makeRemoteTransition(
-                        RemoteTransitionAdapter.adaptRemoteAnimation(animationAdapter,
-                                "SysUILaunch"));
+                        new RemoteTransition(
+                                RemoteAnimationRunnerCompat.wrap(animationAdapter.getRunner()),
+                                animationAdapter.getCallingApplication(), "SysUILaunch"));
             } else {
                 options = ActivityOptions.makeRemoteAnimation(animationAdapter);
             }
@@ -233,35 +233,8 @@
 
     boolean isShadeDisabled();
 
-    /** Starts an activity. Please use ActivityStarter instead of using these methods directly. */
-    void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade,
-            int flags);
-
-    /** Starts an activity. Please use ActivityStarter instead of using these methods directly. */
-    void startActivity(Intent intent, boolean dismissShade);
-
-    /** Starts an activity. Please use ActivityStarter instead of using these methods directly. */
-    void startActivity(Intent intent, boolean dismissShade,
-            @Nullable ActivityLaunchAnimator.Controller animationController);
-
-    /** Starts an activity. Please use ActivityStarter instead of using these methods directly. */
-    void startActivity(Intent intent, boolean dismissShade,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            boolean showOverLockscreenWhenLocked);
-
-    /** Starts an activity. Please use ActivityStarter instead of using these methods directly. */
-    void startActivity(Intent intent, boolean dismissShade,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            boolean showOverLockscreenWhenLocked, UserHandle userHandle);
-
     boolean isLaunchingActivityOverLockscreen();
 
-    /** Starts an activity. Please use ActivityStarter instead of using these methods directly. */
-    void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade);
-
-    /** Starts an activity. Please use ActivityStarter instead of using these methods directly. */
-    void startActivity(Intent intent, boolean dismissShade, Callback callback);
-
     boolean isWakeUpComingFromTouch();
 
     void onKeyguardViewManagerStatesUpdated();
@@ -322,122 +295,12 @@
 
     float getDisplayHeight();
 
-    /** Starts an activity intent that dismisses keyguard.
-     *
-     * Please use ActivityStarter instead of using these methods directly.
-     */
-    void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
-            boolean dismissShade, int flags);
-
-    /** Starts an activity intent that dismisses keyguard.
-     *
-     * Please use ActivityStarter instead of using these methods directly.
-     */
-    void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
-            boolean dismissShade);
-
-    /** Starts an activity intent that dismisses keyguard.
-     *
-     * Please use ActivityStarter instead of using these methods directly.
-     */
-    void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
-            boolean dismissShade, boolean disallowEnterPictureInPictureWhileLaunching,
-            Callback callback, int flags,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            UserHandle userHandle);
-
-    /** Starts an activity intent that dismisses keyguard.
-     *
-     * Please use ActivityStarter instead of using these methods directly.
-     */
-    void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
-            boolean dismissShade, boolean disallowEnterPictureInPictureWhileLaunching,
-            Callback callback, int flags,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            UserHandle userHandle, @Nullable String customMessage);
-
     void readyForKeyguardDone();
 
-    void executeRunnableDismissingKeyguard(Runnable runnable,
-            Runnable cancelAction,
-            boolean dismissShade,
-            boolean afterKeyguardGone,
-            boolean deferred);
-
-    void executeRunnableDismissingKeyguard(Runnable runnable,
-            Runnable cancelAction,
-            boolean dismissShade,
-            boolean afterKeyguardGone,
-            boolean deferred,
-            boolean willAnimateOnKeyguard,
-            @Nullable String customMessage);
-
     void resetUserExpandedStates();
 
-    /**
-     * Dismisses Keyguard and executes an action afterwards.
-     *
-     * Please use ActivityStarter instead of using these methods directly.
-     */
-    void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
-            boolean afterKeyguardGone);
-
-    /**
-     * Dismisses Keyguard and executes an action afterwards.
-     *
-     * Please use ActivityStarter instead of using these methods directly.
-     */
-    void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
-            boolean afterKeyguardGone, @Nullable String customMessage);
-
     void setLockscreenUser(int newUserId);
 
-    /**
-     * Starts a QS runnable on the main thread and dismisses keyguard.
-     *
-     * Please use ActivityStarter instead of using these methods directly.
-     */
-    void postQSRunnableDismissingKeyguard(Runnable runnable);
-
-    /**
-     * Starts an activity on the main thread with a delay.
-     *
-     * Please use ActivityStarter instead of using these methods directly.
-     */
-    void postStartActivityDismissingKeyguard(PendingIntent intent);
-
-    /**
-     * Starts an activity on the main thread with a delay.
-     *
-     * Please use ActivityStarter instead of using these methods directly.
-     */
-    void postStartActivityDismissingKeyguard(PendingIntent intent,
-            @Nullable ActivityLaunchAnimator.Controller animationController);
-
-    /**
-     * Starts an activity on the main thread with a delay.
-     *
-     * Please use ActivityStarter instead of using these methods directly.
-     */
-    void postStartActivityDismissingKeyguard(Intent intent, int delay);
-
-    /**
-     * Starts an activity on the main thread with a delay.
-     *
-     * Please use ActivityStarter instead of using these methods directly.
-     */
-    void postStartActivityDismissingKeyguard(Intent intent, int delay,
-            @Nullable ActivityLaunchAnimator.Controller animationController);
-
-    /**
-     * Starts an activity on the main thread with a delay.
-     *
-     * Please use ActivityStarter instead of using these methods directly.
-     */
-    void postStartActivityDismissingKeyguard(Intent intent, int delay,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            @Nullable String customMessage);
-
     void showKeyguard();
 
     boolean hideKeyguard();
@@ -531,18 +394,6 @@
 
     void awakenDreams();
 
-    void startPendingIntentDismissingKeyguard(PendingIntent intent);
-
-    void startPendingIntentDismissingKeyguard(
-            PendingIntent intent, @Nullable Runnable intentSentUiThreadCallback);
-
-    void startPendingIntentDismissingKeyguard(PendingIntent intent,
-            Runnable intentSentUiThreadCallback, View associatedView);
-
-    void startPendingIntentDismissingKeyguard(
-            PendingIntent intent, @Nullable Runnable intentSentUiThreadCallback,
-            @Nullable ActivityLaunchAnimator.Controller animationController);
-
     void clearNotificationEffects();
 
     boolean isBouncerShowing();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index 37e77766..0ccc819 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -339,7 +339,7 @@
                 mHeadsUpManager.unpinAll(true /* userUnpinned */);
                 mMetricsLogger.count("panel_open", 1);
             } else if (!mQsController.getExpanded()
-                    && !mShadeViewController.isExpanding()) {
+                    && !mShadeViewController.isExpandingOrCollapsing()) {
                 mQsController.flingQs(0 /* velocity */,
                         ShadeViewController.FLING_EXPAND);
                 mMetricsLogger.count("panel_open_qs", 1);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 263566e..0402d4f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -31,7 +31,6 @@
 
 import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
 import static com.android.systemui.charging.WirelessChargingAnimation.UNKNOWN_BATTERY_LEVEL;
-import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
 import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
 import static com.android.systemui.statusbar.StatusBarState.SHADE;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
@@ -43,8 +42,6 @@
 
 import android.annotation.Nullable;
 import android.app.ActivityManager;
-import android.app.ActivityOptions;
-import android.app.ActivityTaskManager;
 import android.app.IWallpaperManager;
 import android.app.KeyguardManager;
 import android.app.Notification;
@@ -52,7 +49,6 @@
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
 import android.app.TaskInfo;
-import android.app.TaskStackBuilder;
 import android.app.UiModeManager;
 import android.app.WallpaperInfo;
 import android.app.WallpaperManager;
@@ -138,7 +134,6 @@
 import com.android.systemui.R;
 import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
 import com.android.systemui.animation.ActivityLaunchAnimator;
-import com.android.systemui.animation.DelegateLaunchAnimatorController;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.biometrics.AuthRippleController;
 import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -168,7 +163,7 @@
 import com.android.systemui.navigationbar.NavigationBarController;
 import com.android.systemui.navigationbar.NavigationBarView;
 import com.android.systemui.notetask.NoteTaskController;
-import com.android.systemui.plugins.ActivityStarter.Callback;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.FalsingManager;
@@ -192,6 +187,7 @@
 import com.android.systemui.shade.QuickSettingsController;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.shade.ShadeExpansionChangeEvent;
+import com.android.systemui.shade.ShadeExpansionListener;
 import com.android.systemui.shade.ShadeExpansionStateManager;
 import com.android.systemui.shade.ShadeLogger;
 import com.android.systemui.shade.ShadeSurface;
@@ -542,6 +538,7 @@
     private final WallpaperManager mWallpaperManager;
     private final UserTracker mUserTracker;
     private final Provider<FingerprintManager> mFingerprintManager;
+    private final ActivityStarter mActivityStarter;
 
     private CentralSurfacesComponent mCentralSurfacesComponent;
 
@@ -819,7 +816,8 @@
             LightRevealScrim lightRevealScrim,
             AlternateBouncerInteractor alternateBouncerInteractor,
             UserTracker userTracker,
-            Provider<FingerprintManager> fingerprintManager
+            Provider<FingerprintManager> fingerprintManager,
+            ActivityStarter activityStarter
     ) {
         mContext = context;
         mNotificationsController = notificationsController;
@@ -906,6 +904,7 @@
         mAlternateBouncerInteractor = alternateBouncerInteractor;
         mUserTracker = userTracker;
         mFingerprintManager = fingerprintManager;
+        mActivityStarter = activityStarter;
 
         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
         mStartingSurfaceOptional = startingSurfaceOptional;
@@ -915,7 +914,11 @@
 
         mScreenOffAnimationController = screenOffAnimationController;
 
-        mShadeExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged);
+        ShadeExpansionListener shadeExpansionListener = this::onPanelExpansionChanged;
+        ShadeExpansionChangeEvent currentState =
+                mShadeExpansionStateManager.addExpansionListener(shadeExpansionListener);
+        shadeExpansionListener.onPanelExpansionChanged(currentState);
+
         mShadeExpansionStateManager.addFullExpansionListener(this::onShadeExpansionFullyChanged);
 
         mActivityIntentHelper = new ActivityIntentHelper(mContext);
@@ -1224,6 +1227,7 @@
         // By default turning off the screen also closes the shade.
         // We want to make sure that the shade status is kept after folding/unfolding.
         boolean isShadeOpen = mShadeController.isShadeFullyOpen();
+        boolean isShadeExpandingOrCollapsing = mShadeController.isExpandingOrCollapsing();
         boolean leaveOpen = isShadeOpen && !willGoToSleep && mState == SHADE;
         if (DEBUG) {
             Log.d(TAG, String.format(
@@ -1231,14 +1235,15 @@
                             + "isFolded=%s, "
                             + "willGoToSleep=%s, "
                             + "isShadeOpen=%s, "
+                            + "isShadeExpandingOrCollapsing=%s, "
                             + "leaveOpen=%s",
-                    isFolded, willGoToSleep, isShadeOpen, leaveOpen));
+                    isFolded, willGoToSleep, isShadeOpen, isShadeExpandingOrCollapsing, leaveOpen));
         }
         if (leaveOpen) {
             // below makes shade stay open when going from folded to unfolded
             mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
         }
-        if (mState != SHADE && isShadeOpen) {
+        if (mState != SHADE && (isShadeOpen || isShadeExpandingOrCollapsing)) {
             // When device state changes on KEYGUARD/SHADE_LOCKED we don't want to keep the state of
             // the shade and instead we open clean state of keyguard with shade closed.
             // Normally some parts of QS state (like expanded/collapsed) are persisted and
@@ -1266,7 +1271,9 @@
         if (!mFeatureFlags.isEnabled(Flags.NOTIFICATION_SHELF_REFACTOR)) {
             mNotificationIconAreaController.setupShelf(mNotificationShelfController);
         }
-        mShadeExpansionStateManager.addExpansionListener(mWakeUpCoordinator);
+        ShadeExpansionChangeEvent currentState =
+                mShadeExpansionStateManager.addExpansionListener(mWakeUpCoordinator);
+        mWakeUpCoordinator.onPanelExpansionChanged(currentState);
 
         // Allow plugins to reference DarkIconDispatcher and StatusBarStateController
         mPluginDependencyProvider.allowPluginDependency(DarkIconDispatcher.class);
@@ -1432,12 +1439,14 @@
                 message.write(SystemProperties.get("ro.serialno"));
                 message.write("\n");
 
-                startActivityDismissingKeyguard(Intent.createChooser(new Intent(Intent.ACTION_SEND)
-                                .setType("*/*")
-                                .putExtra(Intent.EXTRA_SUBJECT, "Rejected touch report")
-                                .putExtra(Intent.EXTRA_STREAM, session)
-                                .putExtra(Intent.EXTRA_TEXT, message.toString()),
-                        "Share rejected touch report")
+                mActivityStarter.startActivityDismissingKeyguard(Intent.createChooser(new Intent(
+                                                Intent.ACTION_SEND)
+                                                .setType("*/*")
+                                                .putExtra(Intent.EXTRA_SUBJECT, "Rejected touch "
+                                                        + "report")
+                                                .putExtra(Intent.EXTRA_STREAM, session)
+                                                .putExtra(Intent.EXTRA_TEXT, message.toString()),
+                                        "Share rejected touch report")
                                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
                         true /* onlyProvisioned */, true /* dismissShade */);
             });
@@ -1794,133 +1803,6 @@
         return (mDisabled1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
     }
 
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade,
-            int flags) {
-        startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, flags);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void startActivity(Intent intent, boolean dismissShade) {
-        startActivityDismissingKeyguard(intent, false /* onlyProvisioned */, dismissShade);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void startActivity(Intent intent, boolean dismissShade,
-            @androidx.annotation.Nullable ActivityLaunchAnimator.Controller animationController) {
-        startActivity(intent, dismissShade, animationController, false);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void startActivity(Intent intent, boolean dismissShade,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            boolean showOverLockscreenWhenLocked) {
-        startActivity(intent, dismissShade, animationController, showOverLockscreenWhenLocked,
-                getActivityUserHandle(intent));
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void startActivity(Intent intent, boolean dismissShade,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            boolean showOverLockscreenWhenLocked, UserHandle userHandle) {
-        // Make sure that we dismiss the keyguard if it is directly dismissable or when we don't
-        // want to show the activity above it.
-        if (mKeyguardStateController.isUnlocked() || !showOverLockscreenWhenLocked) {
-            startActivityDismissingKeyguard(intent, false, dismissShade,
-                    false /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */,
-                    0 /* flags */, animationController, userHandle);
-            return;
-        }
-
-        boolean animate =
-                animationController != null && shouldAnimateLaunch(true /* isActivityIntent */,
-                        showOverLockscreenWhenLocked);
-
-        ActivityLaunchAnimator.Controller controller = null;
-        if (animate) {
-            // Wrap the animation controller to dismiss the shade and set
-            // mIsLaunchingActivityOverLockscreen during the animation.
-            ActivityLaunchAnimator.Controller delegate = wrapAnimationController(
-                    animationController, dismissShade, /* isLaunchForActivity= */ true);
-            controller = new DelegateLaunchAnimatorController(delegate) {
-                @Override
-                public void onIntentStarted(boolean willAnimate) {
-                    getDelegate().onIntentStarted(willAnimate);
-
-                    if (willAnimate) {
-                        CentralSurfacesImpl.this.mIsLaunchingActivityOverLockscreen = true;
-                    }
-                }
-
-                @Override
-                public void onLaunchAnimationStart(boolean isExpandingFullyAbove) {
-                    super.onLaunchAnimationStart(isExpandingFullyAbove);
-
-                    // Double check that the keyguard is still showing and not going away, but if so
-                    // set the keyguard occluded. Typically, WM will let KeyguardViewMediator know
-                    // directly, but we're overriding that to play the custom launch animation, so
-                    // we need to take care of that here. The unocclude animation is not overridden,
-                    // so WM will call KeyguardViewMediator's unocclude animation runner when the
-                    // activity is exited.
-                    if (mKeyguardStateController.isShowing()
-                            && !mKeyguardStateController.isKeyguardGoingAway()) {
-                        Log.d(TAG, "Setting occluded = true in #startActivity.");
-                        mKeyguardViewMediator.setOccluded(true /* isOccluded */,
-                                true /* animate */);
-                    }
-                }
-
-                @Override
-                public void onLaunchAnimationEnd(boolean isExpandingFullyAbove) {
-                    // Set mIsLaunchingActivityOverLockscreen to false before actually finishing the
-                    // animation so that we can assume that mIsLaunchingActivityOverLockscreen
-                    // being true means that we will collapse the shade (or at least run the
-                    // post collapse runnables) later on.
-                    CentralSurfacesImpl.this.mIsLaunchingActivityOverLockscreen = false;
-                    getDelegate().onLaunchAnimationEnd(isExpandingFullyAbove);
-                }
-
-                @Override
-                public void onLaunchAnimationCancelled(@Nullable Boolean newKeyguardOccludedState) {
-                    if (newKeyguardOccludedState != null) {
-                        mKeyguardViewMediator.setOccluded(
-                                newKeyguardOccludedState, false /* animate */);
-                    }
-
-                    // Set mIsLaunchingActivityOverLockscreen to false before actually finishing the
-                    // animation so that we can assume that mIsLaunchingActivityOverLockscreen
-                    // being true means that we will collapse the shade (or at least run the
-                    // post collapse runnables) later on.
-                    CentralSurfacesImpl.this.mIsLaunchingActivityOverLockscreen = false;
-                    getDelegate().onLaunchAnimationCancelled(newKeyguardOccludedState);
-                }
-            };
-        } else if (dismissShade) {
-            // The animation will take care of dismissing the shade at the end of the animation. If
-            // we don't animate, collapse it directly.
-            collapseShade();
-        }
-
-        // We should exit the dream to prevent the activity from starting below the
-        // dream.
-        if (mKeyguardUpdateMonitor.isDreaming()) {
-            awakenDreams();
-        }
-
-        mActivityLaunchAnimator.startIntentWithAnimation(controller, animate,
-                intent.getPackage(), showOverLockscreenWhenLocked, (adapter) -> TaskStackBuilder
-                        .create(mContext)
-                        .addNextIntent(intent)
-                        .startActivities(
-                                CentralSurfaces.getActivityOptions(getDisplayId(), adapter),
-                                userHandle));
-    }
-
     /**
      * Whether we are currently animating an activity launch above the lockscreen (occluding
      * activity).
@@ -1931,18 +1813,6 @@
     }
 
     @Override
-    public void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade) {
-        startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade);
-    }
-
-    @Override
-    public void startActivity(Intent intent, boolean dismissShade, Callback callback) {
-        startActivityDismissingKeyguard(intent, false, dismissShade,
-                false /* disallowEnterPictureInPictureWhileLaunching */, callback, 0,
-                null /* animationController */, getActivityUserHandle(intent));
-    }
-
-    @Override
     public boolean isWakeUpComingFromTouch() {
         return mWakeUpComingFromTouch;
     }
@@ -2421,228 +2291,11 @@
         return mDisplayId;
     }
 
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
-            boolean dismissShade, int flags) {
-        startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade,
-                false /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */,
-                flags, null /* animationController */, getActivityUserHandle(intent));
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
-            boolean dismissShade) {
-        startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, 0);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void startActivityDismissingKeyguard(Intent intent, boolean onlyProvisioned,
-            boolean dismissShade, boolean disallowEnterPictureInPictureWhileLaunching,
-            Callback callback, int flags,
-            @androidx.annotation.Nullable ActivityLaunchAnimator.Controller animationController,
-            UserHandle userHandle) {
-        startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade,
-                disallowEnterPictureInPictureWhileLaunching, callback, flags, animationController,
-                userHandle, null /* customMessage */);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
-            final boolean dismissShade, final boolean disallowEnterPictureInPictureWhileLaunching,
-            final Callback callback, int flags,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            final UserHandle userHandle, @Nullable String customMessage) {
-        if (onlyProvisioned && !mDeviceProvisionedController.isDeviceProvisioned()) return;
-
-        final boolean willLaunchResolverActivity =
-                mActivityIntentHelper.wouldLaunchResolverActivity(intent,
-                        mLockscreenUserManager.getCurrentUserId());
-
-        boolean animate =
-                animationController != null && !willLaunchResolverActivity && shouldAnimateLaunch(
-                        true /* isActivityIntent */);
-        ActivityLaunchAnimator.Controller animController =
-                animationController != null ? wrapAnimationController(animationController,
-                        dismissShade, /* isLaunchForActivity= */ true) : null;
-
-        // If we animate, we will dismiss the shade only once the animation is done. This is taken
-        // care of by the StatusBarLaunchAnimationController.
-        boolean dismissShadeDirectly = dismissShade && animController == null;
-
-        Runnable runnable = () -> {
-            mAssistManagerLazy.get().hideAssist();
-            intent.setFlags(
-                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            intent.addFlags(flags);
-            int[] result = new int[]{ActivityManager.START_CANCELED};
-
-            mActivityLaunchAnimator.startIntentWithAnimation(animController,
-                    animate, intent.getPackage(), (adapter) -> {
-                        ActivityOptions options = new ActivityOptions(
-                                CentralSurfaces.getActivityOptions(mDisplayId, adapter));
-
-                        // We know that the intent of the caller is to dismiss the keyguard and
-                        // this runnable is called right after the keyguard is solved, so we tell
-                        // WM that we should dismiss it to avoid flickers when opening an activity
-                        // that can also be shown over the keyguard.
-                        options.setDismissKeyguard();
-                        options.setDisallowEnterPictureInPictureWhileLaunching(
-                                disallowEnterPictureInPictureWhileLaunching);
-                        if (CameraIntents.isInsecureCameraIntent(intent)) {
-                            // Normally an activity will set it's requested rotation
-                            // animation on its window. However when launching an activity
-                            // causes the orientation to change this is too late. In these cases
-                            // the default animation is used. This doesn't look good for
-                            // the camera (as it rotates the camera contents out of sync
-                            // with physical reality). So, we ask the WindowManager to
-                            // force the crossfade animation if an orientation change
-                            // happens to occur during the launch.
-                            options.setRotationAnimationHint(
-                                    WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
-                        }
-                        if (Settings.Panel.ACTION_VOLUME.equals(intent.getAction())) {
-                            // Settings Panel is implemented as activity(not a dialog), so
-                            // underlying app is paused and may enter picture-in-picture mode
-                            // as a result.
-                            // So we need to disable picture-in-picture mode here
-                            // if it is volume panel.
-                            options.setDisallowEnterPictureInPictureWhileLaunching(true);
-                        }
-
-                        try {
-                            result[0] = ActivityTaskManager.getService().startActivityAsUser(
-                                    null, mContext.getBasePackageName(),
-                                    mContext.getAttributionTag(),
-                                    intent,
-                                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                                    null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
-                                    options.toBundle(), userHandle.getIdentifier());
-                        } catch (RemoteException e) {
-                            Log.w(TAG, "Unable to start activity", e);
-                        }
-                        return result[0];
-                    });
-
-            if (callback != null) {
-                callback.onActivityStarted(result[0]);
-            }
-        };
-        Runnable cancelRunnable = () -> {
-            if (callback != null) {
-                callback.onActivityStarted(ActivityManager.START_CANCELED);
-            }
-        };
-        // Do not deferKeyguard when occluded because, when keyguard is occluded,
-        // we do not launch the activity until keyguard is done.
-        boolean occluded = mKeyguardStateController.isShowing()
-                && mKeyguardStateController.isOccluded();
-        boolean deferred = !occluded;
-        executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShadeDirectly,
-                willLaunchResolverActivity, deferred /* deferred */, animate,
-                customMessage /* customMessage */);
-    }
-
-    /**
-     * Return a {@link ActivityLaunchAnimator.Controller} wrapping {@code animationController} so
-     * that:
-     *  - if it launches in the notification shade window and {@code dismissShade} is true, then
-     *    the shade will be instantly dismissed at the end of the animation.
-     *  - if it launches in status bar window, it will make the status bar window match the device
-     *    size during the animation (that way, the animation won't be clipped by the status bar
-     *    size).
-     *
-     * @param animationController the controller that is wrapped and will drive the main animation.
-     * @param dismissShade whether the notification shade will be dismissed at the end of the
-     *                     animation. This is ignored if {@code animationController} is not
-     *                     animating in the shade window.
-     * @param isLaunchForActivity whether the launch is for an activity.
-     *
-     * Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too.
-     */
-    @Nullable
-    private ActivityLaunchAnimator.Controller wrapAnimationController(
-            ActivityLaunchAnimator.Controller animationController, boolean dismissShade,
-            boolean isLaunchForActivity) {
-        View rootView = animationController.getLaunchContainer().getRootView();
-
-        Optional<ActivityLaunchAnimator.Controller> controllerFromStatusBar =
-                mStatusBarWindowController.wrapAnimationControllerIfInStatusBar(
-                        rootView, animationController);
-        if (controllerFromStatusBar.isPresent()) {
-            return controllerFromStatusBar.get();
-        }
-
-        if (dismissShade) {
-            // If the view is not in the status bar, then we are animating a view in the shade.
-            // We have to make sure that we collapse it when the animation ends or is cancelled.
-            return new StatusBarLaunchAnimatorController(animationController, this,
-                    isLaunchForActivity);
-        }
-
-        return animationController;
-    }
-
     @Override
     public void readyForKeyguardDone() {
         mStatusBarKeyguardViewManager.readyForKeyguardDone();
     }
 
-
-     /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void executeRunnableDismissingKeyguard(final Runnable runnable,
-            final Runnable cancelAction,
-            final boolean dismissShade,
-            final boolean afterKeyguardGone,
-            final boolean deferred) {
-        executeRunnableDismissingKeyguard(runnable, cancelAction, dismissShade, afterKeyguardGone,
-                deferred, false /* willAnimateOnKeyguard */, null /* customMessage */);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void executeRunnableDismissingKeyguard(final Runnable runnable,
-            final Runnable cancelAction,
-            final boolean dismissShade,
-            final boolean afterKeyguardGone,
-            final boolean deferred,
-            final boolean willAnimateOnKeyguard,
-            @Nullable String customMessage) {
-        OnDismissAction onDismissAction = new OnDismissAction() {
-            @Override
-            public boolean onDismiss() {
-                if (runnable != null) {
-                    if (mKeyguardStateController.isShowing()
-                            && mKeyguardStateController.isOccluded()) {
-                        mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
-                    } else {
-                        mMainExecutor.execute(runnable);
-                    }
-                }
-                if (dismissShade) {
-                    if (mShadeController.isExpandedVisible() && !mBouncerShowing) {
-                        mShadeController.animateCollapseShadeDelayed();
-                    } else {
-                        // Do it after DismissAction has been processed to conserve the needed
-                        // ordering.
-                        mMainExecutor.execute(mShadeController::runPostCollapseRunnables);
-                    }
-                }
-                return deferred;
-            }
-
-            @Override
-            public boolean willRunAnimationOnKeyguard() {
-                return willAnimateOnKeyguard;
-            }
-        };
-        dismissKeyguardThenExecute(onDismissAction, cancelAction, afterKeyguardGone, customMessage);
-    }
-
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -2710,49 +2363,10 @@
         if (mKeyguardStateController.isShowing() && requiresShadeOpen) {
             mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
         }
-        dismissKeyguardThenExecute(action, null /* cancelAction */,
+        mActivityStarter.dismissKeyguardThenExecute(action, null /* cancelAction */,
                 afterKeyguardGone /* afterKeyguardGone */);
     }
 
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
-        dismissKeyguardThenExecute(action, null /* cancelRunnable */, afterKeyguardGone);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
-            boolean afterKeyguardGone) {
-        dismissKeyguardThenExecute(action, cancelAction, afterKeyguardGone, null);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
-            boolean afterKeyguardGone, String customMessage) {
-        if (!action.willRunAnimationOnKeyguard()
-                && mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP
-                && mKeyguardStateController.canDismissLockScreen()
-                && !mStatusBarStateController.leaveOpenOnKeyguardHide()
-                && mDozeServiceHost.isPulsing()) {
-            // Reuse the biometric wake-and-unlock transition if we dismiss keyguard from a pulse.
-            // TODO: Factor this transition out of BiometricUnlockController.
-            mBiometricUnlockController.startWakeAndUnlock(
-                    BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING);
-        }
-        if (mKeyguardStateController.isShowing()) {
-            mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
-                    afterKeyguardGone, customMessage);
-        } else {
-            // If the keyguard isn't showing but the device is dreaming, we should exit the dream.
-            if (mKeyguardUpdateMonitor.isDreaming()) {
-                awakenDreams();
-            }
-            action.onDismiss();
-        }
-
-    }
-
     /**
      * Notify the shade controller that the current user changed
      *
@@ -2928,61 +2542,6 @@
                 | ((currentlyInsecure ? 1 : 0) << 12);
     }
 
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void postQSRunnableDismissingKeyguard(final Runnable runnable) {
-        mMainExecutor.execute(() -> {
-            mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
-            executeRunnableDismissingKeyguard(
-                    () -> mMainExecutor.execute(runnable), null, false, false, false);
-        });
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void postStartActivityDismissingKeyguard(PendingIntent intent) {
-        postStartActivityDismissingKeyguard(intent, null /* animationController */);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void postStartActivityDismissingKeyguard(final PendingIntent intent,
-            @Nullable ActivityLaunchAnimator.Controller animationController) {
-        mMainExecutor.execute(() -> startPendingIntentDismissingKeyguard(intent,
-                null /* intentSentUiThreadCallback */, animationController));
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void postStartActivityDismissingKeyguard(final Intent intent, int delay) {
-        postStartActivityDismissingKeyguard(intent, delay, null /* animationController */);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void postStartActivityDismissingKeyguard(Intent intent, int delay,
-            @Nullable ActivityLaunchAnimator.Controller animationController) {
-        postStartActivityDismissingKeyguard(intent, delay, animationController,
-                null /* customMessage */);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void postStartActivityDismissingKeyguard(Intent intent, int delay,
-            @Nullable ActivityLaunchAnimator.Controller animationController,
-            @Nullable String customMessage) {
-        mMainExecutor.executeDelayed(
-                () ->
-                        startActivityDismissingKeyguard(intent, true /* onlyProvisioned */,
-                                true /* dismissShade */,
-                                false /* disallowEnterPictureInPictureWhileLaunching */,
-                                null /* callback */,
-                                0 /* flags */,
-                                animationController,
-                                getActivityUserHandle(intent), customMessage),
-                delay);
-    }
-
     @Override
     public void showKeyguard() {
         mStatusBarStateController.setKeyguardRequested(true);
@@ -4111,95 +3670,8 @@
                 return willAnimateOnKeyguard;
             }
         };
-        dismissKeyguardThenExecute(onDismissAction, afterKeyguardGone);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void startPendingIntentDismissingKeyguard(final PendingIntent intent) {
-        startPendingIntentDismissingKeyguard(intent, null);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void startPendingIntentDismissingKeyguard(
-            final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback) {
-        startPendingIntentDismissingKeyguard(intent, intentSentUiThreadCallback,
-                (ActivityLaunchAnimator.Controller) null);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void startPendingIntentDismissingKeyguard(PendingIntent intent,
-            Runnable intentSentUiThreadCallback, View associatedView) {
-        ActivityLaunchAnimator.Controller animationController = null;
-        if (associatedView instanceof ExpandableNotificationRow) {
-            animationController = mNotificationAnimationProvider.getAnimatorController(
-                    ((ExpandableNotificationRow) associatedView));
-        }
-
-        startPendingIntentDismissingKeyguard(intent, intentSentUiThreadCallback,
-                animationController);
-    }
-
-    /** Logic is duplicated in {@link ActivityStarterImpl}. Please add it there too. */
-    @Override
-    public void startPendingIntentDismissingKeyguard(
-            final PendingIntent intent, @Nullable final Runnable intentSentUiThreadCallback,
-            @Nullable ActivityLaunchAnimator.Controller animationController) {
-        final boolean willLaunchResolverActivity = intent.isActivity()
-                && mActivityIntentHelper.wouldPendingLaunchResolverActivity(intent,
-                mLockscreenUserManager.getCurrentUserId());
-
-        boolean animate = !willLaunchResolverActivity
-                && animationController != null
-                && shouldAnimateLaunch(intent.isActivity());
-
-        // If we animate, don't collapse the shade and defer the keyguard dismiss (in case we run
-        // the animation on the keyguard). The animation will take care of (instantly) collapsing
-        // the shade and hiding the keyguard once it is done.
-        boolean collapse = !animate;
-        executeActionDismissingKeyguard(() -> {
-            try {
-                // We wrap animationCallback with a StatusBarLaunchAnimatorController so that the
-                // shade is collapsed after the animation (or when it is cancelled, aborted, etc).
-                ActivityLaunchAnimator.Controller controller =
-                        animationController != null ? wrapAnimationController(
-                                animationController, /* dismissShade= */ true, intent.isActivity())
-                                : null;
-
-                mActivityLaunchAnimator.startPendingIntentWithAnimation(
-                        controller, animate, intent.getCreatorPackage(),
-                        (animationAdapter) -> {
-                            ActivityOptions options = new ActivityOptions(
-                                    CentralSurfaces.getActivityOptions(
-                                            mDisplayId, animationAdapter));
-                            // TODO b/221255671: restrict this to only be set for notifications
-                            options.setEligibleForLegacyPermissionPrompt(true);
-                            return intent.sendAndReturnResult(null, 0, null, null, null,
-                                    null, options.toBundle());
-                        });
-            } catch (PendingIntent.CanceledException e) {
-                // the stack trace isn't very helpful here.
-                // Just log the exception message.
-                Log.w(TAG, "Sending intent failed: " + e);
-                if (!collapse) {
-                    // executeActionDismissingKeyguard did not collapse for us already.
-                    collapsePanelOnMainThread();
-                }
-                // TODO: Dismiss Keyguard.
-            }
-            if (intent.isActivity()) {
-                mAssistManagerLazy.get().hideAssist();
-            }
-            if (intentSentUiThreadCallback != null) {
-                postOnUiThread(intentSentUiThreadCallback);
-            }
-        }, willLaunchResolverActivity, collapse, animate);
-    }
-
-    private void postOnUiThread(Runnable runnable) {
-        mMainExecutor.execute(runnable);
+        mActivityStarter.dismissKeyguardThenExecute(onDismissAction, /* cancel= */ null,
+                afterKeyguardGone);
     }
 
     private void onShadeVisibilityChanged(boolean visible) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index a6b2bd8..f26a84b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -30,6 +30,8 @@
 import android.view.ViewDebug;
 import android.view.WindowInsetsController.Appearance;
 
+import androidx.annotation.NonNull;
+
 import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.internal.view.AppearanceRegion;
 import com.android.systemui.Dumpable;
@@ -46,7 +48,6 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Date;
 
 import javax.inject.Inject;
 
@@ -57,7 +58,8 @@
 public class LightBarController implements BatteryController.BatteryStateChangeCallback, Dumpable {
 
     private static final String TAG = "LightBarController";
-    private static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
+    private static final boolean DEBUG_NAVBAR = Compile.IS_DEBUG;
+    private static final boolean DEBUG_LOGS = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
 
     private static final float NAV_BAR_INVERSION_SCRIM_ALPHA_THRESHOLD = 0.1f;
 
@@ -113,6 +115,7 @@
 
     private String mLastSetScrimStateLog;
     private String mLastNavigationBarAppearanceChangedLog;
+    private StringBuilder mLogStringBuilder = null;
 
     @Inject
     public LightBarController(
@@ -193,35 +196,43 @@
                 final boolean darkForTop = darkForQs || mGlobalActionsVisible;
                 mNavigationLight =
                         ((mHasLightNavigationBar && !darkForScrim) || lightForScrim) && !darkForTop;
-                mLastNavigationBarAppearanceChangedLog = "onNavigationBarAppearanceChanged()"
-                        + " appearance=" + appearance
-                        + " nbModeChanged=" + nbModeChanged
-                        + " navigationBarMode=" + navigationBarMode
-                        + " navbarColorManagedByIme=" + navbarColorManagedByIme
-                        + " mHasLightNavigationBar=" + mHasLightNavigationBar
-                        + " ignoreScrimForce=" + ignoreScrimForce
-                        + " darkForScrim=" + darkForScrim
-                        + " lightForScrim=" + lightForScrim
-                        + " darkForQs=" + darkForQs
-                        + " darkForTop=" + darkForTop
-                        + " mNavigationLight=" + mNavigationLight
-                        + " last=" + last
-                        + " timestamp=" + new Date();
-                if (DEBUG) Log.d(TAG, mLastNavigationBarAppearanceChangedLog);
+                if (DEBUG_NAVBAR) {
+                    mLastNavigationBarAppearanceChangedLog = getLogStringBuilder()
+                            .append("onNavigationBarAppearanceChanged()")
+                            .append(" appearance=").append(appearance)
+                            .append(" nbModeChanged=").append(nbModeChanged)
+                            .append(" navigationBarMode=").append(navigationBarMode)
+                            .append(" navbarColorManagedByIme=").append(navbarColorManagedByIme)
+                            .append(" mHasLightNavigationBar=").append(mHasLightNavigationBar)
+                            .append(" ignoreScrimForce=").append(ignoreScrimForce)
+                            .append(" darkForScrim=").append(darkForScrim)
+                            .append(" lightForScrim=").append(lightForScrim)
+                            .append(" darkForQs=").append(darkForQs)
+                            .append(" darkForTop=").append(darkForTop)
+                            .append(" mNavigationLight=").append(mNavigationLight)
+                            .append(" last=").append(last)
+                            .append(" timestamp=").append(System.currentTimeMillis())
+                            .toString();
+                    if (DEBUG_LOGS) Log.d(TAG, mLastNavigationBarAppearanceChangedLog);
+                }
             } else {
                 mNavigationLight = mHasLightNavigationBar
                         && (mDirectReplying && mNavbarColorManagedByIme || !mForceDarkForScrim)
                         && !mQsCustomizing;
-                mLastNavigationBarAppearanceChangedLog = "onNavigationBarAppearanceChanged()"
-                        + " appearance=" + appearance
-                        + " nbModeChanged=" + nbModeChanged
-                        + " navigationBarMode=" + navigationBarMode
-                        + " navbarColorManagedByIme=" + navbarColorManagedByIme
-                        + " mHasLightNavigationBar=" + mHasLightNavigationBar
-                        + " mNavigationLight=" + mNavigationLight
-                        + " last=" + last
-                        + " timestamp=" + new Date();
-                if (DEBUG) Log.d(TAG, mLastNavigationBarAppearanceChangedLog);
+                if (DEBUG_NAVBAR) {
+                    mLastNavigationBarAppearanceChangedLog = getLogStringBuilder()
+                            .append("onNavigationBarAppearanceChanged()")
+                            .append(" appearance=").append(appearance)
+                            .append(" nbModeChanged=").append(nbModeChanged)
+                            .append(" navigationBarMode=").append(navigationBarMode)
+                            .append(" navbarColorManagedByIme=").append(navbarColorManagedByIme)
+                            .append(" mHasLightNavigationBar=").append(mHasLightNavigationBar)
+                            .append(" mNavigationLight=").append(mNavigationLight)
+                            .append(" last=").append(last)
+                            .append(" timestamp=").append(System.currentTimeMillis())
+                            .toString();
+                    if (DEBUG_LOGS) Log.d(TAG, mLastNavigationBarAppearanceChangedLog);
+                }
             }
             if (mNavigationLight != last) {
                 updateNavigation();
@@ -319,18 +330,22 @@
             } else {
                 if (mForceLightForScrim != forceLightForScrimLast) reevaluate();
             }
-            mLastSetScrimStateLog = "setScrimState()"
-                    + " scrimState=" + scrimState
-                    + " scrimBehindAlpha=" + scrimBehindAlpha
-                    + " scrimInFrontColor=" + scrimInFrontColor
-                    + " forceForScrim=" + forceForScrim
-                    + " scrimColorIsLight=" + scrimColorIsLight
-                    + " mHasLightNavigationBar=" + mHasLightNavigationBar
-                    + " mBouncerVisible=" + mBouncerVisible
-                    + " mForceDarkForScrim=" + mForceDarkForScrim
-                    + " mForceLightForScrim=" + mForceLightForScrim
-                    + " timestamp=" + new Date();
-            if (DEBUG) Log.d(TAG, mLastSetScrimStateLog);
+            if (DEBUG_NAVBAR) {
+                mLastSetScrimStateLog = getLogStringBuilder()
+                        .append("setScrimState()")
+                        .append(" scrimState=").append(scrimState)
+                        .append(" scrimBehindAlpha=").append(scrimBehindAlpha)
+                        .append(" scrimInFrontColor=").append(scrimInFrontColor)
+                        .append(" forceForScrim=").append(forceForScrim)
+                        .append(" scrimColorIsLight=").append(scrimColorIsLight)
+                        .append(" mHasLightNavigationBar=").append(mHasLightNavigationBar)
+                        .append(" mBouncerVisible=").append(mBouncerVisible)
+                        .append(" mForceDarkForScrim=").append(mForceDarkForScrim)
+                        .append(" mForceLightForScrim=").append(mForceLightForScrim)
+                        .append(" timestamp=").append(System.currentTimeMillis())
+                        .toString();
+                if (DEBUG_LOGS) Log.d(TAG, mLastSetScrimStateLog);
+            }
         } else {
             boolean forceDarkForScrimLast = mForceDarkForScrim;
             // For BOUNCER/BOUNCER_SCRIMMED cases, we assume that alpha is always below threshold.
@@ -344,17 +359,30 @@
             if (mHasLightNavigationBar && (mForceDarkForScrim != forceDarkForScrimLast)) {
                 reevaluate();
             }
-            mLastSetScrimStateLog = "setScrimState()"
-                    + " scrimState=" + scrimState
-                    + " scrimBehindAlpha=" + scrimBehindAlpha
-                    + " scrimInFrontColor=" + scrimInFrontColor
-                    + " mHasLightNavigationBar=" + mHasLightNavigationBar
-                    + " mForceDarkForScrim=" + mForceDarkForScrim
-                    + " timestamp=" + new Date();
-            if (DEBUG) Log.d(TAG, mLastSetScrimStateLog);
+            if (DEBUG_NAVBAR) {
+                mLastSetScrimStateLog = getLogStringBuilder()
+                        .append("setScrimState()")
+                        .append(" scrimState=").append(scrimState)
+                        .append(" scrimBehindAlpha=").append(scrimBehindAlpha)
+                        .append(" scrimInFrontColor=").append(scrimInFrontColor)
+                        .append(" mHasLightNavigationBar=").append(mHasLightNavigationBar)
+                        .append(" mForceDarkForScrim=").append(mForceDarkForScrim)
+                        .append(" timestamp=").append(System.currentTimeMillis())
+                        .toString();
+                if (DEBUG_LOGS) Log.d(TAG, mLastSetScrimStateLog);
+            }
         }
     }
 
+    @NonNull
+    private StringBuilder getLogStringBuilder() {
+        if (mLogStringBuilder == null) {
+            mLogStringBuilder = new StringBuilder();
+        }
+        mLogStringBuilder.setLength(0);
+        return mLogStringBuilder;
+    }
+
     private static boolean isLight(int appearance, int barMode, int flag) {
         final boolean isTransparentBar = (barMode == MODE_TRANSPARENT
                 || barMode == MODE_LIGHTS_OUT_TRANSPARENT);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index f2fbd7d..0414a14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -23,7 +23,6 @@
 import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
 import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
 
-import android.content.ComponentCallbacks2;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.hardware.biometrics.BiometricSourceType;
@@ -36,7 +35,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewRootImpl;
-import android.view.WindowManagerGlobal;
 import android.window.BackEvent;
 import android.window.OnBackAnimationCallback;
 import android.window.OnBackInvokedDispatcher;
@@ -386,7 +384,9 @@
         mPrimaryBouncerCallbackInteractor.addBouncerExpansionCallback(mExpansionCallback);
         mShadeViewController = shadeViewController;
         if (shadeExpansionStateManager != null) {
-            shadeExpansionStateManager.addExpansionListener(this);
+            ShadeExpansionChangeEvent currentState =
+                    shadeExpansionStateManager.addExpansionListener(this);
+            onPanelExpansionChanged(currentState);
         }
         mBypassController = bypassController;
         mNotificationContainer = notificationContainer;
@@ -488,7 +488,7 @@
         final boolean hideBouncerOverDream =
                 mDreamOverlayStateController.isOverlayActive()
                         && (mShadeViewController.isExpanded()
-                        || mShadeViewController.isExpanding());
+                        || mShadeViewController.isExpandingOrCollapsing());
 
         final boolean isUserTrackingStarted =
                 event.getFraction() != EXPANSION_HIDDEN && event.getTracking();
@@ -983,8 +983,6 @@
         mShadeViewController.resetViewGroupFade();
         mCentralSurfaces.finishKeyguardFadingAway();
         mBiometricUnlockController.finishKeyguardFadingAway();
-        WindowManagerGlobal.getInstance().trimMemory(
-                ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
     }
 
     private void wakeAndUnlockDejank() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt
index eb20bba..991ff56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt
@@ -21,6 +21,7 @@
 import com.android.settingslib.SignalIcon
 import com.android.settingslib.mobile.MobileMappings
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.demomode.DemoMode
 import com.android.systemui.demomode.DemoModeController
@@ -62,6 +63,7 @@
  */
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
 @OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
 class MobileRepositorySwitcher
 @Inject
 constructor(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt
index b129617..e96288a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt
@@ -19,6 +19,7 @@
 import android.os.Bundle
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.demomode.DemoMode
 import com.android.systemui.demomode.DemoModeController
@@ -54,6 +55,7 @@
  */
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
 @OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
 class WifiRepositorySwitcher
 @Inject
 constructor(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index d10d7cf..3d16591 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -156,7 +156,7 @@
         default void onWirelessChargingChanged(boolean isWirlessCharging) {
         }
 
-        default void onIsOverheatedChanged(boolean isOverheated) {
+        default void onIsBatteryDefenderChanged(boolean isBatteryDefender) {
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 1e63b2a..e69d86c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -16,9 +16,9 @@
 
 package com.android.systemui.statusbar.policy;
 
-import static android.os.BatteryManager.BATTERY_HEALTH_OVERHEAT;
-import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
-import static android.os.BatteryManager.EXTRA_HEALTH;
+import static android.os.BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE;
+import static android.os.BatteryManager.CHARGING_POLICY_DEFAULT;
+import static android.os.BatteryManager.EXTRA_CHARGING_STATUS;
 import static android.os.BatteryManager.EXTRA_PRESENT;
 
 import static com.android.settingslib.fuelgauge.BatterySaverLogging.SAVER_ENABLED_QS;
@@ -94,7 +94,7 @@
     protected boolean mPowerSave;
     private boolean mAodPowerSave;
     private boolean mWirelessCharging;
-    private boolean mIsOverheated = false;
+    private boolean mIsBatteryDefender = false;
     private boolean mTestMode = false;
     @VisibleForTesting
     boolean mHasReceivedBattery = false;
@@ -163,7 +163,7 @@
         pw.print("  mPluggedIn="); pw.println(mPluggedIn);
         pw.print("  mCharging="); pw.println(mCharging);
         pw.print("  mCharged="); pw.println(mCharged);
-        pw.print("  mIsOverheated="); pw.println(mIsOverheated);
+        pw.print("  mIsBatteryDefender="); pw.println(mIsBatteryDefender);
         pw.print("  mPowerSave="); pw.println(mPowerSave);
         pw.print("  mStateUnknown="); pw.println(mStateUnknown);
     }
@@ -197,7 +197,7 @@
         cb.onPowerSaveChanged(mPowerSave);
         cb.onBatteryUnknownStateChanged(mStateUnknown);
         cb.onWirelessChargingChanged(mWirelessCharging);
-        cb.onIsOverheatedChanged(mIsOverheated);
+        cb.onIsBatteryDefenderChanged(mIsBatteryDefender);
     }
 
     @Override
@@ -236,11 +236,11 @@
                 fireBatteryUnknownStateChanged();
             }
 
-            int batteryHealth = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
-            boolean isOverheated = batteryHealth == BATTERY_HEALTH_OVERHEAT;
-            if (isOverheated != mIsOverheated) {
-                mIsOverheated = isOverheated;
-                fireIsOverheatedChanged();
+            int chargingStatus = intent.getIntExtra(EXTRA_CHARGING_STATUS, CHARGING_POLICY_DEFAULT);
+            boolean isBatteryDefender = chargingStatus == CHARGING_POLICY_ADAPTIVE_LONGLIFE;
+            if (isBatteryDefender != mIsBatteryDefender) {
+                mIsBatteryDefender = isBatteryDefender;
+                fireIsBatteryDefenderChanged();
             }
 
             fireBatteryLevelChanged();
@@ -313,8 +313,8 @@
         return mPluggedChargingSource == BatteryManager.BATTERY_PLUGGED_WIRELESS;
     }
 
-    public boolean isOverheated() {
-        return mIsOverheated;
+    public boolean isBatteryDefender() {
+        return mIsBatteryDefender;
     }
 
     @Override
@@ -428,11 +428,11 @@
         }
     }
 
-    private void fireIsOverheatedChanged() {
+    private void fireIsBatteryDefenderChanged() {
         synchronized (mChangeCallbacks) {
             final int n = mChangeCallbacks.size();
             for (int i = 0; i < n; i++) {
-                mChangeCallbacks.get(i).onIsOverheatedChanged(mIsOverheated);
+                mChangeCallbacks.get(i).onIsBatteryDefenderChanged(mIsBatteryDefender);
             }
         }
     }
@@ -447,7 +447,7 @@
         String plugged = args.getString("plugged");
         String powerSave = args.getString("powersave");
         String present = args.getString("present");
-        String overheated = args.getString("overheated");
+        String defender = args.getString("defender");
         if (level != null) {
             mLevel = Math.min(Math.max(Integer.parseInt(level), 0), 100);
         }
@@ -462,9 +462,9 @@
             mStateUnknown = !present.equals("true");
             fireBatteryUnknownStateChanged();
         }
-        if (overheated != null) {
-            mIsOverheated = overheated.equals("true");
-            fireIsOverheatedChanged();
+        if (defender != null) {
+            mIsBatteryDefender = defender.equals("true");
+            fireIsBatteryDefenderChanged();
         }
         fireBatteryLevelChanged();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index 5cc3d52..9b0daca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -157,6 +157,7 @@
 
     private String getDeviceString(CachedBluetoothDevice device) {
         return device.getName()
+                + " profiles=" + getDeviceProfilesString(device)
                 + " connected=" + device.isConnected()
                 + " active[A2DP]=" + device.isActiveDevice(BluetoothProfile.A2DP)
                 + " active[HEADSET]=" + device.isActiveDevice(BluetoothProfile.HEADSET)
@@ -164,6 +165,14 @@
                 + " active[LE_AUDIO]=" + device.isActiveDevice(BluetoothProfile.LE_AUDIO);
     }
 
+    private String getDeviceProfilesString(CachedBluetoothDevice device) {
+        List<String> profileIds = new ArrayList<>();
+        for (LocalBluetoothProfile profile : device.getProfiles()) {
+            profileIds.add(String.valueOf(profile.getProfileId()));
+        }
+        return "[" + String.join(",", profileIds) + "]";
+    }
+
     @Override
     public List<CachedBluetoothDevice> getConnectedDevices() {
         List<CachedBluetoothDevice> out;
@@ -296,7 +305,8 @@
         for (CachedBluetoothDevice device : getDevices()) {
             isActive |= device.isActiveDevice(BluetoothProfile.HEADSET)
                     || device.isActiveDevice(BluetoothProfile.A2DP)
-                    || device.isActiveDevice(BluetoothProfile.HEARING_AID);
+                    || device.isActiveDevice(BluetoothProfile.HEARING_AID)
+                    || device.isActiveDevice(BluetoothProfile.LE_AUDIO);
         }
 
         if (mIsActive != isActive) {
@@ -315,7 +325,8 @@
                 boolean isConnected = device.isConnectedProfile(profile);
                 if (profileId == BluetoothProfile.HEADSET
                         || profileId == BluetoothProfile.A2DP
-                        || profileId == BluetoothProfile.HEARING_AID) {
+                        || profileId == BluetoothProfile.HEARING_AID
+                        || profileId == BluetoothProfile.LE_AUDIO) {
                     audioProfileConnected |= isConnected;
                 } else {
                     otherProfileConnected |= isConnected;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 9ede6ce..ed8050a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -140,7 +140,13 @@
     }
 
     protected boolean shouldHeadsUpBecomePinned(@NonNull NotificationEntry entry) {
-        return hasFullScreenIntent(entry);
+        final HeadsUpEntry headsUpEntry = getHeadsUpEntry(entry.getKey());
+        if (headsUpEntry == null) {
+            // This should not happen since shouldHeadsUpBecomePinned is always called after adding
+            // the NotificationEntry into AlertingNotificationManager's mAlertEntries map.
+            return hasFullScreenIntent(entry);
+        }
+        return hasFullScreenIntent(entry) && !headsUpEntry.wasUnpinned;
     }
 
     protected boolean hasFullScreenIntent(@NonNull NotificationEntry entry) {
@@ -151,6 +157,9 @@
             @NonNull HeadsUpManager.HeadsUpEntry headsUpEntry, boolean isPinned) {
         mLogger.logSetEntryPinned(headsUpEntry.mEntry, isPinned);
         NotificationEntry entry = headsUpEntry.mEntry;
+        if (!isPinned) {
+            headsUpEntry.wasUnpinned = true;
+        }
         if (entry.isRowPinned() != isPinned) {
             entry.setRowPinned(isPinned);
             updatePinnedMode();
@@ -177,7 +186,9 @@
     protected void onAlertEntryAdded(AlertEntry alertEntry) {
         NotificationEntry entry = alertEntry.mEntry;
         entry.setHeadsUp(true);
-        setEntryPinned((HeadsUpEntry) alertEntry, shouldHeadsUpBecomePinned(entry));
+
+        final boolean shouldPin = shouldHeadsUpBecomePinned(entry);
+        setEntryPinned((HeadsUpEntry) alertEntry, shouldPin);
         EventLogTags.writeSysuiHeadsUpStatus(entry.getKey(), 1 /* visible */);
         for (OnHeadsUpChangedListener listener : mListeners) {
             listener.onHeadsUpStateChanged(entry, true);
@@ -411,6 +422,7 @@
     protected class HeadsUpEntry extends AlertEntry {
         public boolean remoteInputActive;
         protected boolean expanded;
+        protected boolean wasUnpinned;
 
         @Override
         public boolean isSticky() {
diff --git a/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt b/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt
index 8e2b05c..b9c2487 100644
--- a/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/telephony/ui/activity/SwitchToManagedProfileForCallActivity.kt
@@ -22,14 +22,21 @@
 import android.net.Uri
 import android.os.Bundle
 import android.os.UserHandle
+import android.telecom.TelecomManager
 import android.util.Log
 import android.view.WindowManager
 import com.android.internal.app.AlertActivity
 import com.android.systemui.R
+import javax.inject.Inject
 
 /** Dialog shown to the user to switch to managed profile for making a call using work SIM. */
-class SwitchToManagedProfileForCallActivity : AlertActivity(), DialogInterface.OnClickListener {
+class SwitchToManagedProfileForCallActivity
+@Inject
+constructor(
+    private val telecomManager: TelecomManager?,
+) : AlertActivity(), DialogInterface.OnClickListener {
     private lateinit var phoneNumber: Uri
+    private lateinit var positiveActionIntent: Intent
     private var managedProfileUserId = UserHandle.USER_NULL
 
     override fun onCreate(savedInstanceState: Bundle?) {
@@ -37,8 +44,7 @@
             WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS
         )
         super.onCreate(savedInstanceState)
-
-        phoneNumber = intent.getData()
+        phoneNumber = intent.data ?: Uri.EMPTY
         managedProfileUserId =
             intent.getIntExtra(
                 "android.telecom.extra.MANAGED_PROFILE_USER_ID",
@@ -48,11 +54,31 @@
         mAlertParams.apply {
             mTitle = getString(R.string.call_from_work_profile_title)
             mMessage = getString(R.string.call_from_work_profile_text)
-            mPositiveButtonText = getString(R.string.call_from_work_profile_action)
             mNegativeButtonText = getString(R.string.call_from_work_profile_close)
             mPositiveButtonListener = this@SwitchToManagedProfileForCallActivity
             mNegativeButtonListener = this@SwitchToManagedProfileForCallActivity
         }
+
+        // A dialer app may not be available in the managed profile. We try to handle that
+        // gracefully by redirecting the user to the app market to install a suitable app.
+        val defaultDialerPackageName: String? =
+            telecomManager?.getDefaultDialerPackage(UserHandle.of(managedProfileUserId))
+
+        val (intent, positiveButtonText) =
+            defaultDialerPackageName?.let {
+                Intent(
+                    Intent.ACTION_CALL,
+                    phoneNumber,
+                ) to R.string.call_from_work_profile_action
+            }
+                ?: Intent(
+                    Intent.ACTION_VIEW,
+                    Uri.parse(APP_STORE_DIALER_QUERY),
+                ) to R.string.install_dialer_on_work_profile_action
+
+        positiveActionIntent = intent
+        mAlertParams.apply { mPositiveButtonText = getString(positiveButtonText) }
+
         setupAlert()
     }
 
@@ -66,7 +92,7 @@
     private fun switchToManagedProfile() {
         try {
             applicationContext.startActivityAsUser(
-                Intent(Intent.ACTION_CALL, phoneNumber),
+                positiveActionIntent,
                 ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle(),
                 UserHandle.of(managedProfileUserId)
             )
@@ -77,5 +103,6 @@
 
     companion object {
         private const val TAG = "SwitchToManagedProfileForCallActivity"
+        private const val APP_STORE_DIALER_QUERY = "market://search?q=dialer"
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
index 59122af..8f048963 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
@@ -79,6 +79,7 @@
     @LayoutRes private val viewLayoutRes: Int,
     private val wakeLockBuilder: WakeLock.Builder,
     private val systemClock: SystemClock,
+    internal val tempViewUiEventLogger: TemporaryViewUiEventLogger,
 ) : CoreStartable, Dumpable {
     /**
      * Window layout params that will be used as a starting point for the [windowLayoutParams] of
@@ -207,6 +208,7 @@
 
     private fun showNewView(newDisplayInfo: DisplayInfo, timeout: Int) {
         logger.logViewAddition(newDisplayInfo.info)
+        tempViewUiEventLogger.logViewAdded(newDisplayInfo.info.instanceId)
         createAndAcquireWakeLock(newDisplayInfo)
         updateTimeout(newDisplayInfo, timeout)
         inflateAndUpdateView(newDisplayInfo)
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt
index 5596cf6..48bd047 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt
@@ -16,6 +16,8 @@
 
 package com.android.systemui.temporarydisplay
 
+import com.android.internal.logging.InstanceId
+
 /**
  * A superclass view state used with [TemporaryViewDisplayController].
  */
@@ -45,6 +47,9 @@
 
     /** The priority for this view. */
     abstract val priority: ViewPriority
+
+    /** Instance ID for logging purposes */
+    abstract val instanceId: InstanceId?
 }
 
 const val DEFAULT_TIMEOUT_MILLIS = 10000
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLogger.kt
new file mode 100644
index 0000000..1345851
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLogger.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.temporarydisplay
+
+import com.android.internal.logging.InstanceId
+import com.android.internal.logging.InstanceIdSequence
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+private const val INSTANCE_ID_MAX = 1 shl 20
+
+/** A helper class to log events related to the temporary view */
+@SysUISingleton
+class TemporaryViewUiEventLogger @Inject constructor(val logger: UiEventLogger) {
+
+    private val instanceIdSequence = InstanceIdSequence(INSTANCE_ID_MAX)
+
+    /** Get a new instance ID for a new media control */
+    fun getNewInstanceId(): InstanceId {
+        return instanceIdSequence.newInstanceId()
+    }
+
+    /** Logs that view is added */
+    fun logViewAdded(instanceId: InstanceId?) {
+        logger.log(TemporaryViewUiEvent.TEMPORARY_VIEW_ADDED, instanceId)
+    }
+
+    /** Logs that view is manually dismissed by user */
+    fun logViewManuallyDismissed(instanceId: InstanceId?) {
+        logger.log(TemporaryViewUiEvent.TEMPORARY_VIEW_MANUALLY_DISMISSED, instanceId)
+    }
+}
+
+enum class TemporaryViewUiEvent(val metricId: Int) : UiEventLogger.UiEventEnum {
+    @UiEvent(doc = "The temporary view was added to window manager") TEMPORARY_VIEW_ADDED(1389),
+    @UiEvent(doc = "The temporary view was manually dismissed")
+    TEMPORARY_VIEW_MANUALLY_DISMISSED(1390);
+
+    override fun getId() = metricId
+}
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
index 4fbbc89..7ed56e7 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
@@ -21,6 +21,8 @@
 import android.content.Context
 import android.graphics.Rect
 import android.os.PowerManager
+import android.os.Process
+import android.os.VibrationAttributes
 import android.view.Gravity
 import android.view.MotionEvent
 import android.view.View
@@ -50,6 +52,7 @@
 import com.android.systemui.statusbar.VibratorHelper
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.temporarydisplay.TemporaryViewDisplayController
+import com.android.systemui.temporarydisplay.TemporaryViewUiEventLogger
 import com.android.systemui.util.concurrency.DelayableExecutor
 import com.android.systemui.util.time.SystemClock
 import com.android.systemui.util.view.ViewUtil
@@ -90,6 +93,7 @@
     private val vibratorHelper: VibratorHelper,
     wakeLockBuilder: WakeLock.Builder,
     systemClock: SystemClock,
+    tempViewUiEventLogger: TemporaryViewUiEventLogger,
 ) :
     TemporaryViewDisplayController<ChipbarInfo, ChipbarLogger>(
         context,
@@ -103,6 +107,7 @@
         R.layout.chipbar,
         wakeLockBuilder,
         systemClock,
+        tempViewUiEventLogger,
     ) {
 
     private lateinit var parent: ChipbarRootView
@@ -226,7 +231,15 @@
         maybeGetAccessibilityFocus(newInfo, currentView)
 
         // ---- Haptics ----
-        newInfo.vibrationEffect?.let { vibratorHelper.vibrate(it) }
+        newInfo.vibrationEffect?.let {
+            vibratorHelper.vibrate(
+                Process.myUid(),
+                context.getApplicationContext().getPackageName(),
+                it,
+                newInfo.windowTitle,
+                VIBRATION_ATTRIBUTES,
+            )
+        }
     }
 
     private fun maybeGetAccessibilityFocus(info: ChipbarInfo?, view: ViewGroup) {
@@ -305,6 +318,7 @@
             )
             return
         }
+        tempViewUiEventLogger.logViewManuallyDismissed(currentDisplayInfo.info.instanceId)
         removeView(currentDisplayInfo.info.id, SWIPE_UP_GESTURE_REASON)
         updateGestureListening()
     }
@@ -352,6 +366,11 @@
         val loadingView: View,
         val animator: ObjectAnimator,
     )
+
+    companion object {
+        val VIBRATION_ATTRIBUTES: VibrationAttributes =
+            VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK)
+    }
 }
 
 @IdRes private val INFO_TAG = R.id.tag_chipbar_info
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
index 52f2d11..1d50241 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
@@ -19,6 +19,7 @@
 import android.os.VibrationEffect
 import android.view.View
 import androidx.annotation.AttrRes
+import com.android.internal.logging.InstanceId
 import com.android.systemui.R
 import com.android.systemui.common.shared.model.Text
 import com.android.systemui.common.shared.model.TintedIcon
@@ -47,6 +48,7 @@
     override val timeoutMs: Int,
     override val id: String,
     override val priority: ViewPriority,
+    override val instanceId: InstanceId?,
 ) : TemporaryViewInfo() {
     companion object {
         // LINT.IfChange
diff --git a/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java b/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java
index 08dbb81..08b0c64 100644
--- a/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/user/CreateUserActivity.java
@@ -32,11 +32,9 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.logging.UiEventLogger;
-import com.android.settingslib.users.EditUserInfoController;
-import com.android.settingslib.users.GrantAdminDialogController;
+import com.android.settingslib.users.CreateUserDialogController;
 import com.android.systemui.R;
 import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.user.utils.MultiUserActionsEvent;
 
 import javax.inject.Inject;
 
@@ -61,20 +59,18 @@
     private static final String EXTRA_IS_KEYGUARD_SHOWING = "extra_is_keyguard_showing";
 
     private final UserCreator mUserCreator;
-    private final EditUserInfoController mEditUserInfoController;
+    private CreateUserDialogController mCreateUserDialogController;
     private final IActivityManager mActivityManager;
     private final ActivityStarter mActivityStarter;
     private final UiEventLogger mUiEventLogger;
-    private Dialog mGrantAdminDialog;
     private Dialog mSetupUserDialog;
     private final OnBackInvokedCallback mBackCallback = this::onBackInvoked;
-    private boolean mGrantAdminRights;
     @Inject
     public CreateUserActivity(UserCreator userCreator,
-            EditUserInfoController editUserInfoController, IActivityManager activityManager,
+            CreateUserDialogController createUserDialogController, IActivityManager activityManager,
             ActivityStarter activityStarter, UiEventLogger uiEventLogger) {
         mUserCreator = userCreator;
-        mEditUserInfoController = editUserInfoController;
+        mCreateUserDialogController = createUserDialogController;
         mActivityManager = activityManager;
         mActivityStarter = activityStarter;
         mUiEventLogger = uiEventLogger;
@@ -86,19 +82,10 @@
         setShowWhenLocked(true);
         setContentView(R.layout.activity_create_new_user);
         if (savedInstanceState != null) {
-            mEditUserInfoController.onRestoreInstanceState(savedInstanceState);
+            mCreateUserDialogController.onRestoreInstanceState(savedInstanceState);
         }
-        boolean isKeyguardShowing = getIntent().getBooleanExtra(EXTRA_IS_KEYGUARD_SHOWING, true);
-        // Display grant admin dialog only on unlocked device to admin users if multiple admins
-        // are allowed on this device.
-        if (mUserCreator.isMultipleAdminEnabled() && mUserCreator.isUserAdmin()
-                && !isKeyguardShowing) {
-            mGrantAdminDialog = buildGrantAdminDialog();
-            mGrantAdminDialog.show();
-        } else {
-            mSetupUserDialog = createDialog();
-            mSetupUserDialog.show();
-        }
+        mSetupUserDialog = createDialog();
+        mSetupUserDialog.show();
         getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
                         OnBackInvokedDispatcher.PRIORITY_DEFAULT,
                         mBackCallback);
@@ -110,7 +97,7 @@
             outState.putBundle(DIALOG_STATE_KEY, mSetupUserDialog.onSaveInstanceState());
         }
 
-        mEditUserInfoController.onSaveInstanceState(outState);
+        mCreateUserDialogController.onSaveInstanceState(outState);
         super.onSaveInstanceState(outState);
     }
 
@@ -125,48 +112,21 @@
 
     private Dialog createDialog() {
         String defaultUserName = getString(com.android.settingslib.R.string.user_new_user_name);
-
-        return mEditUserInfoController.createDialog(
+        boolean isKeyguardShowing = getIntent().getBooleanExtra(EXTRA_IS_KEYGUARD_SHOWING, true);
+        return mCreateUserDialogController.createDialog(
                 this,
                 this::startActivity,
-                null,
-                defaultUserName,
-                getString(com.android.settingslib.R.string.user_add_user),
+                (mUserCreator.isMultipleAdminEnabled() && mUserCreator.isUserAdmin()
+                        && !isKeyguardShowing),
                 this::addUserNow,
                 this::finish
         );
     }
 
-    /**
-     * Returns dialog that allows to grant user admin rights.
-     */
-    private Dialog buildGrantAdminDialog() {
-        return new GrantAdminDialogController().createDialog(
-                this,
-                (grantAdminRights) -> {
-                    mGrantAdminDialog.dismiss();
-                    mGrantAdminRights = grantAdminRights;
-                    if (mGrantAdminRights) {
-                        mUiEventLogger.log(MultiUserActionsEvent
-                                        .GRANT_ADMIN_FROM_USER_SWITCHER_CREATION_DIALOG);
-                    } else {
-                        mUiEventLogger.log(MultiUserActionsEvent
-                                        .NOT_GRANT_ADMIN_FROM_USER_SWITCHER_CREATION_DIALOG);
-                    }
-                    mSetupUserDialog = createDialog();
-                    mSetupUserDialog.show();
-                },
-                () -> {
-                    mGrantAdminRights = false;
-                    finish();
-                }
-        );
-    }
-
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
-        mEditUserInfoController.onActivityResult(requestCode, resultCode, data);
+        mCreateUserDialogController.onActivityResult(requestCode, resultCode, data);
     }
 
     @Override
@@ -178,9 +138,6 @@
         if (mSetupUserDialog != null) {
             mSetupUserDialog.dismiss();
         }
-        if (mGrantAdminDialog != null) {
-            mGrantAdminDialog.dismiss();
-        }
         finish();
     }
 
@@ -190,7 +147,7 @@
         super.onDestroy();
     }
 
-    private void addUserNow(String userName, Drawable userIcon) {
+    private void addUserNow(String userName, Drawable userIcon, Boolean isAdmin) {
         mSetupUserDialog.dismiss();
         userName = (userName == null || userName.trim().isEmpty())
                 ? getString(com.android.settingslib.R.string.user_new_user_name)
@@ -198,7 +155,7 @@
 
         mUserCreator.createUser(userName, userIcon,
                 userInfo -> {
-                    if (mGrantAdminRights) {
+                    if (isAdmin) {
                         mUserCreator.setUserAdmin(userInfo.id);
                     }
                     switchToUser(userInfo.id);
@@ -230,7 +187,7 @@
      */
     private void startActivity(Intent intent, int requestCode) {
         mActivityStarter.dismissKeyguardThenExecute(() -> {
-            mEditUserInfoController.startingActivityForResult();
+            mCreateUserDialogController.startingActivityForResult();
             startActivityForResult(intent, requestCode);
             return true;
         }, /* cancel= */ null, /* afterKeyguardGone= */ true);
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserModule.java b/packages/SystemUI/src/com/android/systemui/user/UserModule.java
index b2bf972..d8ee686 100644
--- a/packages/SystemUI/src/com/android/systemui/user/UserModule.java
+++ b/packages/SystemUI/src/com/android/systemui/user/UserModule.java
@@ -18,6 +18,7 @@
 
 import android.os.UserHandle;
 
+import com.android.settingslib.users.CreateUserDialogController;
 import com.android.settingslib.users.EditUserInfoController;
 import com.android.systemui.user.data.repository.UserRepositoryModule;
 import com.android.systemui.user.domain.interactor.HeadlessSystemUserModeModule;
@@ -45,6 +46,12 @@
         return new EditUserInfoController(FILE_PROVIDER_AUTHORITY);
     }
 
+    /** Provides {@link CreateUserDialogController} */
+    @Provides
+    public static CreateUserDialogController provideCreateUserDialogController() {
+        return new CreateUserDialogController(FILE_PROVIDER_AUTHORITY);
+    }
+
     /**
      * Provides the {@link UserHandle} for the user associated with this System UI process.
      *
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
index c2922c4..27c348b 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
@@ -50,6 +50,7 @@
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.qs.user.UserSwitchDialogController
 import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
+import com.android.systemui.user.CreateUserActivity
 import com.android.systemui.user.data.model.UserSwitcherSettingsModel
 import com.android.systemui.user.data.repository.UserRepository
 import com.android.systemui.user.data.source.UserRecord
@@ -455,13 +456,16 @@
             UserActionModel.ADD_USER -> {
                 uiEventLogger.log(MultiUserActionsEvent.CREATE_USER_FROM_USER_SWITCHER)
                 val currentUser = repository.getSelectedUserInfo()
-                showDialog(
-                    ShowDialogRequestModel.ShowAddUserDialog(
-                        userHandle = currentUser.userHandle,
-                        isKeyguardShowing = keyguardInteractor.isKeyguardShowing(),
-                        showEphemeralMessage = currentUser.isGuest && currentUser.isEphemeral,
-                        dialogShower = dialogShower,
-                    )
+                dismissDialog()
+                activityStarter.startActivity(
+                    CreateUserActivity.createIntentForStart(
+                        applicationContext,
+                        keyguardInteractor.isKeyguardShowing()
+                    ),
+                    /* dismissShade= */ true,
+                    /* animationController */ null,
+                    /* showOverLockscreenWhenLocked */ true,
+                    /* userHandle */ currentUser.getUserHandle(),
                 )
             }
             UserActionModel.ADD_SUPERVISED_USER -> {
diff --git a/packages/SystemUI/src/com/android/systemui/util/BinderLogger.kt b/packages/SystemUI/src/com/android/systemui/util/BinderLogger.kt
new file mode 100644
index 0000000..e21f0aa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/BinderLogger.kt
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.util
+
+import android.os.Binder
+import android.os.Binder.ProxyTransactListener
+import android.os.Build
+import android.os.IBinder
+import android.os.StrictMode
+import android.os.StrictMode.ThreadPolicy
+import android.os.Trace.TRACE_TAG_APP
+import android.os.Trace.asyncTraceForTrackBegin
+import android.os.Trace.asyncTraceForTrackEnd
+import android.util.Log
+import com.android.settingslib.utils.ThreadUtils
+import com.android.systemui.CoreStartable
+import com.android.systemui.DejankUtils
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import javax.inject.Inject
+import kotlin.random.Random.Default.nextInt
+
+@SysUISingleton
+class BinderLogger
+@Inject
+constructor(
+    private val featureFlags: FeatureFlags,
+) : CoreStartable, ProxyTransactListener {
+
+    override fun start() {
+        // This feature is only allowed on "userdebug" and "eng" builds
+        if (Build.IS_USER) return
+        if (!featureFlags.isEnabled(Flags.WARN_ON_BLOCKING_BINDER_TRANSACTIONS)) return
+        if (DejankUtils.STRICT_MODE_ENABLED) {
+            Log.e(
+                TAG,
+                "Feature disabled; persist.sysui.strictmode (DejankUtils) and " +
+                    "WARN_ON_BLOCKING_BINDER_TRANSACTIONS (BinderLogger) are incompatible"
+            )
+            return
+        }
+        Binder.setProxyTransactListener(this)
+        val policyBuilder = ThreadPolicy.Builder().detectCustomSlowCalls().penaltyLog()
+        StrictMode.setThreadPolicy(policyBuilder.build())
+    }
+
+    override fun onTransactStarted(binder: IBinder, transactionCode: Int, flags: Int): Any? {
+        // Ignore one-way binder transactions
+        if (flags and IBinder.FLAG_ONEWAY != 0) return null
+        // Ignore anything not on the main thread
+        if (!ThreadUtils.isMainThread()) return null
+
+        // To make it easier to debug, log the most likely cause of the blocking binder transaction
+        // by parsing the stack trace.
+        val tr = Throwable()
+        val analysis = BinderTransactionAnalysis.fromStackTrace(tr.stackTrace)
+        val traceCookie = nextInt()
+        asyncTraceForTrackBegin(TRACE_TAG_APP, TRACK_NAME, analysis.traceMessage, traceCookie)
+        if (analysis.isSystemUi) {
+            StrictMode.noteSlowCall(analysis.logMessage)
+        } else {
+            Log.v(TAG, analysis.logMessage, tr)
+        }
+        return traceCookie
+    }
+
+    override fun onTransactStarted(binder: IBinder, transactionCode: Int): Any? {
+        return null
+    }
+
+    override fun onTransactEnded(o: Any?) {
+        if (o is Int) {
+            asyncTraceForTrackEnd(TRACE_TAG_APP, TRACK_NAME, o)
+        }
+    }
+
+    /**
+     * Class for finding the origin of a binder transaction from a stack trace and creating an error
+     * message that indicates 1) whether or not the call originated from System UI, and 2) the name
+     * of the binder transaction and where it was called.
+     *
+     * There are two types of stack traces:
+     * 1. Stack traces that originate from System UI, which look like the following: ```
+     *    android.os.BinderProxy.transact(BinderProxy.java:541)
+     *    android.content.pm.BaseParceledListSlice.<init>(BaseParceledListSlice.java:94)
+     *    android.content.pm.ParceledListSlice.<init>(ParceledListSlice.java:42)
+     *    android.content.pm.ParceledListSlice.<init>(Unknown Source:0)
+     *    android.content.pm.ParceledListSlice$1.createFromParcel(ParceledListSlice.java:80)
+     *    android.content.pm.ParceledListSlice$1.createFromParcel(ParceledListSlice.java:78)
+     *    android.os.Parcel.readTypedObject(Parcel.java:3982)
+     *    android.content.pm.IPackageManager$Stub$Proxy.getInstalledPackages(IPackageManager.java:5029)
+     *    com.android.systemui.ExampleClass.runTwoWayBinderIPC(ExampleClass.kt:343) ... ``` Most of
+     *    these binder transactions contain a reference to a `$Stub$Proxy`, but some don't. For
+     *    example: ``` android.os.BinderProxy.transact(BinderProxy.java:541)
+     *    android.content.ContentProviderProxy.query(ContentProviderNative.java:479)
+     *    android.content.ContentResolver.query(ContentResolver.java:1219)
+     *    com.android.systemui.power.PowerUI.refreshEstimateIfNeeded(PowerUI.java:383) ``` In both
+     *    cases, we identify the call closest to a sysui package to make the error more clear.
+     * 2. Stack traces that originate outside of System UI, which look like the following: ```
+     *    android.os.BinderProxy.transact(BinderProxy.java:541)
+     *    android.service.notification.IStatusBarNotificationHolder$Stub$Proxy.get(IStatusBarNotificationHolder.java:121)
+     *    android.service.notification.NotificationListenerService$NotificationListenerWrapper.onNotificationPosted(NotificationListenerService.java:1396)
+     *    android.service.notification.INotificationListener$Stub.onTransact(INotificationListener.java:248)
+     *    android.os.Binder.execTransactInternal(Binder.java:1285)
+     *    android.os.Binder.execTransact(Binder.java:1244) ```
+     *
+     * @param isSystemUi Whether or not the call originated from System UI. If it didn't, it's due
+     *   to internal implementation details of a core framework API.
+     * @param cause The cause of the binder transaction
+     * @param binderCall The binder transaction itself
+     */
+    private class BinderTransactionAnalysis
+    constructor(
+        val isSystemUi: Boolean,
+        cause: StackTraceElement?,
+        binderCall: StackTraceElement?
+    ) {
+        val logMessage: String
+        val traceMessage: String
+
+        init {
+            val callName =
+                (if (isSystemUi) getSimpleCallRefWithFileAndLineNumber(cause)
+                else "${getSimpleCallRef(cause)}()") + " -> ${getBinderCallRef(binderCall)}"
+            logMessage =
+                "Blocking binder transaction detected" +
+                    (if (!isSystemUi) ", but the call did not originate from System UI" else "") +
+                    ": $callName"
+            traceMessage = "${if (isSystemUi) "sysui" else "core"}: $callName"
+        }
+
+        companion object {
+            fun fromStackTrace(stackTrace: Array<StackTraceElement>): BinderTransactionAnalysis {
+                if (stackTrace.size < 2) {
+                    return BinderTransactionAnalysis(false, null, null)
+                }
+                var previousStackElement: StackTraceElement = stackTrace.first()
+
+                // The stack element corresponding to the binder transaction. For example:
+                // `android.content.pm.IPackageManager$Stub$Proxy.getInstalledPackages(IPackageManager.java:50)`
+                var binderTransaction: StackTraceElement? = null
+                // The stack element that caused the binder transaction in the first place.
+                // For example:
+                // `com.android.systemui.ExampleClass.runTwoWayBinderIPC(ExampleClass.kt:343)`
+                var causeOfBinderTransaction: StackTraceElement? = null
+
+                // Iterate starting from the top of the stack (BinderProxy.transact).
+                for (i in 1 until stackTrace.size) {
+                    val stackElement = stackTrace[i]
+                    if (previousStackElement.className?.endsWith("\$Stub\$Proxy") == true) {
+                        binderTransaction = previousStackElement
+                        causeOfBinderTransaction = stackElement
+                    }
+                    // As a heuristic, find the top-most call from a sysui package (besides this
+                    // class) and blame it
+                    val className = stackElement.className
+                    if (
+                        className != BinderLogger::class.java.name &&
+                            (className.startsWith(SYSUI_PKG) || className.startsWith(KEYGUARD_PKG))
+                    ) {
+                        causeOfBinderTransaction = stackElement
+
+                        return BinderTransactionAnalysis(
+                            true,
+                            causeOfBinderTransaction,
+                            // If an IInterface.Stub.Proxy-like call has not been identified yet,
+                            // blame the previous call in the stack.
+                            binderTransaction ?: previousStackElement
+                        )
+                    }
+                    previousStackElement = stackElement
+                }
+                // If we never found a call originating from sysui, report it with an explanation
+                // that we could not find a culprit in sysui.
+                return BinderTransactionAnalysis(false, causeOfBinderTransaction, binderTransaction)
+            }
+        }
+    }
+
+    companion object {
+        private const val TAG: String = "SystemUIBinder"
+        private const val TRACK_NAME = "Blocking Binder Transactions"
+        private const val SYSUI_PKG = "com.android.systemui"
+        private const val KEYGUARD_PKG = "com.android.keyguard"
+        private const val UNKNOWN = "<unknown>"
+
+        /**
+         * Start of the source file for any R8 build within AOSP.
+         *
+         * TODO(b/213833843): Allow configuration of the prefix via a build variable.
+         */
+        private const val AOSP_SOURCE_FILE_MARKER = "go/retraceme "
+
+        /** Start of the source file for any R8 compiler build. */
+        private const val R8_SOURCE_FILE_MARKER = "R8_"
+
+        /**
+         * Returns a short string for a [StackTraceElement] that references a binder transaction.
+         * For example, a stack frame of
+         * `android.content.pm.IPackageManager$Stub$Proxy.getInstalledPackages(IPackageManager.java:50)`
+         * would return `android.content.pm.IPackageManager#getInstalledPackages()`
+         */
+        private fun getBinderCallRef(stackFrame: StackTraceElement?): String =
+            if (stackFrame != null) "${getBinderClassName(stackFrame)}#${stackFrame.methodName}()"
+            else UNKNOWN
+
+        /**
+         * Returns the class name of a [StackTraceElement], removing any `$Stub$Proxy` suffix, but
+         * still including the package name. This makes binder class names more readable. For
+         * example, for a stack element of
+         * `android.content.pm.IPackageManager$Stub$Proxy.getInstalledPackages(IPackageManager.java:50)`
+         * this would return `android.content.pm.IPackageManager`
+         */
+        private fun getBinderClassName(stackFrame: StackTraceElement): String {
+            val className = stackFrame.className
+            val stubDefIndex = className.indexOf("\$Stub\$Proxy")
+            return if (stubDefIndex > 0) className.substring(0, stubDefIndex) else className
+        }
+
+        /**
+         * Returns a short string for a [StackTraceElement], including the file name and line
+         * number.
+         *
+         * If the source file needs retracing, this falls back to the default `toString()` method so
+         * that it can be read by the `retrace` command-line tool (`m retrace`).
+         */
+        private fun getSimpleCallRefWithFileAndLineNumber(stackFrame: StackTraceElement?): String =
+            if (stackFrame != null) {
+                with(stackFrame) {
+                    if (
+                        fileName == null ||
+                            fileName.startsWith(AOSP_SOURCE_FILE_MARKER) ||
+                            fileName.startsWith(R8_SOURCE_FILE_MARKER)
+                    ) {
+                        // If the source file needs retracing, use the default toString() method for
+                        // compatibility with the retrace command-line tool
+                        "at $stackFrame"
+                    } else {
+                        "at ${getSimpleCallRef(stackFrame)}($fileName:$lineNumber)"
+                    }
+                }
+            } else UNKNOWN
+
+        /**
+         * Returns a short string for a [StackTraceElement] including it's class name and method
+         * name. For example, if the stack frame is
+         * `com.android.systemui.ExampleController.makeBlockingBinderIPC(ExampleController.kt:343)`
+         * this would return `ExampleController#makeBlockingBinderIPC()`
+         */
+        private fun getSimpleCallRef(stackFrame: StackTraceElement?): String =
+            if (stackFrame != null) "${getSimpleClassName(stackFrame)}#${stackFrame.methodName}"
+            else UNKNOWN
+
+        /**
+         * Returns a short string for a [StackTraceElement] including just its class name without
+         * any package name. For example, if the stack frame is
+         * `com.android.systemui.ExampleController.makeBlockingBinderIPC(ExampleController.kt:343)`
+         * this would return `ExampleController`
+         */
+        private fun getSimpleClassName(stackFrame: StackTraceElement): String =
+            try {
+                with(Class.forName(stackFrame.className)) {
+                    canonicalName?.substring(packageName.length + 1)
+                }
+            } finally {} ?: stackFrame.className
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java
index c72853e..7b652c1 100644
--- a/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java
@@ -29,18 +29,28 @@
 import com.android.systemui.dagger.qualifiers.LongRunning;
 import com.android.systemui.dagger.qualifiers.Main;
 
+import dagger.Module;
+import dagger.Provides;
+
 import java.util.concurrent.Executor;
 
 import javax.inject.Named;
 
-import dagger.Module;
-import dagger.Provides;
-
 /**
  * Dagger Module for classes found within the concurrent package.
  */
 @Module
 public abstract class SysUIConcurrencyModule {
+
+    // Slow BG executor can potentially affect UI if UI is waiting for an updated state from this
+    // thread
+    private static final Long BG_SLOW_DISPATCH_THRESHOLD = 1000L;
+    private static final Long BG_SLOW_DELIVERY_THRESHOLD = 1000L;
+    private static final Long LONG_SLOW_DISPATCH_THRESHOLD = 2500L;
+    private static final Long LONG_SLOW_DELIVERY_THRESHOLD = 2500L;
+    private static final Long BROADCAST_SLOW_DISPATCH_THRESHOLD = 1000L;
+    private static final Long BROADCAST_SLOW_DELIVERY_THRESHOLD = 1000L;
+
     /** Background Looper */
     @Provides
     @SysUISingleton
@@ -49,6 +59,8 @@
         HandlerThread thread = new HandlerThread("SysUiBg",
                 Process.THREAD_PRIORITY_BACKGROUND);
         thread.start();
+        thread.getLooper().setSlowLogThresholdMs(BG_SLOW_DISPATCH_THRESHOLD,
+                BG_SLOW_DELIVERY_THRESHOLD);
         return thread.getLooper();
     }
 
@@ -60,6 +72,8 @@
         HandlerThread thread = new HandlerThread("BroadcastRunning",
                 Process.THREAD_PRIORITY_BACKGROUND);
         thread.start();
+        thread.getLooper().setSlowLogThresholdMs(BROADCAST_SLOW_DISPATCH_THRESHOLD,
+                BROADCAST_SLOW_DELIVERY_THRESHOLD);
         return thread.getLooper();
     }
 
@@ -71,6 +85,8 @@
         HandlerThread thread = new HandlerThread("SysUiLng",
                 Process.THREAD_PRIORITY_BACKGROUND);
         thread.start();
+        thread.getLooper().setSlowLogThresholdMs(LONG_SLOW_DISPATCH_THRESHOLD,
+                LONG_SLOW_DELIVERY_THRESHOLD);
         return thread.getLooper();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/utils/GlobalWindowManager.kt b/packages/SystemUI/src/com/android/systemui/utils/GlobalWindowManager.kt
new file mode 100644
index 0000000..4111850
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/utils/GlobalWindowManager.kt
@@ -0,0 +1,22 @@
+package com.android.systemui.utils
+
+import android.graphics.HardwareRenderer.CacheTrimLevel
+import android.view.WindowManagerGlobal
+import javax.inject.Inject
+
+/** Interface to talk to [WindowManagerGlobal] */
+class GlobalWindowManager @Inject constructor() {
+    /**
+     * Sends a trim memory command to [WindowManagerGlobal].
+     *
+     * @param level One of levels from [ComponentCallbacks2] starting with TRIM_
+     */
+    fun trimMemory(level: Int) {
+        WindowManagerGlobal.getInstance().trimMemory(level)
+    }
+
+    /** Sends a trim caches command to [WindowManagerGlobal]. */
+    fun trimCaches(@CacheTrimLevel level: Int) {
+        WindowManagerGlobal.getInstance().trimCaches(level)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 5ba02fa..b24a692 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -73,7 +73,6 @@
 import android.os.SystemClock;
 import android.os.Trace;
 import android.os.VibrationEffect;
-import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.provider.Settings.Global;
 import android.text.InputFilter;
@@ -113,7 +112,6 @@
 import com.android.app.animation.Interpolators;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.graphics.drawable.BackgroundBlurDrawable;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.view.RotationPolicy;
@@ -133,15 +131,11 @@
 import com.android.systemui.statusbar.policy.DevicePostureController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.util.AlphaTintDrawableWrapper;
-import com.android.systemui.util.DeviceConfigProxy;
 import com.android.systemui.util.RoundedCornerProgressDrawable;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
 /**
@@ -198,9 +192,6 @@
     private ViewGroup mDialogRowsView;
     private ViewGroup mRinger;
 
-    private DeviceConfigProxy mDeviceConfigProxy;
-    private Executor mExecutor;
-
     /**
      * Container for the top part of the dialog, which contains the ringer, the ringer drawer, the
      * volume rows, and the ellipsis button. This does not include the live caption button.
@@ -290,14 +281,12 @@
     private BackgroundBlurDrawable mDialogRowsViewBackground;
     private final InteractionJankMonitor mInteractionJankMonitor;
 
-    private boolean mSeparateNotification;
-
     private int mWindowGravity;
 
     @VisibleForTesting
-    int mVolumeRingerIconDrawableId;
+    final int mVolumeRingerIconDrawableId = R.drawable.ic_speaker_on;
     @VisibleForTesting
-    int mVolumeRingerMuteIconDrawableId;
+    final int mVolumeRingerMuteIconDrawableId = R.drawable.ic_speaker_mute;
 
     private int mOriginalGravity;
     private final DevicePostureController.Callback mDevicePostureControllerCallback;
@@ -315,8 +304,6 @@
             VolumePanelFactory volumePanelFactory,
             ActivityStarter activityStarter,
             InteractionJankMonitor interactionJankMonitor,
-            DeviceConfigProxy deviceConfigProxy,
-            Executor executor,
             CsdWarningDialog.Factory csdWarningDialogFactory,
             DevicePostureController devicePostureController,
             Looper looper,
@@ -374,12 +361,6 @@
         } else {
             mDevicePostureControllerCallback = null;
         }
-
-        mDeviceConfigProxy = deviceConfigProxy;
-        mExecutor = executor;
-        mSeparateNotification = mDeviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, false);
-        updateRingerModeIconSet();
     }
 
     /**
@@ -401,44 +382,6 @@
         return mWindowGravity;
     }
 
-    /**
-     * If ringer and notification are the same stream (T and earlier), use notification-like bell
-     * icon set.
-     * If ringer and notification are separated, then use generic speaker icons.
-     */
-    private void updateRingerModeIconSet() {
-        if (mSeparateNotification) {
-            mVolumeRingerIconDrawableId = R.drawable.ic_speaker_on;
-            mVolumeRingerMuteIconDrawableId = R.drawable.ic_speaker_mute;
-        } else {
-            mVolumeRingerIconDrawableId = R.drawable.ic_volume_ringer;
-            mVolumeRingerMuteIconDrawableId = R.drawable.ic_volume_ringer_mute;
-        }
-
-        if (mRingerDrawerMuteIcon != null) {
-            mRingerDrawerMuteIcon.setImageResource(mVolumeRingerMuteIconDrawableId);
-        }
-        if (mRingerDrawerNormalIcon != null) {
-            mRingerDrawerNormalIcon.setImageResource(mVolumeRingerIconDrawableId);
-        }
-    }
-
-    /**
-     * Change icon for ring stream (not ringer mode icon)
-     */
-    private void updateRingRowIcon() {
-        Optional<VolumeRow> volumeRow = mRows.stream().filter(row -> row.stream == STREAM_RING)
-                .findFirst();
-        if (volumeRow.isPresent()) {
-            VolumeRow volRow = volumeRow.get();
-            volRow.iconRes = mSeparateNotification ? R.drawable.ic_ring_volume
-                    : R.drawable.ic_volume_ringer;
-            volRow.iconMuteRes = mSeparateNotification ? R.drawable.ic_ring_volume_off
-                    : R.drawable.ic_volume_ringer_mute;
-            volRow.setIcon(volRow.iconRes, mContext.getTheme());
-        }
-    }
-
     @Override
     public void onUiModeChanged() {
         mContext.getTheme().applyStyle(mContext.getThemeResId(), true);
@@ -454,9 +397,6 @@
 
         mConfigurationController.addCallback(this);
 
-        mDeviceConfigProxy.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
-                mExecutor, this::onDeviceConfigChange);
-
         if (mDevicePostureController != null) {
             mDevicePostureController.addCallback(mDevicePostureControllerCallback);
         }
@@ -464,31 +404,15 @@
 
     @Override
     public void destroy() {
+        Log.d(TAG, "destroy() called");
         mController.removeCallback(mControllerCallbackH);
         mHandler.removeCallbacksAndMessages(null);
         mConfigurationController.removeCallback(this);
-        mDeviceConfigProxy.removeOnPropertiesChangedListener(this::onDeviceConfigChange);
         if (mDevicePostureController != null) {
             mDevicePostureController.removeCallback(mDevicePostureControllerCallback);
         }
     }
 
-    /**
-     * Update ringer mode icon based on the config
-     */
-    private void onDeviceConfigChange(DeviceConfig.Properties properties) {
-        Set<String> changeSet = properties.getKeyset();
-        if (changeSet.contains(SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION)) {
-            boolean newVal = properties.getBoolean(
-                    SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, false);
-            if (newVal != mSeparateNotification) {
-                mSeparateNotification = newVal;
-                updateRingerModeIconSet();
-                updateRingRowIcon();
-            }
-        }
-    }
-
     @Override
     public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo internalInsetsInfo) {
         // Set touchable region insets on the root dialog view. This tells WindowManager that
@@ -542,6 +466,7 @@
     }
 
     private void initDialog(int lockTaskModeState) {
+        Log.d(TAG, "initDialog: called!");
         mDialog = new CustomDialog(mContext);
         initDimens();
 
@@ -699,7 +624,12 @@
         mRingerDrawerNormalIcon = mDialog.findViewById(R.id.volume_drawer_normal_icon);
         mRingerDrawerNewSelectionBg = mDialog.findViewById(R.id.volume_drawer_selection_background);
 
-        updateRingerModeIconSet();
+        if (mRingerDrawerMuteIcon != null) {
+            mRingerDrawerMuteIcon.setImageResource(mVolumeRingerMuteIconDrawableId);
+        }
+        if (mRingerDrawerNormalIcon != null) {
+            mRingerDrawerNormalIcon.setImageResource(mVolumeRingerIconDrawableId);
+        }
 
         setupRingerDrawer();
 
@@ -724,13 +654,10 @@
             addRow(AudioManager.STREAM_MUSIC,
                     R.drawable.ic_volume_media, R.drawable.ic_volume_media_mute, true, true);
             if (!AudioSystem.isSingleVolume(mContext)) {
-                if (mSeparateNotification) {
-                    addRow(AudioManager.STREAM_RING, R.drawable.ic_ring_volume,
-                            R.drawable.ic_ring_volume_off, true, false);
-                } else {
-                    addRow(AudioManager.STREAM_RING, R.drawable.ic_volume_ringer,
-                            R.drawable.ic_volume_ringer, true, false);
-                }
+
+                addRow(AudioManager.STREAM_RING, R.drawable.ic_ring_volume,
+                        R.drawable.ic_ring_volume_off, true, false);
+
 
                 addRow(STREAM_ALARM,
                         R.drawable.ic_alarm, R.drawable.ic_volume_alarm_mute, true, false);
@@ -1344,7 +1271,7 @@
     }
 
     protected void tryToRemoveCaptionsTooltip() {
-        if (mHasSeenODICaptionsTooltip && mODICaptionsTooltipView != null) {
+        if (mHasSeenODICaptionsTooltip && mODICaptionsTooltipView != null && mDialog != null) {
             ViewGroup container = mDialog.findViewById(R.id.volume_dialog_container);
             container.removeView(mODICaptionsTooltipView);
             mODICaptionsTooltipView = null;
@@ -1551,8 +1478,16 @@
 
         mHandler.removeMessages(H.DISMISS);
         mHandler.removeMessages(H.SHOW);
-        if (mIsAnimatingDismiss) {
-            Log.d(TAG, "dismissH: isAnimatingDismiss");
+
+        boolean showingStateInconsistent = !mShowing && mDialog != null && mDialog.isShowing();
+        // If incorrectly assuming dialog is not showing, continue and make the state consistent.
+        if (showingStateInconsistent) {
+            Log.d(TAG, "dismissH: volume dialog possible in inconsistent state:"
+                    + "mShowing=" + mShowing + ", mDialog==null?" + (mDialog == null));
+        }
+        if (mIsAnimatingDismiss && !showingStateInconsistent) {
+            Log.d(TAG, "dismissH: skipping dismiss because isAnimatingDismiss is true"
+                    + " and showingStateInconsistent is false");
             Trace.endSection();
             return;
         }
@@ -1570,8 +1505,12 @@
                 .setDuration(mDialogHideAnimationDurationMs)
                 .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
                 .withEndAction(() -> mHandler.postDelayed(() -> {
-                    mController.notifyVisible(false);
-                    mDialog.dismiss();
+                    if (mController != null) {
+                        mController.notifyVisible(false);
+                    }
+                    if (mDialog != null) {
+                        mDialog.dismiss();
+                    }
                     tryToRemoveCaptionsTooltip();
                     mIsAnimatingDismiss = false;
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
index bb04f82..aa4ee54 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
@@ -21,7 +21,6 @@
 import android.os.Looper;
 
 import com.android.internal.jank.InteractionJankMonitor;
-import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.media.dialog.MediaOutputDialogFactory;
 import com.android.systemui.plugins.ActivityStarter;
@@ -31,7 +30,6 @@
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DevicePostureController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.util.DeviceConfigProxy;
 import com.android.systemui.volume.CsdWarningDialog;
 import com.android.systemui.volume.VolumeComponent;
 import com.android.systemui.volume.VolumeDialogComponent;
@@ -42,8 +40,6 @@
 import dagger.Module;
 import dagger.Provides;
 
-import java.util.concurrent.Executor;
-
 /** Dagger Module for code in the volume package. */
 @Module
 public interface VolumeModule {
@@ -63,8 +59,6 @@
             VolumePanelFactory volumePanelFactory,
             ActivityStarter activityStarter,
             InteractionJankMonitor interactionJankMonitor,
-            DeviceConfigProxy deviceConfigProxy,
-            @Main Executor executor,
             CsdWarningDialog.Factory csdFactory,
             DevicePostureController devicePostureController,
             DumpManager dumpManager) {
@@ -78,8 +72,6 @@
                 volumePanelFactory,
                 activityStarter,
                 interactionJankMonitor,
-                deviceConfigProxy,
-                executor,
                 csdFactory,
                 devicePostureController,
                 Looper.getMainLooper(),
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
index 5557efa..48a8d1b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
@@ -21,6 +21,8 @@
 import static android.telephony.SubscriptionManager.DATA_ROAMING_ENABLE;
 import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static junit.framework.Assert.assertTrue;
@@ -30,13 +32,18 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.provider.Settings;
 import android.telephony.ServiceState;
@@ -47,8 +54,10 @@
 import android.testing.AndroidTestingRunner;
 import android.text.TextUtils;
 
+import com.android.keyguard.logging.CarrierTextManagerLogger;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dump.LogBufferHelperKt;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository;
 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel;
@@ -110,6 +119,10 @@
 
     private CarrierTextManager mCarrierTextManager;
 
+    private CarrierTextManagerLogger mLogger =
+            new CarrierTextManagerLogger(
+                    LogBufferHelperKt.logcatLogBuffer("CarrierTextManagerLog"));
+
     private Void checkMainThread(InvocationOnMock inv) {
         assertThat(mMainExecutor.isExecuting()).isTrue();
         assertThat(mBgExecutor.isExecuting()).isFalse();
@@ -144,7 +157,7 @@
         mCarrierTextManager = new CarrierTextManager.Builder(
                 mContext, mContext.getResources(), mWifiRepository,
                 mTelephonyManager, mTelephonyListenerManager, mWakefulnessLifecycle, mMainExecutor,
-                mBgExecutor, mKeyguardUpdateMonitor)
+                mBgExecutor, mKeyguardUpdateMonitor, mLogger)
                 .setShowAirplaneMode(true)
                 .setShowMissingSim(true)
                 .build();
@@ -183,6 +196,47 @@
         assertEquals(AIRPLANE_MODE_TEXT, captor.getValue().carrierText);
     }
 
+    /** regression test for b/281706473, caused by sending NULL plmn / spn to the logger */
+    @Test
+    public void testAirplaneMode_noSim_nullPlmn_nullSpn_doesNotCrash() {
+        // GIVEN - sticy broadcast that returns a null PLMN and null SPN
+        Intent stickyIntent = new Intent(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED);
+        stickyIntent.putExtra(TelephonyManager.EXTRA_SHOW_PLMN, true);
+        stickyIntent.removeExtra(TelephonyManager.EXTRA_PLMN);
+        stickyIntent.putExtra(TelephonyManager.EXTRA_SHOW_SPN, true);
+        stickyIntent.removeExtra(TelephonyManager.EXTRA_SPN);
+
+        mCarrierTextManager = new CarrierTextManager.Builder(
+                getContextSpyForStickyBroadcast(stickyIntent),
+                mContext.getResources(),
+                mWifiRepository,
+                mTelephonyManager,
+                mTelephonyListenerManager,
+                mWakefulnessLifecycle,
+                mMainExecutor,
+                mBgExecutor,
+                mKeyguardUpdateMonitor,
+                mLogger
+        )
+                .setShowAirplaneMode(true)
+                .setShowMissingSim(true)
+                .build();
+
+        // GIVEN - airplane mode is off (causing CTM to fetch the sticky broadcast)
+        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
+        reset(mCarrierTextCallback);
+        List<SubscriptionInfo> list = new ArrayList<>();
+        when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo()).thenReturn(list);
+        when(mKeyguardUpdateMonitor.getSimState(0))
+                .thenReturn(TelephonyManager.SIM_STATE_NOT_READY);
+        mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
+
+        // WHEN CTM fetches the broadcast and attempts to log the result, no crash results
+        mCarrierTextManager.updateCarrierText();
+
+        // No assert, this test should not crash
+    }
+
     @Test
     public void testCardIOError() {
         reset(mCarrierTextCallback);
@@ -506,4 +560,10 @@
         assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER,
                 captor.getValue().carrierText);
     }
+
+    private Context getContextSpyForStickyBroadcast(Intent returnVal) {
+        Context contextSpy = spy(mContext);
+        doReturn(returnVal).when(contextSpy).registerReceiver(eq(null), any(IntentFilter.class));
+        return contextSpy;
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
index 1ba9931..ae3a320 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
@@ -40,6 +40,8 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.classifier.FalsingCollectorFake;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.Flags;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -77,6 +79,7 @@
     @Mock
     private EmergencyButtonController mEmergencyButtonController;
 
+    private FakeFeatureFlags mFeatureFlags;
     private KeyguardAbsKeyInputViewController mKeyguardAbsKeyInputViewController;
 
     @Before
@@ -90,10 +93,18 @@
         when(mAbsKeyInputView.requireViewById(R.id.bouncer_message_area))
                 .thenReturn(mKeyguardMessageArea);
         when(mAbsKeyInputView.getResources()).thenReturn(getContext().getResources());
-        mKeyguardAbsKeyInputViewController = new KeyguardAbsKeyInputViewController(mAbsKeyInputView,
+        mFeatureFlags = new FakeFeatureFlags();
+        mFeatureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, false);
+        mKeyguardAbsKeyInputViewController = createTestObject();
+        mKeyguardAbsKeyInputViewController.init();
+        reset(mKeyguardMessageAreaController);  // Clear out implicit call to init.
+    }
+
+    private KeyguardAbsKeyInputViewController createTestObject() {
+        return new KeyguardAbsKeyInputViewController(mAbsKeyInputView,
                 mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
                 mKeyguardMessageAreaControllerFactory, mLatencyTracker, mFalsingCollector,
-                mEmergencyButtonController) {
+                mEmergencyButtonController, mFeatureFlags) {
             @Override
             void resetState() {
             }
@@ -108,8 +119,16 @@
                 return 0;
             }
         };
-        mKeyguardAbsKeyInputViewController.init();
-        reset(mKeyguardMessageAreaController);  // Clear out implicit call to init.
+    }
+
+    @Test
+    public void withFeatureFlagOn_oldMessage_isHidden() {
+        mFeatureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true);
+        KeyguardAbsKeyInputViewController underTest = createTestObject();
+
+        underTest.init();
+
+        verify(mKeyguardMessageAreaController).disable();
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index d8e2a38..b21cc6d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -134,7 +134,6 @@
 
     private KeyguardClockSwitchController mController;
     private View mSliceView;
-    private LinearLayout mStatusArea;
     private FakeExecutor mExecutor;
 
     @Before
@@ -151,6 +150,8 @@
                 .thenReturn(100);
         when(mResources.getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin))
                 .thenReturn(-200);
+        when(mResources.getInteger(R.integer.keyguard_date_weather_view_invisibility))
+                .thenReturn(View.INVISIBLE);
 
         when(mView.findViewById(R.id.lockscreen_clock_view_large)).thenReturn(mLargeClockFrame);
         when(mView.findViewById(R.id.lockscreen_clock_view)).thenReturn(mSmallClockFrame);
@@ -196,8 +197,8 @@
 
         mSliceView = new View(getContext());
         when(mView.findViewById(R.id.keyguard_slice_view)).thenReturn(mSliceView);
-        mStatusArea = new LinearLayout(getContext());
-        when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(mStatusArea);
+        when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(
+                new LinearLayout(getContext()));
     }
 
     @Test
@@ -402,15 +403,6 @@
         assertNull(mController.getClock());
     }
 
-    @Test
-    public void testSetAlpha_setClockAlphaForCLockFace() {
-        mController.onViewAttached();
-        mController.setAlpha(0.5f);
-        verify(mLargeClockView).setAlpha(0.5f);
-        verify(mSmallClockView).setAlpha(0.5f);
-        assertEquals(0.5f, mStatusArea.getAlpha(), 0.0f);
-    }
-
     private void verifyAttachment(VerificationMode times) {
         verify(mClockRegistry, times).registerClockChangeListener(
                 any(ClockRegistry.ClockChangeListener.class));
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java
index 30e3d09..b349696 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.hardware.display.DisplayManagerGlobal;
 import android.testing.AndroidTestingRunner;
@@ -38,6 +39,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.navigationbar.NavigationBarController;
 import com.android.systemui.settings.FakeDisplayTracker;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -58,6 +60,10 @@
     private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
     @Mock
     private KeyguardDisplayManager.KeyguardPresentation mKeyguardPresentation;
+    @Mock
+    private KeyguardDisplayManager.DeviceStateHelper mDeviceStateHelper;
+    @Mock
+    private KeyguardStateController mKeyguardStateController;
 
     private Executor mMainExecutor = Runnable::run;
     private Executor mBackgroundExecutor = Runnable::run;
@@ -76,7 +82,7 @@
         MockitoAnnotations.initMocks(this);
         mManager = spy(new KeyguardDisplayManager(mContext, () -> mNavigationBarController,
                 mKeyguardStatusViewComponentFactory, mDisplayTracker, mMainExecutor,
-                mBackgroundExecutor));
+                mBackgroundExecutor, mDeviceStateHelper, mKeyguardStateController));
         doReturn(mKeyguardPresentation).when(mManager).createPresentation(any());
 
         mDefaultDisplay = new Display(DisplayManagerGlobal.getInstance(), Display.DEFAULT_DISPLAY,
@@ -123,4 +129,13 @@
         mManager.show();
         verify(mManager, times(1)).createPresentation(eq(mSecondaryDisplay));
     }
+
+    @Test
+    public void testShow_concurrentDisplayActive_occluded() {
+        mDisplayTracker.setAllDisplays(new Display[]{mDefaultDisplay, mSecondaryDisplay});
+
+        when(mDeviceStateHelper.isConcurrentDisplayActive(mSecondaryDisplay)).thenReturn(true);
+        when(mKeyguardStateController.isOccluded()).thenReturn(true);
+        verify(mManager, never()).createPresentation(eq(mSecondaryDisplay));
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
index a35e5b5..d4522d0 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
@@ -27,6 +27,8 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.text.Editable;
+import android.text.TextWatcher;
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -93,16 +95,16 @@
     }
 
     @Test
-    public void testSetMessage_AnnounceForAccessibility() {
-        ArgumentCaptor<Runnable> argumentCaptor = ArgumentCaptor.forClass(Runnable.class);
-        when(mKeyguardMessageArea.getText()).thenReturn("abc");
-        mMessageAreaController.setMessage("abc");
+    public void textChanged_AnnounceForAccessibility() {
+        ArgumentCaptor<TextWatcher> textWatcherArgumentCaptor = ArgumentCaptor.forClass(
+                TextWatcher.class);
+        mMessageAreaController.onViewAttached();
+        verify(mKeyguardMessageArea).addTextChangedListener(textWatcherArgumentCaptor.capture());
 
-        verify(mKeyguardMessageArea).setMessage("abc", /* animate= */ true);
+        textWatcherArgumentCaptor.getValue().afterTextChanged(
+                Editable.Factory.getInstance().newEditable("abc"));
         verify(mKeyguardMessageArea).removeCallbacks(any(Runnable.class));
-        verify(mKeyguardMessageArea).postDelayed(argumentCaptor.capture(), anyLong());
-        argumentCaptor.getValue().run();
-        verify(mKeyguardMessageArea).announceForAccessibility("abc");
+        verify(mKeyguardMessageArea).postDelayed(any(Runnable.class), anyLong());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
index 082c8cc..1a9260c 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
@@ -26,6 +26,8 @@
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.util.concurrency.DelayableExecutor
 import org.junit.Before
 import org.junit.Test
@@ -76,6 +78,8 @@
     Mockito.`when`(keyguardPasswordView.findViewById<EditText>(R.id.passwordEntry))
         .thenReturn(passwordEntry)
     `when`(keyguardPasswordView.resources).thenReturn(context.resources)
+    val fakeFeatureFlags = FakeFeatureFlags()
+    fakeFeatureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true)
     keyguardPasswordViewController =
         KeyguardPasswordViewController(
             keyguardPasswordView,
@@ -90,7 +94,8 @@
             mainExecutor,
             mContext.resources,
             falsingCollector,
-            keyguardViewController)
+            keyguardViewController,
+            fakeFeatureFlags)
   }
 
   @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
index a8d5569..71a57c7 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
@@ -26,6 +26,8 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.classifier.FalsingCollectorFake
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.statusbar.policy.DevicePostureController
 import org.junit.Before
 import org.junit.Test
@@ -72,6 +74,7 @@
   @Mock private lateinit var mPostureController: DevicePostureController
 
   private lateinit var mKeyguardPatternViewController: KeyguardPatternViewController
+  private lateinit var fakeFeatureFlags: FakeFeatureFlags
 
   @Before
   fun setup() {
@@ -86,6 +89,8 @@
     `when`(mKeyguardMessageAreaControllerFactory.create(mKeyguardMessageArea))
         .thenReturn(mKeyguardMessageAreaController)
     `when`(mKeyguardPatternView.resources).thenReturn(context.resources)
+    fakeFeatureFlags = FakeFeatureFlags()
+    fakeFeatureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, false)
     mKeyguardPatternViewController =
         KeyguardPatternViewController(
             mKeyguardPatternView,
@@ -97,7 +102,17 @@
             mFalsingCollector,
             mEmergencyButtonController,
             mKeyguardMessageAreaControllerFactory,
-            mPostureController)
+            mPostureController,
+            fakeFeatureFlags)
+  }
+
+  @Test
+  fun withFeatureFlagOn_oldMessage_isHidden() {
+    fakeFeatureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true)
+
+    mKeyguardPatternViewController.init()
+
+    verify<KeyguardMessageAreaController<*>>(mKeyguardMessageAreaController).disable()
   }
 
   @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
index 0881e61..cf86c21 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
@@ -36,6 +36,8 @@
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.classifier.FalsingCollectorFake;
 import com.android.systemui.classifier.SingleTapClassifier;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.Flags;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -98,10 +100,13 @@
                 .thenReturn(mDeleteButton);
         when(mPinBasedInputView.findViewById(R.id.key_enter))
                 .thenReturn(mOkButton);
+        FakeFeatureFlags featureFlags = new FakeFeatureFlags();
+        featureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true);
+
         mKeyguardPinViewController = new KeyguardPinBasedInputViewController(mPinBasedInputView,
                 mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
                 mKeyguardMessageAreaControllerFactory, mLatencyTracker, mLiftToactivateListener,
-                mEmergencyButtonController, mFalsingCollector) {
+                mEmergencyButtonController, mFalsingCollector, featureFlags) {
             @Override
             public void onResume(int reason) {
                 super.onResume(reason);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
index 70476aa..d3b4190 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
@@ -152,9 +152,15 @@
         `when`(passwordTextView.text).thenReturn("")
 
         pinViewController.startAppearAnimation()
-        verify(deleteButton).visibility = View.INVISIBLE
+        verify(deleteButton).visibility = View.VISIBLE
         verify(enterButton).visibility = View.VISIBLE
         verify(passwordTextView).setUsePinShapes(true)
-        verify(passwordTextView).setIsPinHinting(true)
+        verify(passwordTextView).setIsPinHinting(false)
+    }
+
+    @Test
+    fun handleLockout_readsNumberOfErrorAttempts() {
+        pinViewController.handleAttemptLockout(0)
+        verify(lockPatternUtils).getCurrentFailedPasswordAttempts(anyInt())
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index 65ddb53..d2e5a45 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -18,6 +18,7 @@
 
 import static com.android.keyguard.KeyguardSecurityContainer.MODE_DEFAULT;
 import static com.android.keyguard.KeyguardSecurityContainer.MODE_ONE_HANDED;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -63,7 +64,9 @@
 import com.android.systemui.biometrics.SideFpsUiRequestSource;
 import com.android.systemui.classifier.FalsingA11yDelegate;
 import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.flags.FakeFeatureFlags;
 import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor;
 import com.android.systemui.log.SessionTracker;
 import com.android.systemui.plugins.ActivityStarter;
@@ -195,11 +198,15 @@
         when(mKeyguardPasswordView.getWindowInsetsController()).thenReturn(mWindowInsetsController);
         when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(SecurityMode.PIN);
         when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true);
+        FakeFeatureFlags featureFlags = new FakeFeatureFlags();
+        featureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true);
+
         mKeyguardPasswordViewController = new KeyguardPasswordViewController(
                 (KeyguardPasswordView) mKeyguardPasswordView, mKeyguardUpdateMonitor,
                 SecurityMode.Password, mLockPatternUtils, null,
                 mKeyguardMessageAreaControllerFactory, null, null, mEmergencyButtonController,
-                null, mock(Resources.class), null, mKeyguardViewController);
+                null, mock(Resources.class), null, mKeyguardViewController,
+                featureFlags);
 
         mKeyguardSecurityContainerController = new KeyguardSecurityContainerController(
                 mView, mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
@@ -685,6 +692,14 @@
         verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
     }
 
+    @Test
+    public void setExpansion_setsAlpha() {
+        mKeyguardSecurityContainerController.setExpansion(EXPANSION_VISIBLE);
+
+        verify(mView).setAlpha(1f);
+        verify(mView).setTranslationY(0f);
+    }
+
     private KeyguardSecurityContainer.SwipeListener getRegisteredSwipeListener() {
         mKeyguardSecurityContainerController.onViewAttached();
         verify(mView).setSwipeListener(mSwipeListenerArgumentCaptor.capture());
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
index eb86c05..a3acc78 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
@@ -27,6 +27,8 @@
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.util.mockito.any
 import org.junit.Before
 import org.junit.Test
@@ -71,6 +73,9 @@
         simPinView =
             LayoutInflater.from(context).inflate(R.layout.keyguard_sim_pin_view, null)
                 as KeyguardSimPinView
+        val fakeFeatureFlags = FakeFeatureFlags()
+        fakeFeatureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true)
+
         underTest =
             KeyguardSimPinViewController(
                 simPinView,
@@ -83,7 +88,8 @@
                 liftToActivateListener,
                 telephonyManager,
                 falsingCollector,
-                emergencyButtonController
+                emergencyButtonController,
+                fakeFeatureFlags,
             )
         underTest.init()
     }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
index 2dcca55..efcf4dd 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
@@ -27,6 +27,8 @@
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.util.mockito.any
 import org.junit.Before
 import org.junit.Test
@@ -70,6 +72,9 @@
         simPukView =
             LayoutInflater.from(context).inflate(R.layout.keyguard_sim_puk_view, null)
                 as KeyguardSimPukView
+        val fakeFeatureFlags = FakeFeatureFlags()
+        fakeFeatureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true)
+
         underTest =
             KeyguardSimPukViewController(
                 simPukView,
@@ -82,7 +87,8 @@
                 liftToActivateListener,
                 telephonyManager,
                 falsingCollector,
-                emergencyButtonController
+                emergencyButtonController,
+                fakeFeatureFlags,
             )
         underTest.init()
     }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java
index 68dc6c0..4d3243a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java
@@ -15,11 +15,13 @@
  */
 package com.android.keyguard;
 
+import static org.junit.Assume.assumeFalse;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.pm.PackageManager;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
@@ -76,12 +78,20 @@
 
     @Test
     public void refresh_replacesSliceContentAndNotifiesListener() {
+        // Skips the test if running on a watch because watches don't have a SliceManager system
+        // service.
+        assumeFalse(isWatch());
+
         mController.refresh();
         verify(mView).hideSlice();
     }
 
     @Test
     public void onAttachedToWindow_registersListeners() {
+        // Skips the test if running on a watch because watches don't have a SliceManager system
+        // service.
+        assumeFalse(isWatch());
+
         mController.init();
         verify(mTunerService).addTunable(any(TunerService.Tunable.class), anyString());
         verify(mConfigurationController).addCallback(
@@ -90,6 +100,10 @@
 
     @Test
     public void onDetachedFromWindow_unregistersListeners() {
+        // Skips the test if running on a watch because watches don't have a SliceManager system
+        // service.
+        assumeFalse(isWatch());
+
         ArgumentCaptor<View.OnAttachStateChangeListener> attachListenerArgumentCaptor =
                 ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
 
@@ -102,4 +116,9 @@
         verify(mConfigurationController).removeCallback(
                 any(ConfigurationController.ConfigurationListener.class));
     }
+
+    private boolean isWatch() {
+        final PackageManager pm = mContext.getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
index a8c281c..f8262d4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
@@ -24,46 +24,33 @@
         get() = keyguardStatusView.findViewById(R.id.status_view_media_container)
     private val statusViewContainer: ViewGroup
         get() = keyguardStatusView.findViewById(R.id.status_view_container)
-    private val clockView: ViewGroup
-        get() = keyguardStatusView.findViewById(R.id.keyguard_clock_container)
     private val childrenExcludingMedia
         get() = statusViewContainer.children.filter { it != mediaView }
 
     @Before
     fun setUp() {
-        keyguardStatusView = LayoutInflater.from(context)
-                .inflate(R.layout.keyguard_status_view, /* root= */ null) as KeyguardStatusView
+        keyguardStatusView =
+            LayoutInflater.from(context).inflate(R.layout.keyguard_status_view, /* root= */ null)
+                as KeyguardStatusView
     }
 
     @Test
     fun setChildrenTranslationYExcludingMediaView_mediaViewIsNotTranslated() {
         val translationY = 1234f
 
-        keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */true)
+        keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */ true)
 
         assertThat(mediaView.translationY).isEqualTo(0)
 
-        childrenExcludingMedia.forEach {
-            assertThat(it.translationY).isEqualTo(translationY)
-        }
+        childrenExcludingMedia.forEach { assertThat(it.translationY).isEqualTo(translationY) }
     }
 
     @Test
     fun setChildrenTranslationYIncludeMediaView() {
         val translationY = 1234f
 
-        keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */false)
+        keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */ false)
 
-        statusViewContainer.children.forEach {
-            assertThat(it.translationY).isEqualTo(translationY)
-        }
-    }
-
-    @Test
-    fun setAlphaExcludeClock() {
-        keyguardStatusView.setAlpha(0.5f, /* excludeClock= */true)
-        assertThat(statusViewContainer.alpha).isNotEqualTo(0.5f)
-        assertThat(mediaView.alpha).isEqualTo(0.5f)
-        assertThat(clockView.alpha).isNotEqualTo(0.5f)
+        statusViewContainer.children.forEach { assertThat(it.translationY).isEqualTo(translationY) }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index d867df5..2f72cb9 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -3088,7 +3088,8 @@
 
     private Intent getBatteryIntent() {
         return new Intent(Intent.ACTION_BATTERY_CHANGED).putExtra(
-                BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_OVERHEAT);
+                BatteryManager.EXTRA_CHARGING_STATUS,
+                BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE);
     }
 
     private class TestableKeyguardUpdateMonitor extends KeyguardUpdateMonitor {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt
deleted file mode 100644
index babbe45..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt
+++ /dev/null
@@ -1,215 +0,0 @@
-package com.android.systemui
-
-import android.content.ComponentName
-import android.content.Context
-import android.content.pm.PackageManager
-import android.content.pm.UserInfo
-import android.content.res.Resources
-import android.testing.AndroidTestingRunner
-import androidx.test.filters.SmallTest
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flag
-import com.android.systemui.flags.FlagListenable
-import com.android.systemui.flags.Flags
-import com.android.systemui.flags.ReleasedFlag
-import com.android.systemui.flags.UnreleasedFlag
-import com.android.systemui.settings.UserTracker
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.kotlinArgumentCaptor
-import com.android.systemui.util.mockito.whenever
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.cancel
-import kotlinx.coroutines.test.TestCoroutineDispatcher
-import org.junit.After
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.anyInt
-import org.mockito.Mockito.clearInvocations
-import org.mockito.Mockito.never
-import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.MockitoAnnotations
-
-@OptIn(ExperimentalCoroutinesApi::class)
-@RunWith(AndroidTestingRunner::class)
-@SmallTest
-class ChooserSelectorTest : SysuiTestCase() {
-
-    private val flagListener = kotlinArgumentCaptor<FlagListenable.Listener>()
-
-    private val testDispatcher = TestCoroutineDispatcher()
-    private val testScope = CoroutineScope(testDispatcher)
-
-    private lateinit var chooserSelector: ChooserSelector
-
-    @Mock private lateinit var mockContext: Context
-    @Mock private lateinit var mockProfileContext: Context
-    @Mock private lateinit var mockUserTracker: UserTracker
-    @Mock private lateinit var mockPackageManager: PackageManager
-    @Mock private lateinit var mockResources: Resources
-    @Mock private lateinit var mockFeatureFlags: FeatureFlags
-
-    @Before
-    fun setup() {
-        MockitoAnnotations.initMocks(this)
-
-        whenever(mockContext.createContextAsUser(any(), anyInt())).thenReturn(mockProfileContext)
-        whenever(mockContext.resources).thenReturn(mockResources)
-        whenever(mockProfileContext.packageManager).thenReturn(mockPackageManager)
-        whenever(mockResources.getString(anyInt())).thenReturn(
-                ComponentName("TestPackage", "TestClass").flattenToString())
-        whenever(mockUserTracker.userProfiles).thenReturn(listOf(UserInfo(), UserInfo()))
-
-        chooserSelector = ChooserSelector(
-                mockContext,
-                mockUserTracker,
-                mockFeatureFlags,
-                testScope,
-                testDispatcher,
-        )
-    }
-
-    @After
-    fun tearDown() {
-        testDispatcher.cleanupTestCoroutines()
-    }
-
-    @Test
-    fun initialize_registersFlagListenerUntilScopeCancelled() {
-        // Arrange
-
-        // Act
-        chooserSelector.start()
-
-        // Assert
-        verify(mockFeatureFlags).addListener(
-                eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED),
-                flagListener.capture(),
-        )
-        verify(mockFeatureFlags, never()).removeListener(any())
-
-        // Act
-        testScope.cancel()
-
-        // Assert
-        verify(mockFeatureFlags).removeListener(eq(flagListener.value))
-    }
-
-    @Test
-    fun initialize_enablesUnbundledChooser_whenFlagEnabled() {
-        // Arrange
-        setFlagMock(true)
-
-        // Act
-        chooserSelector.start()
-
-        // Assert
-        verify(mockPackageManager, times(2)).setComponentEnabledSetting(
-                eq(ComponentName("TestPackage", "TestClass")),
-                eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
-                anyInt(),
-        )
-    }
-
-    @Test
-    fun initialize_disablesUnbundledChooser_whenFlagDisabled() {
-        // Arrange
-        setFlagMock(false)
-
-        // Act
-        chooserSelector.start()
-
-        // Assert
-        verify(mockPackageManager, times(2)).setComponentEnabledSetting(
-                eq(ComponentName("TestPackage", "TestClass")),
-                eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED),
-                anyInt(),
-        )
-    }
-
-    @Test
-    fun enablesUnbundledChooser_whenFlagBecomesEnabled() {
-        // Arrange
-        setFlagMock(false)
-        chooserSelector.start()
-        verify(mockFeatureFlags).addListener(
-                eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED),
-                flagListener.capture(),
-        )
-        verify(mockPackageManager, never()).setComponentEnabledSetting(
-                any(),
-                eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
-                anyInt(),
-        )
-
-        // Act
-        setFlagMock(true)
-        flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.name))
-
-        // Assert
-        verify(mockPackageManager, times(2)).setComponentEnabledSetting(
-                eq(ComponentName("TestPackage", "TestClass")),
-                eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
-                anyInt(),
-        )
-    }
-
-    @Test
-    fun disablesUnbundledChooser_whenFlagBecomesDisabled() {
-        // Arrange
-        setFlagMock(true)
-        chooserSelector.start()
-        verify(mockFeatureFlags).addListener(
-                eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED),
-                flagListener.capture(),
-        )
-        verify(mockPackageManager, never()).setComponentEnabledSetting(
-                any(),
-                eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED),
-                anyInt(),
-        )
-
-        // Act
-        setFlagMock(false)
-        flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.name))
-
-        // Assert
-        verify(mockPackageManager, times(2)).setComponentEnabledSetting(
-                eq(ComponentName("TestPackage", "TestClass")),
-                eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED),
-                anyInt(),
-        )
-    }
-
-    @Test
-    fun doesNothing_whenAnotherFlagChanges() {
-        // Arrange
-        setFlagMock(false)
-        chooserSelector.start()
-        verify(mockFeatureFlags).addListener(
-                eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED),
-                flagListener.capture(),
-        )
-        clearInvocations(mockPackageManager)
-
-        // Act
-        flagListener.value.onFlagChanged(TestFlagEvent("other flag"))
-
-        // Assert
-        verifyZeroInteractions(mockPackageManager)
-    }
-
-    private fun setFlagMock(enabled: Boolean) {
-        whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(enabled)
-        whenever(mockFeatureFlags.isEnabled(any<ReleasedFlag>())).thenReturn(enabled)
-    }
-
-    private class TestFlagEvent(override val flagName: String) : FlagListenable.FlagEvent {
-        override fun requestNoRestart() {}
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
index eff8c01..f64db78f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
@@ -80,6 +80,8 @@
     private OverviewProxyService mOverviewProxyService;
     @Mock
     private SecureSettings mSecureSettings;
+    @Mock
+    private AccessibilityLogger mA11yLogger;
 
     private IWindowMagnificationConnection mIWindowMagnificationConnection;
     private WindowMagnification mWindowMagnification;
@@ -97,7 +99,7 @@
         mWindowMagnification = new WindowMagnification(getContext(),
                 getContext().getMainThreadHandler(), mCommandQueue,
                 mModeSwitchesController, mSysUiState, mOverviewProxyService, mSecureSettings,
-                mDisplayTracker, getContext().getSystemService(DisplayManager.class));
+                mDisplayTracker, getContext().getSystemService(DisplayManager.class), mA11yLogger);
         mWindowMagnification.mMagnificationControllerSupplier = new FakeControllerSupplier(
                 mContext.getSystemService(DisplayManager.class));
         mWindowMagnification.mMagnificationSettingsSupplier = new FakeSettingsSupplier(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java
index 30cbc52..665246b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java
@@ -17,7 +17,6 @@
 package com.android.systemui.accessibility;
 
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
-import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
 
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
@@ -74,10 +73,9 @@
 
     @Test
     public void testShowSettingsPanel() {
-        final int mode = ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
-        mMagnificationSettingsController.showMagnificationSettings(mode);
+        mMagnificationSettingsController.showMagnificationSettings();
 
-        verify(mWindowMagnificationSettings).showSettingPanel(eq(mode));
+        verify(mWindowMagnificationSettings).showSettingPanel();
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
index c08b5b4..ce96708 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
@@ -16,7 +16,10 @@
 
 package com.android.systemui.accessibility;
 
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY;
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -24,12 +27,17 @@
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.annotation.IdRes;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
+import android.database.ContentObserver;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -102,7 +110,10 @@
 
     @Test
     public void showSettingPanel_hasAccessibilityWindowTitle() {
-        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        setupMagnificationCapabilityAndMode(
+                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        mWindowMagnificationSettings.showSettingPanel();
 
         final WindowManager.LayoutParams layoutPrams =
                 mWindowManager.getLayoutParamsFromAttachedView();
@@ -114,7 +125,10 @@
 
     @Test
     public void showSettingPanel_windowMode_showEditButtonAndDiagonalView() {
-        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        setupMagnificationCapabilityAndMode(
+                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        mWindowMagnificationSettings.showSettingPanel();
 
         final Button editButton = getInternalView(R.id.magnifier_edit_button);
         assertEquals(editButton.getVisibility(), View.VISIBLE);
@@ -125,7 +139,10 @@
 
     @Test
     public void showSettingPanel_fullScreenMode_hideEditButtonAndDiagonalView() {
-        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+        setupMagnificationCapabilityAndMode(
+                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_ALL,
+                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+        mWindowMagnificationSettings.showSettingPanel();
 
         final Button editButton = getInternalView(R.id.magnifier_edit_button);
         assertEquals(editButton.getVisibility(), View.INVISIBLE);
@@ -135,9 +152,22 @@
     }
 
     @Test
+    public void showSettingPanel_windowOnlyCapability_hideFullscreenButton() {
+        setupMagnificationCapabilityAndMode(
+                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        mWindowMagnificationSettings.showSettingPanel();
+
+        final View fullscreenButton = getInternalView(R.id.magnifier_full_button);
+        assertThat(fullscreenButton.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
     public void performClick_smallSizeButton_changeMagnifierSizeSmallAndSwitchToWindowMode() {
-        // Open view
-        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        setupMagnificationCapabilityAndMode(
+                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        mWindowMagnificationSettings.showSettingPanel();
 
         verifyOnSetMagnifierSizeAndOnModeSwitch(
                 R.id.magnifier_small_button, MAGNIFICATION_SIZE_SMALL);
@@ -145,8 +175,10 @@
 
     @Test
     public void performClick_mediumSizeButton_changeMagnifierSizeMediumAndSwitchToWindowMode() {
-        // Open view
-        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        setupMagnificationCapabilityAndMode(
+                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        mWindowMagnificationSettings.showSettingPanel();
 
         verifyOnSetMagnifierSizeAndOnModeSwitch(
                 R.id.magnifier_medium_button, MAGNIFICATION_SIZE_MEDIUM);
@@ -154,8 +186,10 @@
 
     @Test
     public void performClick_largeSizeButton_changeMagnifierSizeLargeAndSwitchToWindowMode() {
-        // Open view
-        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        setupMagnificationCapabilityAndMode(
+                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        mWindowMagnificationSettings.showSettingPanel();
 
         verifyOnSetMagnifierSizeAndOnModeSwitch(
                 R.id.magnifier_large_button, MAGNIFICATION_SIZE_LARGE);
@@ -178,8 +212,10 @@
         View fullScreenModeButton = getInternalView(R.id.magnifier_full_button);
         getInternalView(R.id.magnifier_panel_view);
 
-        // Open view
-        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        setupMagnificationCapabilityAndMode(
+                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_ALL,
+                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        mWindowMagnificationSettings.showSettingPanel();
 
         // Perform click
         fullScreenModeButton.performClick();
@@ -192,8 +228,10 @@
     public void performClick_editButton_setEditMagnifierSizeMode() {
         View editButton = getInternalView(R.id.magnifier_edit_button);
 
-        // Open view
-        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        setupMagnificationCapabilityAndMode(
+                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        mWindowMagnificationSettings.showSettingPanel();
 
         // Perform click
         editButton.performClick();
@@ -208,8 +246,10 @@
                 getInternalView(R.id.magnifier_horizontal_lock_switch);
         final boolean currentCheckedState = diagonalScrollingSwitch.isChecked();
 
-        // Open view
-        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        setupMagnificationCapabilityAndMode(
+                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
+                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        mWindowMagnificationSettings.showSettingPanel();
 
         // Perform click
         diagonalScrollingSwitch.performClick();
@@ -219,8 +259,10 @@
 
     @Test
     public void onConfigurationChanged_selectedButtonIsStillSelected() {
-        // Open view
-        mWindowMagnificationSettings.showSettingPanel(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        setupMagnificationCapabilityAndMode(
+                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_ALL,
+                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        mWindowMagnificationSettings.showSettingPanel();
         View magnifierMediumButton = getInternalView(R.id.magnifier_medium_button);
         magnifierMediumButton.performClick();
 
@@ -232,9 +274,46 @@
         assertThat(magnifierMediumButton.isSelected()).isTrue();
     }
 
+    @Test
+    public void showSettingsPanel_observerRegistered() {
+        setupMagnificationCapabilityAndMode(
+                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_ALL,
+                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+
+        mWindowMagnificationSettings.showSettingPanel();
+
+        verify(mSecureSettings).registerContentObserverForUser(
+                eq(ACCESSIBILITY_MAGNIFICATION_CAPABILITY),
+                any(ContentObserver.class),
+                eq(UserHandle.USER_CURRENT));
+    }
+
+    @Test
+    public void hideSettingsPanel_observerUnregistered() {
+        setupMagnificationCapabilityAndMode(
+                /* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_ALL,
+                /* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+
+        mWindowMagnificationSettings.showSettingPanel();
+        mWindowMagnificationSettings.hideSettingPanel();
+
+        verify(mSecureSettings).unregisterContentObserver(any(ContentObserver.class));
+    }
+
     private <T extends View> T getInternalView(@IdRes int idRes) {
         T view = mSettingView.findViewById(idRes);
         assertNotNull(view);
         return view;
     }
+
+    private void setupMagnificationCapabilityAndMode(int capability, int mode) {
+        when(mSecureSettings.getIntForUser(
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY,
+                ACCESSIBILITY_MAGNIFICATION_MODE_NONE,
+                UserHandle.USER_CURRENT)).thenReturn(capability);
+        when(mSecureSettings.getIntForUser(
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
+                ACCESSIBILITY_MAGNIFICATION_MODE_NONE,
+                UserHandle.USER_CURRENT)).thenReturn(mode);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
index 239b5bd..38ecec0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
@@ -19,6 +19,7 @@
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
 
+import static com.android.systemui.accessibility.AccessibilityLogger.MagnificationSettingsEvent;
 import static com.android.systemui.accessibility.WindowMagnificationSettings.MagnificationSize;
 import static com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_MAGNIFICATION_OVERLAP;
@@ -89,6 +90,8 @@
     private WindowMagnificationController mWindowMagnificationController;
     @Mock
     private MagnificationSettingsController mMagnificationSettingsController;
+    @Mock
+    private AccessibilityLogger mA11yLogger;
 
     @Before
     public void setUp() throws Exception {
@@ -103,11 +106,22 @@
 
         when(mSysUiState.setFlag(anyInt(), anyBoolean())).thenReturn(mSysUiState);
 
+        doAnswer(invocation -> {
+            mWindowMagnification.mMagnificationSettingsControllerCallback
+                    .onSettingsPanelVisibilityChanged(TEST_DISPLAY, /* shown= */ true);
+            return null;
+        }).when(mMagnificationSettingsController).showMagnificationSettings();
+        doAnswer(invocation -> {
+            mWindowMagnification.mMagnificationSettingsControllerCallback
+                    .onSettingsPanelVisibilityChanged(TEST_DISPLAY, /* shown= */ false);
+            return null;
+        }).when(mMagnificationSettingsController).closeMagnificationSettings();
+
         mCommandQueue = new CommandQueue(getContext(), mDisplayTracker);
         mWindowMagnification = new WindowMagnification(getContext(),
                 getContext().getMainThreadHandler(), mCommandQueue, mModeSwitchesController,
                 mSysUiState, mOverviewProxyService, mSecureSettings, mDisplayTracker,
-                getContext().getSystemService(DisplayManager.class));
+                getContext().getSystemService(DisplayManager.class), mA11yLogger);
         mWindowMagnification.mMagnificationControllerSupplier = new FakeControllerSupplier(
                 mContext.getSystemService(DisplayManager.class), mWindowMagnificationController);
         mWindowMagnification.mMagnificationSettingsSupplier = new FakeSettingsSupplier(
@@ -184,8 +198,9 @@
         mWindowMagnification.mWindowMagnifierCallback.onClickSettingsButton(TEST_DISPLAY);
         waitForIdleSync();
 
-        verify(mMagnificationSettingsController).showMagnificationSettings(
-                eq(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW));
+        verify(mMagnificationSettingsController).showMagnificationSettings();
+        verify(mA11yLogger).log(
+                eq(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_OPENED));
     }
 
     @Test
@@ -196,6 +211,8 @@
         waitForIdleSync();
 
         verify(mWindowMagnificationController).changeMagnificationSize(eq(index));
+        verify(mA11yLogger).log(
+                eq(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_WINDOW_SIZE_SELECTED));
     }
 
     @Test
@@ -215,6 +232,16 @@
         waitForIdleSync();
 
         verify(mWindowMagnificationController).setEditMagnifierSizeMode(eq(true));
+        verify(mA11yLogger).log(
+                eq(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_SIZE_EDITING_ACTIVATED));
+
+        mWindowMagnification.mMagnificationSettingsControllerCallback.onEditMagnifierSizeMode(
+                TEST_DISPLAY, /* enable= */ false);
+        waitForIdleSync();
+        verify(mA11yLogger).log(
+                eq(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_SIZE_EDITING_ACTIVATED));
+        verify(mA11yLogger).log(
+                eq(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_SIZE_EDITING_DEACTIVATED));
     }
 
     @Test
@@ -240,6 +267,8 @@
         waitForIdleSync();
 
         verify(mMagnificationSettingsController).closeMagnificationSettings();
+        verify(mA11yLogger).log(
+                eq(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_CLOSED));
         verify(mConnectionCallback).onChangeMagnificationMode(eq(TEST_DISPLAY),
                 eq(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN));
     }
@@ -269,6 +298,8 @@
         waitForIdleSync();
 
         verify(mWindowMagnificationController).updateDragHandleResourcesIfNeeded(eq(shown));
+        verify(mA11yLogger).log(
+                eq(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_CLOSED));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
index 2e62beb..1990c8f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
@@ -19,9 +19,9 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.data.repository.AuthenticationRepository
-import com.android.systemui.authentication.data.repository.AuthenticationRepositoryImpl
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.scene.SceneTestUtils
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
@@ -37,10 +37,10 @@
 class AuthenticationInteractorTest : SysuiTestCase() {
 
     private val testScope = TestScope()
-    private val repository: AuthenticationRepository = AuthenticationRepositoryImpl()
+    private val utils = SceneTestUtils(this, testScope)
+    private val repository: AuthenticationRepository = utils.authenticationRepository()
     private val underTest =
-        AuthenticationInteractor(
-            applicationScope = testScope.backgroundScope,
+        utils.authenticationInteractor(
             repository = repository,
         )
 
@@ -145,50 +145,59 @@
     @Test
     fun authenticate_withCorrectPin_returnsTrueAndUnlocksDevice() =
         testScope.runTest {
+            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
             val isUnlocked by collectLastValue(underTest.isUnlocked)
             underTest.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
             assertThat(isUnlocked).isFalse()
 
             assertThat(underTest.authenticate(listOf(1, 2, 3, 4))).isTrue()
             assertThat(isUnlocked).isTrue()
+            assertThat(failedAttemptCount).isEqualTo(0)
         }
 
     @Test
     fun authenticate_withIncorrectPin_returnsFalseAndDoesNotUnlockDevice() =
         testScope.runTest {
+            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
             val isUnlocked by collectLastValue(underTest.isUnlocked)
             underTest.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
             assertThat(isUnlocked).isFalse()
 
             assertThat(underTest.authenticate(listOf(9, 8, 7))).isFalse()
             assertThat(isUnlocked).isFalse()
+            assertThat(failedAttemptCount).isEqualTo(1)
         }
 
     @Test
     fun authenticate_withCorrectPassword_returnsTrueAndUnlocksDevice() =
         testScope.runTest {
+            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
             val isUnlocked by collectLastValue(underTest.isUnlocked)
             underTest.setAuthenticationMethod(AuthenticationMethodModel.Password("password"))
             assertThat(isUnlocked).isFalse()
 
             assertThat(underTest.authenticate("password".toList())).isTrue()
             assertThat(isUnlocked).isTrue()
+            assertThat(failedAttemptCount).isEqualTo(0)
         }
 
     @Test
     fun authenticate_withIncorrectPassword_returnsFalseAndDoesNotUnlockDevice() =
         testScope.runTest {
+            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
             val isUnlocked by collectLastValue(underTest.isUnlocked)
             underTest.setAuthenticationMethod(AuthenticationMethodModel.Password("password"))
             assertThat(isUnlocked).isFalse()
 
             assertThat(underTest.authenticate("alohomora".toList())).isFalse()
             assertThat(isUnlocked).isFalse()
+            assertThat(failedAttemptCount).isEqualTo(1)
         }
 
     @Test
     fun authenticate_withCorrectPattern_returnsTrueAndUnlocksDevice() =
         testScope.runTest {
+            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
             val isUnlocked by collectLastValue(underTest.isUnlocked)
             underTest.setAuthenticationMethod(
                 AuthenticationMethodModel.Pattern(
@@ -230,11 +239,13 @@
                 )
                 .isTrue()
             assertThat(isUnlocked).isTrue()
+            assertThat(failedAttemptCount).isEqualTo(0)
         }
 
     @Test
     fun authenticate_withIncorrectPattern_returnsFalseAndDoesNotUnlockDevice() =
         testScope.runTest {
+            val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
             val isUnlocked by collectLastValue(underTest.isUnlocked)
             underTest.setAuthenticationMethod(
                 AuthenticationMethodModel.Pattern(
@@ -276,6 +287,7 @@
                 )
                 .isFalse()
             assertThat(isUnlocked).isFalse()
+            assertThat(failedAttemptCount).isEqualTo(1)
         }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt
index eb7d9c3..c84efac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt
@@ -85,9 +85,9 @@
     }
 
     @Test
-    fun contentDescription_estimateAndOverheated() {
+    fun contentDescription_estimateAndBatteryDefender() {
         mBatteryMeterView.onBatteryLevelChanged(17, false)
-        mBatteryMeterView.onIsOverheatedChanged(true)
+        mBatteryMeterView.onIsBatteryDefenderChanged(true)
         mBatteryMeterView.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE)
         mBatteryMeterView.setBatteryEstimateFetcher(Fetcher())
 
@@ -103,9 +103,9 @@
     }
 
     @Test
-    fun contentDescription_overheated() {
+    fun contentDescription_batteryDefender() {
         mBatteryMeterView.onBatteryLevelChanged(90, false)
-        mBatteryMeterView.onIsOverheatedChanged(true)
+        mBatteryMeterView.onIsBatteryDefenderChanged(true)
 
         assertThat(mBatteryMeterView.contentDescription).isEqualTo(
                 context.getString(R.string.accessibility_battery_level_charging_paused, 90)
@@ -155,14 +155,14 @@
 
     @Test
     fun contentDescription_manyUpdates_alwaysUpdated() {
-        // Overheated
+        // BatteryDefender
         mBatteryMeterView.onBatteryLevelChanged(90, false)
-        mBatteryMeterView.onIsOverheatedChanged(true)
+        mBatteryMeterView.onIsBatteryDefenderChanged(true)
         assertThat(mBatteryMeterView.contentDescription).isEqualTo(
                 context.getString(R.string.accessibility_battery_level_charging_paused, 90)
         )
 
-        // Overheated & estimate
+        // BatteryDefender & estimate
         mBatteryMeterView.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE)
         mBatteryMeterView.setBatteryEstimateFetcher(Fetcher())
         mBatteryMeterView.updatePercentText()
@@ -175,7 +175,7 @@
         )
 
         // Just estimate
-        mBatteryMeterView.onIsOverheatedChanged(false)
+        mBatteryMeterView.onIsBatteryDefenderChanged(false)
         assertThat(mBatteryMeterView.contentDescription).isEqualTo(
                 context.getString(
                         R.string.accessibility_battery_level_with_estimate,
@@ -198,35 +198,35 @@
     }
 
     @Test
-    fun isOverheatedChanged_true_drawableGetsTrue() {
+    fun isBatteryDefenderChanged_true_drawableGetsTrue() {
         mBatteryMeterView.setDisplayShieldEnabled(true)
         val drawable = getBatteryDrawable()
 
-        mBatteryMeterView.onIsOverheatedChanged(true)
+        mBatteryMeterView.onIsBatteryDefenderChanged(true)
 
         assertThat(drawable.displayShield).isTrue()
     }
 
     @Test
-    fun isOverheatedChanged_false_drawableGetsFalse() {
+    fun isBatteryDefenderChanged_false_drawableGetsFalse() {
         mBatteryMeterView.setDisplayShieldEnabled(true)
         val drawable = getBatteryDrawable()
 
         // Start as true
-        mBatteryMeterView.onIsOverheatedChanged(true)
+        mBatteryMeterView.onIsBatteryDefenderChanged(true)
 
         // Update to false
-        mBatteryMeterView.onIsOverheatedChanged(false)
+        mBatteryMeterView.onIsBatteryDefenderChanged(false)
 
         assertThat(drawable.displayShield).isFalse()
     }
 
     @Test
-    fun isOverheatedChanged_true_featureflagOff_drawableGetsFalse() {
+    fun isBatteryDefenderChanged_true_featureflagOff_drawableGetsFalse() {
         mBatteryMeterView.setDisplayShieldEnabled(false)
         val drawable = getBatteryDrawable()
 
-        mBatteryMeterView.onIsOverheatedChanged(true)
+        mBatteryMeterView.onIsBatteryDefenderChanged(true)
 
         assertThat(drawable.displayShield).isFalse()
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
index 213dc87..2d1e8a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
@@ -73,7 +73,7 @@
 
     @Test
     fun fingerprintSuccessDoesNotRequireExplicitConfirmation() {
-        biometricView.onDialogAnimatedIn()
+        biometricView.onDialogAnimatedIn(fingerprintWasStarted = true)
         biometricView.onAuthenticationSucceeded(TYPE_FINGERPRINT)
         TestableLooper.get(this).moveTimeForward(1000)
         waitForIdleSync()
@@ -84,7 +84,7 @@
 
     @Test
     fun faceSuccessRequiresExplicitConfirmation() {
-        biometricView.onDialogAnimatedIn()
+        biometricView.onDialogAnimatedIn(fingerprintWasStarted = true)
         biometricView.onAuthenticationSucceeded(TYPE_FACE)
         waitForIdleSync()
 
@@ -104,7 +104,7 @@
 
     @Test
     fun ignoresFaceErrors_faceIsNotClass3_notLockoutError() {
-        biometricView.onDialogAnimatedIn()
+        biometricView.onDialogAnimatedIn(fingerprintWasStarted = true)
         biometricView.onError(TYPE_FACE, "not a face")
         waitForIdleSync()
 
@@ -121,7 +121,7 @@
     @Test
     fun doNotIgnoresFaceErrors_faceIsClass3_notLockoutError() {
         biometricView.isFaceClass3 = true
-        biometricView.onDialogAnimatedIn()
+        biometricView.onDialogAnimatedIn(fingerprintWasStarted = true)
         biometricView.onError(TYPE_FACE, "not a face")
         waitForIdleSync()
 
@@ -138,7 +138,7 @@
     @Test
     fun doNotIgnoresFaceErrors_faceIsClass3_lockoutError() {
         biometricView.isFaceClass3 = true
-        biometricView.onDialogAnimatedIn()
+        biometricView.onDialogAnimatedIn(fingerprintWasStarted = true)
         biometricView.onError(
             TYPE_FACE,
             FaceManager.getErrorString(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
index 22ebc7e..8e5d96b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
@@ -120,7 +120,7 @@
 
     @Test
     fun testNegativeButton_beforeAuthentication_sendsActionButtonNegative() {
-        biometricView.onDialogAnimatedIn()
+        biometricView.onDialogAnimatedIn(fingerprintWasStarted = true)
         biometricView.mNegativeButton.performClick()
         TestableLooper.get(this).moveTimeForward(1000)
         waitForIdleSync()
@@ -212,7 +212,7 @@
     @Test
     fun testIgnoresUselessHelp() {
         biometricView.mAnimationDurationHideDialog = 10_000
-        biometricView.onDialogAnimatedIn()
+        biometricView.onDialogAnimatedIn(fingerprintWasStarted = true)
         waitForIdleSync()
 
         assertThat(biometricView.isAuthenticating).isTrue()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index a361bbc..d31a86a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -41,11 +41,15 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.data.repository.FakePromptRepository
 import com.android.systemui.biometrics.data.repository.FakeRearDisplayStateRepository
-import com.android.systemui.biometrics.domain.interactor.FakeCredentialInteractor
-import com.android.systemui.biometrics.domain.interactor.BiometricPromptCredentialInteractor
 import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl
+import com.android.systemui.biometrics.domain.interactor.FakeCredentialInteractor
+import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor
+import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractorImpl
 import com.android.systemui.biometrics.ui.viewmodel.AuthBiometricFingerprintViewModel
 import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel
+import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.time.FakeSystemClock
@@ -53,29 +57,34 @@
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
 import org.junit.After
+import org.junit.Before
 import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
+import org.mockito.Mockito.anyBoolean
 import org.mockito.Mockito.anyInt
 import org.mockito.Mockito.anyLong
 import org.mockito.Mockito.eq
 import org.mockito.Mockito.never
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
 import org.mockito.junit.MockitoJUnit
+import org.mockito.Mockito.`when` as whenever
 
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
-class AuthContainerViewTest : SysuiTestCase() {
+open class AuthContainerViewTest : SysuiTestCase() {
 
     @JvmField @Rule
     var mockitoRule = MockitoJUnit.rule()
 
+    private val featureFlags = FakeFeatureFlags()
+
     @Mock
     lateinit var callback: AuthDialogCallback
     @Mock
@@ -91,16 +100,25 @@
     @Mock
     lateinit var interactionJankMonitor: InteractionJankMonitor
 
+    // TODO(b/278622168): remove with flag
+    open val useNewBiometricPrompt = false
+
     private val testScope = TestScope(StandardTestDispatcher())
     private val fakeExecutor = FakeExecutor(FakeSystemClock())
     private val biometricPromptRepository = FakePromptRepository()
     private val rearDisplayStateRepository = FakeRearDisplayStateRepository()
     private val credentialInteractor = FakeCredentialInteractor()
-    private val bpCredentialInteractor = BiometricPromptCredentialInteractor(
+    private val bpCredentialInteractor = PromptCredentialInteractor(
         Dispatchers.Main.immediate,
         biometricPromptRepository,
-        credentialInteractor
+        credentialInteractor,
     )
+    private val promptSelectorInteractor by lazy {
+        PromptSelectorInteractorImpl(
+            biometricPromptRepository,
+            lockPatternUtils,
+        )
+    }
     private val displayStateInteractor = DisplayStateInteractorImpl(
         testScope.backgroundScope,
         mContext,
@@ -115,6 +133,11 @@
 
     private var authContainer: TestAuthContainerView? = null
 
+    @Before
+    fun setup() {
+        featureFlags.set(Flags.BIOMETRIC_BP_STRONG, useNewBiometricPrompt)
+    }
+
     @After
     fun tearDown() {
         if (authContainer?.isAttachedToWindow == true) {
@@ -125,7 +148,7 @@
     @Test
     fun testNotifiesAnimatedIn() {
         initializeFingerprintContainer()
-        verify(callback).onDialogAnimatedIn(authContainer?.requestId ?: 0L)
+        verify(callback).onDialogAnimatedIn(authContainer?.requestId ?: 0L, true /* startFingerprintNow */)
     }
 
     @Test
@@ -164,13 +187,13 @@
         container.dismissFromSystemServer()
         waitForIdleSync()
 
-        verify(callback, never()).onDialogAnimatedIn(anyLong())
+        verify(callback, never()).onDialogAnimatedIn(anyLong(), anyBoolean())
 
         container.addToView()
         waitForIdleSync()
 
         // attaching the view resets the state and allows this to happen again
-        verify(callback).onDialogAnimatedIn(authContainer?.requestId ?: 0L)
+        verify(callback).onDialogAnimatedIn(authContainer?.requestId ?: 0L, true /* startFingerprintNow */)
     }
 
     @Test
@@ -185,7 +208,7 @@
 
         // the first time is triggered by initializeFingerprintContainer()
         // the second time was triggered by dismissWithoutCallback()
-        verify(callback, times(2)).onDialogAnimatedIn(authContainer?.requestId ?: 0L)
+        verify(callback, times(2)).onDialogAnimatedIn(authContainer?.requestId ?: 0L, true /* startFingerprintNow */)
     }
 
     @Test
@@ -479,6 +502,8 @@
                 this.authenticators = authenticators
             }
         },
+        featureFlags,
+        testScope.backgroundScope,
         fingerprintProps,
         faceProps,
         wakefulnessLifecycle,
@@ -486,8 +511,10 @@
         userManager,
         lockPatternUtils,
         interactionJankMonitor,
-        { bpCredentialInteractor },
         { authBiometricFingerprintViewModel },
+        { promptSelectorInteractor },
+        { bpCredentialInteractor },
+        PromptViewModel(promptSelectorInteractor),
         { credentialViewModel },
         Handler(TestableLooper.get(this).looper),
         fakeExecutor
@@ -497,13 +524,31 @@
         }
     }
 
-    override fun waitForIdleSync() = TestableLooper.get(this).processAllMessages()
+    override fun waitForIdleSync() {
+        testScope.runCurrent()
+        TestableLooper.get(this).processAllMessages()
+    }
 
     private fun AuthContainerView.addToView() {
         ViewUtils.attachView(this)
         waitForIdleSync()
         assertThat(isAttachedToWindow()).isTrue()
     }
+
+    @Test
+    fun testLayoutParams_hasCutoutModeAlwaysFlag() {
+        val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
+        val lpFlags = layoutParams.flags
+
+        assertThat((lpFlags and WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS)
+                != 0).isTrue()
+    }
+
+    @Test
+    fun testLayoutParams_excludesSystemBarInsets() {
+        val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
+        assertThat((layoutParams.fitInsetsTypes and WindowInsets.Type.systemBars()) == 0).isTrue()
+    }
 }
 
 private fun AuthContainerView.hasBiometricPrompt() =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest2.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest2.kt
new file mode 100644
index 0000000..b56d055
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest2.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics
+
+import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import org.junit.runner.RunWith
+
+// TODO(b/278622168): remove with flag
+@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class AuthContainerViewTest2 : AuthContainerViewTest() {
+    override val useNewBiometricPrompt = true
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index a326cc7..b9f92a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -18,7 +18,6 @@
 
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
 import static android.hardware.biometrics.BiometricManager.Authenticators;
-import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -54,7 +53,6 @@
 import android.graphics.Point;
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricConstants;
-import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricPrompt;
 import android.hardware.biometrics.BiometricStateListener;
 import android.hardware.biometrics.ComponentInfoInternal;
@@ -91,10 +89,14 @@
 import com.android.settingslib.udfps.UdfpsUtils;
 import com.android.systemui.RoboPilotTest;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.biometrics.domain.interactor.BiometricPromptCredentialInteractor;
 import com.android.systemui.biometrics.domain.interactor.LogContextInteractor;
+import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor;
+import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor;
 import com.android.systemui.biometrics.ui.viewmodel.AuthBiometricFingerprintViewModel;
 import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel;
+import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.VibratorHelper;
@@ -171,12 +173,16 @@
     @Mock
     private InteractionJankMonitor mInteractionJankMonitor;
     @Mock
-    private BiometricPromptCredentialInteractor mBiometricPromptCredentialInteractor;
+    private PromptCredentialInteractor mBiometricPromptCredentialInteractor;
+    @Mock
+    private PromptSelectorInteractor mPromptSelectionInteractor;
     @Mock
     private AuthBiometricFingerprintViewModel mAuthBiometricFingerprintViewModel;
     @Mock
     private CredentialViewModel mCredentialViewModel;
     @Mock
+    private PromptViewModel mPromptViewModel;
+    @Mock
     private UdfpsUtils mUdfpsUtils;
 
     @Captor
@@ -194,12 +200,17 @@
     private Handler mHandler;
     private DelayableExecutor mBackgroundExecutor;
     private TestableAuthController mAuthController;
+    private FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
 
     @Mock
     private VibratorHelper mVibratorHelper;
 
     @Before
     public void setup() throws RemoteException {
+        // TODO(b/278622168): remove with flag
+        // AuthController simply passes this through to AuthContainerView (does not impact test)
+        mFeatureFlags.set(Flags.BIOMETRIC_BP_STRONG, false);
+
         mContextSpy = spy(mContext);
         mExecution = new FakeExecution();
         mTestableLooper = TestableLooper.get(this);
@@ -952,8 +963,7 @@
                 0 /* userId */,
                 0 /* operationId */,
                 "testPackage",
-                REQUEST_ID,
-                BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE);
+                REQUEST_ID);
     }
 
     private void switchTask(String packageName) {
@@ -993,25 +1003,26 @@
         private PromptInfo mLastBiometricPromptInfo;
 
         TestableAuthController(Context context) {
-            super(context, mExecution, mCommandQueue, mActivityTaskManager, mWindowManager,
+            super(context, mFeatureFlags, null /* applicationCoroutineScope */,
+                    mExecution, mCommandQueue, mActivityTaskManager, mWindowManager,
                     mFingerprintManager, mFaceManager, () -> mUdfpsController,
                     () -> mSideFpsController, mDisplayManager, mWakefulnessLifecycle,
                     mPanelInteractionDetector, mUserManager, mLockPatternUtils, mUdfpsLogger,
-                    mLogContextInteractor, () -> mBiometricPromptCredentialInteractor,
-                    () -> mAuthBiometricFingerprintViewModel, () -> mCredentialViewModel,
-                    mInteractionJankMonitor, mHandler, mBackgroundExecutor, mVibratorHelper,
-                    mUdfpsUtils);
+                    mLogContextInteractor, () -> mAuthBiometricFingerprintViewModel,
+                    () -> mBiometricPromptCredentialInteractor, () -> mPromptSelectionInteractor,
+                    () -> mCredentialViewModel, () -> mPromptViewModel,
+                    mInteractionJankMonitor, mHandler,
+                    mBackgroundExecutor, mVibratorHelper, mUdfpsUtils);
         }
 
         @Override
         protected AuthDialog buildDialog(DelayableExecutor bgExecutor, PromptInfo promptInfo,
                 boolean requireConfirmation, int userId, int[] sensorIds,
                 String opPackageName, boolean skipIntro, long operationId, long requestId,
-                @BiometricManager.BiometricMultiSensorMode int multiSensorConfig,
                 WakefulnessLifecycle wakefulnessLifecycle,
                 AuthDialogPanelInteractionDetector panelInteractionDetector,
                 UserManager userManager,
-                LockPatternUtils lockPatternUtils) {
+                LockPatternUtils lockPatternUtils, PromptViewModel viewModel) {
 
             mLastBiometricPromptInfo = promptInfo;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
index 1379a0e..94244cd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
@@ -18,10 +18,11 @@
 
 import android.annotation.IdRes
 import android.content.Context
-import android.hardware.biometrics.BiometricManager
+import android.hardware.biometrics.BiometricManager.Authenticators
 import android.hardware.biometrics.ComponentInfoInternal
 import android.hardware.biometrics.PromptInfo
 import android.hardware.biometrics.SensorProperties
+import android.hardware.biometrics.SensorPropertiesInternal
 import android.hardware.face.FaceSensorProperties
 import android.hardware.face.FaceSensorPropertiesInternal
 import android.hardware.fingerprint.FingerprintSensorProperties
@@ -61,9 +62,9 @@
 private fun buildPromptInfo(allowDeviceCredential: Boolean): PromptInfo {
     val promptInfo = PromptInfo()
     promptInfo.title = "Title"
-    var authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK
+    var authenticators = Authenticators.BIOMETRIC_WEAK
     if (allowDeviceCredential) {
-        authenticators = authenticators or BiometricManager.Authenticators.DEVICE_CREDENTIAL
+        authenticators = authenticators or Authenticators.DEVICE_CREDENTIAL
     } else {
         promptInfo.negativeButtonText = "Negative"
     }
@@ -80,7 +81,8 @@
 
 /** Create [FingerprintSensorPropertiesInternal] for a test. */
 internal fun fingerprintSensorPropertiesInternal(
-    ids: List<Int> = listOf(0)
+    ids: List<Int> = listOf(0),
+    strong: Boolean = true,
 ): List<FingerprintSensorPropertiesInternal> {
     val componentInfo =
         listOf(
@@ -102,7 +104,7 @@
     return ids.map { id ->
         FingerprintSensorPropertiesInternal(
             id,
-            SensorProperties.STRENGTH_STRONG,
+            if (strong) SensorProperties.STRENGTH_STRONG else SensorProperties.STRENGTH_WEAK,
             5 /* maxEnrollmentsPerUser */,
             componentInfo,
             FingerprintSensorProperties.TYPE_REAR,
@@ -113,7 +115,8 @@
 
 /** Create [FaceSensorPropertiesInternal] for a test. */
 internal fun faceSensorPropertiesInternal(
-    ids: List<Int> = listOf(1)
+    ids: List<Int> = listOf(1),
+    strong: Boolean = true,
 ): List<FaceSensorPropertiesInternal> {
     val componentInfo =
         listOf(
@@ -135,7 +138,7 @@
     return ids.map { id ->
         FaceSensorPropertiesInternal(
             id,
-            SensorProperties.STRENGTH_STRONG,
+            if (strong) SensorProperties.STRENGTH_STRONG else SensorProperties.STRENGTH_WEAK,
             2 /* maxEnrollmentsPerUser */,
             componentInfo,
             FaceSensorProperties.TYPE_RGB,
@@ -146,6 +149,24 @@
     }
 }
 
+@Authenticators.Types
+internal fun Collection<SensorPropertiesInternal?>.extractAuthenticatorTypes(): Int {
+    var authenticators = Authenticators.EMPTY_SET
+    mapNotNull { it?.sensorStrength }
+        .forEach { strength ->
+            authenticators =
+                authenticators or
+                    when (strength) {
+                        SensorProperties.STRENGTH_CONVENIENCE ->
+                            Authenticators.BIOMETRIC_CONVENIENCE
+                        SensorProperties.STRENGTH_WEAK -> Authenticators.BIOMETRIC_WEAK
+                        SensorProperties.STRENGTH_STRONG -> Authenticators.BIOMETRIC_STRONG
+                        else -> Authenticators.EMPTY_SET
+                    }
+        }
+    return authenticators
+}
+
 internal fun promptInfo(
     title: String = "title",
     subtitle: String = "sub",
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java
index d3622c5..0d3b394 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerBaseTest.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.biometrics;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -100,6 +101,8 @@
         when(mResourceContext.getString(anyInt())).thenReturn("test string");
         when(mKeyguardViewMediator.isAnimatingScreenOff()).thenReturn(false);
         when(mView.getUnpausedAlpha()).thenReturn(255);
+        when(mShadeExpansionStateManager.addExpansionListener(any())).thenReturn(
+                new ShadeExpansionChangeEvent(0, false, false, 0));
         mController = createUdfpsKeyguardViewController();
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
index 7531cb4..ffad326 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
@@ -24,13 +24,14 @@
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.BouncerView
 import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.data.repository.FakeTrustRepository
 import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
 import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepositoryImpl
-import com.android.systemui.keyguard.data.repository.TrustRepository
 import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
@@ -95,8 +96,9 @@
                 mock(DismissCallbackRegistry::class.java),
                 context,
                 mKeyguardUpdateMonitor,
-                mock(TrustRepository::class.java),
-                FakeFeatureFlags(),
+                FakeTrustRepository(),
+                FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) },
+                testScope.backgroundScope,
             )
         mAlternateBouncerInteractor =
             AlternateBouncerInteractor(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
index 2d5614c..4836af6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
@@ -4,7 +4,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.AuthController
-import com.android.systemui.biometrics.data.model.PromptKind
+import com.android.systemui.biometrics.shared.model.PromptKind
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
@@ -60,7 +60,7 @@
 
     @Test
     fun setsAndUnsetsPrompt() = runBlockingTest {
-        val kind = PromptKind.PIN
+        val kind = PromptKind.Pin
         val uid = 8
         val challenge = 90L
         val promptInfo = PromptInfo()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
index dbcbf41..720a35c9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
@@ -9,15 +9,17 @@
 import com.android.systemui.biometrics.domain.model.BiometricPromptRequest
 import com.android.systemui.biometrics.domain.model.BiometricUserInfo
 import com.android.systemui.biometrics.promptInfo
+import com.android.systemui.coroutines.collectLastValue
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.toList
 import kotlinx.coroutines.launch
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Rule
@@ -36,42 +38,39 @@
 
     @JvmField @Rule var mockitoRule = MockitoJUnit.rule()
 
-    private val dispatcher = UnconfinedTestDispatcher()
+    private val testDispatcher = StandardTestDispatcher()
+    private val testScope = TestScope(testDispatcher)
     private val biometricPromptRepository = FakePromptRepository()
     private val credentialInteractor = FakeCredentialInteractor()
 
-    private lateinit var interactor: BiometricPromptCredentialInteractor
+    private lateinit var interactor: PromptCredentialInteractor
 
     @Before
     fun setup() {
         interactor =
-            BiometricPromptCredentialInteractor(
-                dispatcher,
+            PromptCredentialInteractor(
+                testDispatcher,
                 biometricPromptRepository,
-                credentialInteractor
+                credentialInteractor,
             )
     }
 
     @Test
     fun testIsShowing() =
-        runTest(dispatcher) {
-            var showing = false
-            val job = launch { interactor.isShowing.collect { showing = it } }
+        testScope.runTest {
+            val showing by collectLastValue(interactor.isShowing)
 
             biometricPromptRepository.setIsShowing(false)
             assertThat(showing).isFalse()
 
             biometricPromptRepository.setIsShowing(true)
             assertThat(showing).isTrue()
-
-            job.cancel()
         }
 
     @Test
     fun testShowError() =
-        runTest(dispatcher) {
-            var error: CredentialStatus.Fail? = null
-            val job = launch { interactor.verificationError.collect { error = it } }
+        testScope.runTest {
+            val error by collectLastValue(interactor.verificationError)
 
             for (msg in listOf("once", "again")) {
                 interactor.setVerificationError(error(msg))
@@ -80,19 +79,14 @@
 
             interactor.resetVerificationError()
             assertThat(error).isNull()
-
-            job.cancel()
         }
 
     @Test
     fun nullWhenNoPromptInfo() =
-        runTest(dispatcher) {
-            var prompt: BiometricPromptRequest? = null
-            val job = launch { interactor.prompt.collect { prompt = it } }
+        testScope.runTest {
+            val prompt by collectLastValue(interactor.prompt)
 
             assertThat(prompt).isNull()
-
-            job.cancel()
         }
 
     @Test fun usePinCredentialForPrompt() = useCredentialForPrompt(Utils.CREDENTIAL_PIN)
@@ -102,12 +96,11 @@
     @Test fun usePatternCredentialForPrompt() = useCredentialForPrompt(Utils.CREDENTIAL_PATTERN)
 
     private fun useCredentialForPrompt(kind: Int) =
-        runTest(dispatcher) {
+        testScope.runTest {
             val isStealth = false
             credentialInteractor.stealthMode = isStealth
 
-            var prompt: BiometricPromptRequest? = null
-            val job = launch { interactor.prompt.collect { prompt = it } }
+            val prompt by collectLastValue(interactor.prompt)
 
             val title = "what a prompt"
             val subtitle = "s"
@@ -124,14 +117,12 @@
                 challenge = OPERATION_ID
             )
 
-            val p = prompt as? BiometricPromptRequest.Credential
-            assertThat(p).isNotNull()
-            assertThat(p!!.title).isEqualTo(title)
-            assertThat(p.subtitle).isEqualTo(subtitle)
-            assertThat(p.description).isEqualTo(description)
-            assertThat(p.userInfo).isEqualTo(BiometricUserInfo(USER_ID))
-            assertThat(p.operationInfo).isEqualTo(BiometricOperationInfo(OPERATION_ID))
-            assertThat(p)
+            assertThat(prompt?.title).isEqualTo(title)
+            assertThat(prompt?.subtitle).isEqualTo(subtitle)
+            assertThat(prompt?.description).isEqualTo(description)
+            assertThat(prompt?.userInfo).isEqualTo(BiometricUserInfo(USER_ID))
+            assertThat(prompt?.operationInfo).isEqualTo(BiometricOperationInfo(OPERATION_ID))
+            assertThat(prompt)
                 .isInstanceOf(
                     when (kind) {
                         Utils.CREDENTIAL_PIN -> BiometricPromptRequest.Credential.Pin::class.java
@@ -142,25 +133,25 @@
                         else -> throw Exception("wrong kind")
                     }
                 )
-            if (p is BiometricPromptRequest.Credential.Pattern) {
-                assertThat(p.stealthMode).isEqualTo(isStealth)
+            val pattern = prompt as? BiometricPromptRequest.Credential.Pattern
+            if (pattern != null) {
+                assertThat(pattern.stealthMode).isEqualTo(isStealth)
             }
 
             interactor.resetPrompt()
 
             assertThat(prompt).isNull()
-
-            job.cancel()
         }
 
     @Test
     fun checkCredential() =
-        runTest(dispatcher) {
+        testScope.runTest {
             val hat = ByteArray(4)
             credentialInteractor.verifyCredentialResponse = { _ -> flowOf(verified(hat)) }
 
             val errors = mutableListOf<CredentialStatus.Fail?>()
             val job = launch { interactor.verificationError.toList(errors) }
+            runCurrent()
 
             val checked =
                 interactor.checkCredential(pinRequest(), text = "1234")
@@ -168,6 +159,8 @@
 
             assertThat(checked).isNotNull()
             assertThat(checked!!.hat).isSameInstanceAs(hat)
+
+            runCurrent()
             assertThat(errors.map { it?.error }).containsExactly(null)
 
             job.cancel()
@@ -175,7 +168,7 @@
 
     @Test
     fun checkCredentialWhenBad() =
-        runTest(dispatcher) {
+        testScope.runTest {
             val errorMessage = "bad"
             val remainingAttempts = 12
             credentialInteractor.verifyCredentialResponse = { _ ->
@@ -184,6 +177,7 @@
 
             val errors = mutableListOf<CredentialStatus.Fail?>()
             val job = launch { interactor.verificationError.toList(errors) }
+            runCurrent()
 
             val checked =
                 interactor.checkCredential(pinRequest(), text = "1234")
@@ -192,6 +186,8 @@
             assertThat(checked).isNotNull()
             assertThat(checked!!.remainingAttempts).isEqualTo(remainingAttempts)
             assertThat(checked.urgentMessage).isNull()
+
+            runCurrent()
             assertThat(errors.map { it?.error }).containsExactly(null, errorMessage).inOrder()
 
             job.cancel()
@@ -199,7 +195,7 @@
 
     @Test
     fun checkCredentialWhenBadAndUrgentMessage() =
-        runTest(dispatcher) {
+        testScope.runTest {
             val error = "not so bad"
             val urgentMessage = "really bad"
             credentialInteractor.verifyCredentialResponse = { _ ->
@@ -208,6 +204,7 @@
 
             val errors = mutableListOf<CredentialStatus.Fail?>()
             val job = launch { interactor.verificationError.toList(errors) }
+            runCurrent()
 
             val checked =
                 interactor.checkCredential(pinRequest(), text = "1234")
@@ -215,6 +212,8 @@
 
             assertThat(checked).isNotNull()
             assertThat(checked!!.urgentMessage).isEqualTo(urgentMessage)
+
+            runCurrent()
             assertThat(errors.map { it?.error }).containsExactly(null, error).inOrder()
             assertThat(errors.last() as? CredentialStatus.Fail.Error)
                 .isEqualTo(error(error, 10, urgentMessage))
@@ -224,7 +223,7 @@
 
     @Test
     fun checkCredentialWhenBadAndThrottled() =
-        runTest(dispatcher) {
+        testScope.runTest {
             val remainingAttempts = 3
             val error = ":("
             val urgentMessage = ":D"
@@ -239,6 +238,7 @@
             }
             val errors = mutableListOf<CredentialStatus.Fail?>()
             val job = launch { interactor.verificationError.toList(errors) }
+            runCurrent()
 
             val checked =
                 interactor.checkCredential(pinRequest(), text = "1234")
@@ -246,6 +246,8 @@
 
             assertThat(checked).isNotNull()
             assertThat(checked!!.remainingAttempts).isEqualTo(remainingAttempts)
+
+            runCurrent()
             assertThat(checked.urgentMessage).isEqualTo(urgentMessage)
             assertThat(errors.map { it?.error })
                 .containsExactly(null, "1", "2", "3", error)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
new file mode 100644
index 0000000..a62ea3b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.domain.interactor
+
+import android.app.admin.DevicePolicyManager
+import android.hardware.biometrics.BiometricManager.Authenticators
+import android.hardware.biometrics.PromptInfo
+import androidx.test.filters.SmallTest
+import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.Utils
+import com.android.systemui.biometrics.data.repository.FakePromptRepository
+import com.android.systemui.biometrics.domain.model.BiometricModalities
+import com.android.systemui.biometrics.faceSensorPropertiesInternal
+import com.android.systemui.biometrics.fingerprintSensorPropertiesInternal
+import com.android.systemui.biometrics.shared.model.PromptKind
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnit
+
+private const val TITLE = "hey there"
+private const val SUBTITLE = "ok"
+private const val DESCRIPTION = "football"
+private const val NEGATIVE_TEXT = "escape"
+
+private const val USER_ID = 8
+private const val CHALLENGE = 999L
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class PromptSelectorInteractorImplTest : SysuiTestCase() {
+
+    @JvmField @Rule var mockitoRule = MockitoJUnit.rule()
+
+    @Mock private lateinit var lockPatternUtils: LockPatternUtils
+
+    private val testScope = TestScope()
+    private val promptRepository = FakePromptRepository()
+
+    private lateinit var interactor: PromptSelectorInteractor
+
+    @Before
+    fun setup() {
+        interactor = PromptSelectorInteractorImpl(promptRepository, lockPatternUtils)
+    }
+
+    @Test
+    fun useBiometricsAndReset() =
+        testScope.runTest { useBiometricsAndReset(allowCredentialFallback = true) }
+
+    @Test
+    fun useBiometricsAndResetWithoutFallback() =
+        testScope.runTest { useBiometricsAndReset(allowCredentialFallback = false) }
+
+    private fun TestScope.useBiometricsAndReset(allowCredentialFallback: Boolean) {
+        setUserCredentialType(isPassword = true)
+
+        val confirmationRequired = true
+        val info =
+            PromptInfo().apply {
+                title = TITLE
+                subtitle = SUBTITLE
+                description = DESCRIPTION
+                negativeButtonText = NEGATIVE_TEXT
+                isConfirmationRequested = confirmationRequired
+                authenticators =
+                    if (allowCredentialFallback) {
+                        Authenticators.BIOMETRIC_STRONG or Authenticators.DEVICE_CREDENTIAL
+                    } else {
+                        Authenticators.BIOMETRIC_STRONG
+                    }
+                isDeviceCredentialAllowed = allowCredentialFallback
+            }
+        val modalities =
+            BiometricModalities(
+                fingerprintProperties = fingerprintSensorPropertiesInternal().first(),
+                faceProperties = faceSensorPropertiesInternal().first(),
+            )
+
+        val currentPrompt by collectLastValue(interactor.prompt)
+        val credentialKind by collectLastValue(interactor.credentialKind)
+        val isCredentialAllowed by collectLastValue(interactor.isCredentialAllowed)
+        val isExplicitConfirmationRequired by collectLastValue(interactor.isConfirmationRequested)
+
+        assertThat(currentPrompt).isNull()
+
+        interactor.useBiometricsForAuthentication(
+            info,
+            confirmationRequired,
+            USER_ID,
+            CHALLENGE,
+            modalities
+        )
+
+        assertThat(currentPrompt).isNotNull()
+        assertThat(currentPrompt?.title).isEqualTo(TITLE)
+        assertThat(currentPrompt?.description).isEqualTo(DESCRIPTION)
+        assertThat(currentPrompt?.subtitle).isEqualTo(SUBTITLE)
+        assertThat(currentPrompt?.negativeButtonText).isEqualTo(NEGATIVE_TEXT)
+
+        if (allowCredentialFallback) {
+            assertThat(credentialKind).isSameInstanceAs(PromptKind.Password)
+            assertThat(isCredentialAllowed).isTrue()
+        } else {
+            assertThat(credentialKind).isEqualTo(PromptKind.Biometric())
+            assertThat(isCredentialAllowed).isFalse()
+        }
+        assertThat(isExplicitConfirmationRequired).isEqualTo(confirmationRequired)
+
+        interactor.resetPrompt()
+        verifyUnset()
+    }
+
+    @Test
+    fun usePinCredentialAndReset() =
+        testScope.runTest { useCredentialAndReset(Utils.CREDENTIAL_PIN) }
+
+    @Test
+    fun usePattermCredentialAndReset() =
+        testScope.runTest { useCredentialAndReset(Utils.CREDENTIAL_PATTERN) }
+
+    @Test
+    fun usePasswordCredentialAndReset() =
+        testScope.runTest { useCredentialAndReset(Utils.CREDENTIAL_PASSWORD) }
+
+    private fun TestScope.useCredentialAndReset(@Utils.CredentialType kind: Int) {
+        setUserCredentialType(
+            isPin = kind == Utils.CREDENTIAL_PIN,
+            isPassword = kind == Utils.CREDENTIAL_PASSWORD,
+        )
+
+        val info =
+            PromptInfo().apply {
+                title = TITLE
+                subtitle = SUBTITLE
+                description = DESCRIPTION
+                negativeButtonText = NEGATIVE_TEXT
+                authenticators = Authenticators.DEVICE_CREDENTIAL
+                isDeviceCredentialAllowed = true
+            }
+
+        val currentPrompt by collectLastValue(interactor.prompt)
+        val credentialKind by collectLastValue(interactor.credentialKind)
+
+        assertThat(currentPrompt).isNull()
+
+        interactor.useCredentialsForAuthentication(info, kind, USER_ID, CHALLENGE)
+
+        // not using biometrics, should be null with no fallback option
+        assertThat(currentPrompt).isNull()
+        assertThat(credentialKind).isEqualTo(PromptKind.Biometric())
+
+        interactor.resetPrompt()
+        verifyUnset()
+    }
+
+    private fun TestScope.verifyUnset() {
+        val currentPrompt by collectLastValue(interactor.prompt)
+        val credentialKind by collectLastValue(interactor.credentialKind)
+
+        assertThat(currentPrompt).isNull()
+
+        val kind = credentialKind as? PromptKind.Biometric
+        assertThat(kind).isNotNull()
+        assertThat(kind?.activeModalities?.isEmpty).isTrue()
+    }
+
+    private fun setUserCredentialType(isPin: Boolean = false, isPassword: Boolean = false) {
+        whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(any()))
+            .thenReturn(
+                when {
+                    isPin -> DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
+                    isPassword -> DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
+                    else -> DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
+                }
+            )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricModalitiesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricModalitiesTest.kt
new file mode 100644
index 0000000..526b833
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricModalitiesTest.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.domain.model
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.faceSensorPropertiesInternal
+import com.android.systemui.biometrics.fingerprintSensorPropertiesInternal
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class BiometricModalitiesTest : SysuiTestCase() {
+
+    @Test
+    fun isEmpty() {
+        assertThat(BiometricModalities().isEmpty).isTrue()
+    }
+
+    @Test
+    fun fingerprintOnly() {
+        with(
+            BiometricModalities(
+                fingerprintProperties = fingerprintSensorPropertiesInternal().first(),
+            )
+        ) {
+            assertThat(isEmpty).isFalse()
+            assertThat(hasFace).isFalse()
+            assertThat(hasFaceOnly).isFalse()
+            assertThat(hasFingerprint).isTrue()
+            assertThat(hasFingerprintOnly).isTrue()
+            assertThat(hasFaceAndFingerprint).isFalse()
+        }
+    }
+
+    @Test
+    fun faceOnly() {
+        with(BiometricModalities(faceProperties = faceSensorPropertiesInternal().first())) {
+            assertThat(isEmpty).isFalse()
+            assertThat(hasFace).isTrue()
+            assertThat(hasFaceOnly).isTrue()
+            assertThat(hasFingerprint).isFalse()
+            assertThat(hasFingerprintOnly).isFalse()
+            assertThat(hasFaceAndFingerprint).isFalse()
+        }
+    }
+
+    @Test
+    fun faceStrength() {
+        with(
+            BiometricModalities(
+                fingerprintProperties = fingerprintSensorPropertiesInternal(strong = false).first(),
+                faceProperties = faceSensorPropertiesInternal(strong = true).first()
+            )
+        ) {
+            assertThat(isFaceStrong).isTrue()
+        }
+
+        with(
+            BiometricModalities(
+                fingerprintProperties = fingerprintSensorPropertiesInternal(strong = false).first(),
+                faceProperties = faceSensorPropertiesInternal(strong = false).first()
+            )
+        ) {
+            assertThat(isFaceStrong).isFalse()
+        }
+    }
+
+    @Test
+    fun faceAndFingerprint() {
+        with(
+            BiometricModalities(
+                fingerprintProperties = fingerprintSensorPropertiesInternal().first(),
+                faceProperties = faceSensorPropertiesInternal().first(),
+            )
+        ) {
+            assertThat(isEmpty).isFalse()
+            assertThat(hasFace).isTrue()
+            assertThat(hasFingerprint).isTrue()
+            assertThat(hasFaceOnly).isFalse()
+            assertThat(hasFingerprintOnly).isFalse()
+            assertThat(hasFaceAndFingerprint).isTrue()
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequestTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequestTest.kt
index 4c5e3c1..e352905 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequestTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequestTest.kt
@@ -2,6 +2,7 @@
 
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.fingerprintSensorPropertiesInternal
 import com.android.systemui.biometrics.promptInfo
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
@@ -21,11 +22,13 @@
         val subtitle = "a"
         val description = "request"
 
+        val fpPros = fingerprintSensorPropertiesInternal().first()
         val request =
             BiometricPromptRequest.Biometric(
                 promptInfo(title = title, subtitle = subtitle, description = description),
                 BiometricUserInfo(USER_ID),
-                BiometricOperationInfo(OPERATION_ID)
+                BiometricOperationInfo(OPERATION_ID),
+                BiometricModalities(fingerprintProperties = fpPros),
             )
 
         assertThat(request.title).isEqualTo(title)
@@ -33,6 +36,8 @@
         assertThat(request.description).isEqualTo(description)
         assertThat(request.userInfo).isEqualTo(BiometricUserInfo(USER_ID))
         assertThat(request.operationInfo).isEqualTo(BiometricOperationInfo(OPERATION_ID))
+        assertThat(request.modalities)
+            .isEqualTo(BiometricModalities(fingerprintProperties = fpPros))
     }
 
     @Test
@@ -51,19 +56,19 @@
                         description = description,
                         credentialTitle = null,
                         credentialSubtitle = null,
-                        credentialDescription = null
+                        credentialDescription = null,
                     ),
                     BiometricUserInfo(USER_ID),
-                    BiometricOperationInfo(OPERATION_ID)
+                    BiometricOperationInfo(OPERATION_ID),
                 ),
                 BiometricPromptRequest.Credential.Password(
                     promptInfo(
                         credentialTitle = title,
                         credentialSubtitle = subtitle,
-                        credentialDescription = description
+                        credentialDescription = description,
                     ),
                     BiometricUserInfo(USER_ID),
-                    BiometricOperationInfo(OPERATION_ID)
+                    BiometricOperationInfo(OPERATION_ID),
                 ),
                 BiometricPromptRequest.Credential.Pattern(
                     promptInfo(
@@ -71,11 +76,11 @@
                         description = description,
                         credentialTitle = title,
                         credentialSubtitle = null,
-                        credentialDescription = null
+                        credentialDescription = null,
                     ),
                     BiometricUserInfo(USER_ID),
                     BiometricOperationInfo(OPERATION_ID),
-                    stealth
+                    stealth,
                 )
             )
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt
index d73cdfc..3245020 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt
@@ -2,12 +2,12 @@
 
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.data.model.PromptKind
 import com.android.systemui.biometrics.data.repository.FakePromptRepository
-import com.android.systemui.biometrics.domain.interactor.BiometricPromptCredentialInteractor
 import com.android.systemui.biometrics.domain.interactor.CredentialStatus
 import com.android.systemui.biometrics.domain.interactor.FakeCredentialInteractor
+import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor
 import com.android.systemui.biometrics.promptInfo
+import com.android.systemui.biometrics.shared.model.PromptKind
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
@@ -40,17 +40,13 @@
         viewModel =
             CredentialViewModel(
                 mContext,
-                BiometricPromptCredentialInteractor(
-                    dispatcher,
-                    promptRepository,
-                    credentialInteractor
-                )
+                PromptCredentialInteractor(dispatcher, promptRepository, credentialInteractor)
             )
     }
 
-    @Test fun setsPinInputFlags() = setsInputFlags(PromptKind.PIN, expectFlags = true)
-    @Test fun setsPasswordInputFlags() = setsInputFlags(PromptKind.PASSWORD, expectFlags = false)
-    @Test fun setsPatternInputFlags() = setsInputFlags(PromptKind.PATTERN, expectFlags = false)
+    @Test fun setsPinInputFlags() = setsInputFlags(PromptKind.Pin, expectFlags = true)
+    @Test fun setsPasswordInputFlags() = setsInputFlags(PromptKind.Password, expectFlags = false)
+    @Test fun setsPatternInputFlags() = setsInputFlags(PromptKind.Pattern, expectFlags = false)
 
     private fun setsInputFlags(type: PromptKind, expectFlags: Boolean) =
         runTestWithKind(type) {
@@ -65,10 +61,10 @@
             job.cancel()
         }
 
-    @Test fun isStealthIgnoredByPin() = isStealthMode(PromptKind.PIN, expectStealth = false)
+    @Test fun isStealthIgnoredByPin() = isStealthMode(PromptKind.Pin, expectStealth = false)
     @Test
-    fun isStealthIgnoredByPassword() = isStealthMode(PromptKind.PASSWORD, expectStealth = false)
-    @Test fun isStealthUsedByPattern() = isStealthMode(PromptKind.PATTERN, expectStealth = true)
+    fun isStealthIgnoredByPassword() = isStealthMode(PromptKind.Password, expectStealth = false)
+    @Test fun isStealthUsedByPattern() = isStealthMode(PromptKind.Pattern, expectStealth = true)
 
     private fun isStealthMode(type: PromptKind, expectStealth: Boolean) =
         runTestWithKind(type, init = { credentialInteractor.stealthMode = true }) {
@@ -119,7 +115,7 @@
 
         val attestations = mutableListOf<ByteArray?>()
         val remainingAttempts = mutableListOf<RemainingAttempts?>()
-        var header: HeaderViewModel? = null
+        var header: CredentialHeaderViewModel? = null
         val job = launch {
             launch { viewModel.validatedAttestation.toList(attestations) }
             launch { viewModel.remainingAttempts.toList(remainingAttempts) }
@@ -147,7 +143,7 @@
 
         val attestations = mutableListOf<ByteArray?>()
         val remainingAttempts = mutableListOf<RemainingAttempts?>()
-        var header: HeaderViewModel? = null
+        var header: CredentialHeaderViewModel? = null
         val job = launch {
             launch { viewModel.validatedAttestation.toList(attestations) }
             launch { viewModel.remainingAttempts.toList(remainingAttempts) }
@@ -169,7 +165,7 @@
     }
 
     private fun runTestWithKind(
-        kind: PromptKind = PromptKind.PIN,
+        kind: PromptKind = PromptKind.Pin,
         init: () -> Unit = {},
         block: suspend TestScope.() -> Unit,
     ) =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthStateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthStateTest.kt
new file mode 100644
index 0000000..689bb00
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthStateTest.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.domain.model.BiometricModality
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class PromptAuthStateTest : SysuiTestCase() {
+
+    @Test
+    fun notAuthenticated() {
+        with(PromptAuthState(isAuthenticated = false)) {
+            assertThat(isNotAuthenticated).isTrue()
+            assertThat(isAuthenticatedAndConfirmed).isFalse()
+            assertThat(isAuthenticatedByFace).isFalse()
+            assertThat(isAuthenticatedByFingerprint).isFalse()
+        }
+    }
+
+    @Test
+    fun authenticatedByUnknown() {
+        with(PromptAuthState(isAuthenticated = true)) {
+            assertThat(isNotAuthenticated).isFalse()
+            assertThat(isAuthenticatedAndConfirmed).isTrue()
+            assertThat(isAuthenticatedByFace).isFalse()
+            assertThat(isAuthenticatedByFingerprint).isFalse()
+        }
+
+        with(PromptAuthState(isAuthenticated = true, needsUserConfirmation = true)) {
+            assertThat(isNotAuthenticated).isFalse()
+            assertThat(isAuthenticatedAndConfirmed).isFalse()
+            assertThat(isAuthenticatedByFace).isFalse()
+            assertThat(isAuthenticatedByFingerprint).isFalse()
+
+            assertThat(asConfirmed().isAuthenticatedAndConfirmed).isTrue()
+        }
+    }
+
+    @Test
+    fun authenticatedWithFace() {
+        with(
+            PromptAuthState(isAuthenticated = true, authenticatedModality = BiometricModality.Face)
+        ) {
+            assertThat(isNotAuthenticated).isFalse()
+            assertThat(isAuthenticatedAndConfirmed).isTrue()
+            assertThat(isAuthenticatedByFace).isTrue()
+            assertThat(isAuthenticatedByFingerprint).isFalse()
+        }
+    }
+
+    @Test
+    fun authenticatedWithFingerprint() {
+        with(
+            PromptAuthState(
+                isAuthenticated = true,
+                authenticatedModality = BiometricModality.Fingerprint,
+            )
+        ) {
+            assertThat(isNotAuthenticated).isFalse()
+            assertThat(isAuthenticatedAndConfirmed).isTrue()
+            assertThat(isAuthenticatedByFace).isFalse()
+            assertThat(isAuthenticatedByFingerprint).isTrue()
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
new file mode 100644
index 0000000..3ba6004
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -0,0 +1,639 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics.ui.viewmodel
+
+import android.hardware.biometrics.PromptInfo
+import android.hardware.face.FaceSensorPropertiesInternal
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+import androidx.test.filters.SmallTest
+import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.AuthBiometricView
+import com.android.systemui.biometrics.data.repository.FakePromptRepository
+import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor
+import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractorImpl
+import com.android.systemui.biometrics.domain.model.BiometricModalities
+import com.android.systemui.biometrics.domain.model.BiometricModality
+import com.android.systemui.biometrics.extractAuthenticatorTypes
+import com.android.systemui.biometrics.faceSensorPropertiesInternal
+import com.android.systemui.biometrics.fingerprintSensorPropertiesInternal
+import com.android.systemui.coroutines.collectLastValue
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnit
+
+private const val USER_ID = 4
+private const val CHALLENGE = 2L
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(Parameterized::class)
+internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCase() {
+
+    @JvmField @Rule var mockitoRule = MockitoJUnit.rule()
+
+    @Mock private lateinit var lockPatternUtils: LockPatternUtils
+
+    private val testScope = TestScope()
+    private val promptRepository = FakePromptRepository()
+
+    private lateinit var selector: PromptSelectorInteractor
+    private lateinit var viewModel: PromptViewModel
+
+    @Before
+    fun setup() {
+        selector = PromptSelectorInteractorImpl(promptRepository, lockPatternUtils)
+        selector.resetPrompt()
+
+        viewModel = PromptViewModel(selector)
+    }
+
+    @Test
+    fun `start idle and show authenticating`() =
+        runGenericTest(doNotStart = true) {
+            val expectedSize =
+                if (testCase.shouldStartAsImplicitFlow) PromptSize.SMALL else PromptSize.MEDIUM
+            val authenticating by collectLastValue(viewModel.isAuthenticating)
+            val authenticated by collectLastValue(viewModel.isAuthenticated)
+            val modalities by collectLastValue(viewModel.modalities)
+            val message by collectLastValue(viewModel.message)
+            val size by collectLastValue(viewModel.size)
+            val legacyState by collectLastValue(viewModel.legacyState)
+
+            assertThat(authenticating).isFalse()
+            assertThat(authenticated?.isNotAuthenticated).isTrue()
+            with(modalities ?: throw Exception("missing modalities")) {
+                assertThat(hasFace).isEqualTo(testCase.face != null)
+                assertThat(hasFingerprint).isEqualTo(testCase.fingerprint != null)
+            }
+            assertThat(message).isEqualTo(PromptMessage.Empty)
+            assertThat(size).isEqualTo(expectedSize)
+            assertThat(legacyState).isEqualTo(AuthBiometricView.STATE_AUTHENTICATING_ANIMATING_IN)
+
+            val startMessage = "here we go"
+            viewModel.showAuthenticating(startMessage, isRetry = false)
+
+            assertThat(message).isEqualTo(PromptMessage.Help(startMessage))
+            assertThat(authenticating).isTrue()
+            assertThat(authenticated?.isNotAuthenticated).isTrue()
+            assertThat(size).isEqualTo(expectedSize)
+            assertButtonsVisible(negative = expectedSize != PromptSize.SMALL)
+            assertThat(legacyState).isEqualTo(AuthBiometricView.STATE_AUTHENTICATING)
+        }
+
+    @Test
+    fun `shows authenticated - no errors`() = runGenericTest {
+        // this case can't happen until fingerprint is started
+        // trigger it now since no error has occurred in this test
+        val forceError = testCase.isCoex && testCase.authenticatedByFingerprint
+
+        if (forceError) {
+            assertThat(viewModel.fingerprintStartMode.first())
+                .isEqualTo(FingerprintStartMode.Pending)
+            viewModel.ensureFingerprintHasStarted(isDelayed = true)
+        }
+
+        showAuthenticated(
+            testCase.authenticatedModality,
+            testCase.expectConfirmation(atLeastOneFailure = forceError),
+        )
+    }
+
+    private suspend fun TestScope.showAuthenticated(
+        authenticatedModality: BiometricModality,
+        expectConfirmation: Boolean,
+    ) {
+        val authenticating by collectLastValue(viewModel.isAuthenticating)
+        val authenticated by collectLastValue(viewModel.isAuthenticated)
+        val fpStartMode by collectLastValue(viewModel.fingerprintStartMode)
+        val size by collectLastValue(viewModel.size)
+        val legacyState by collectLastValue(viewModel.legacyState)
+
+        val authWithSmallPrompt =
+            testCase.shouldStartAsImplicitFlow &&
+                (fpStartMode == FingerprintStartMode.Pending || testCase.isFaceOnly)
+        assertThat(authenticating).isTrue()
+        assertThat(authenticated?.isNotAuthenticated).isTrue()
+        assertThat(size).isEqualTo(if (authWithSmallPrompt) PromptSize.SMALL else PromptSize.MEDIUM)
+        assertThat(legacyState).isEqualTo(AuthBiometricView.STATE_AUTHENTICATING)
+        assertButtonsVisible(negative = !authWithSmallPrompt)
+
+        val delay = 1000L
+        viewModel.showAuthenticated(authenticatedModality, delay)
+
+        assertThat(authenticated?.isAuthenticated).isTrue()
+        assertThat(authenticated?.delay).isEqualTo(delay)
+        assertThat(authenticated?.needsUserConfirmation).isEqualTo(expectConfirmation)
+        assertThat(size)
+            .isEqualTo(
+                if (authenticatedModality == BiometricModality.Fingerprint || expectConfirmation) {
+                    PromptSize.MEDIUM
+                } else {
+                    PromptSize.SMALL
+                }
+            )
+        assertThat(legacyState)
+            .isEqualTo(
+                if (expectConfirmation) {
+                    AuthBiometricView.STATE_PENDING_CONFIRMATION
+                } else {
+                    AuthBiometricView.STATE_AUTHENTICATED
+                }
+            )
+        assertButtonsVisible(
+            cancel = expectConfirmation,
+            confirm = expectConfirmation,
+        )
+    }
+
+    @Test
+    fun `shows temporary errors`() = runGenericTest {
+        val checkAtEnd = suspend { assertButtonsVisible(negative = true) }
+
+        showTemporaryErrors(restart = false) { checkAtEnd() }
+        showTemporaryErrors(restart = false, helpAfterError = "foo") { checkAtEnd() }
+        showTemporaryErrors(restart = true) { checkAtEnd() }
+    }
+
+    private suspend fun TestScope.showTemporaryErrors(
+        restart: Boolean,
+        helpAfterError: String = "",
+        block: suspend TestScope.() -> Unit = {},
+    ) {
+        val errorMessage = "oh no!"
+        val authenticating by collectLastValue(viewModel.isAuthenticating)
+        val authenticated by collectLastValue(viewModel.isAuthenticated)
+        val message by collectLastValue(viewModel.message)
+        val messageVisible by collectLastValue(viewModel.isIndicatorMessageVisible)
+        val size by collectLastValue(viewModel.size)
+        val legacyState by collectLastValue(viewModel.legacyState)
+        val canTryAgainNow by collectLastValue(viewModel.canTryAgainNow)
+
+        val errorJob = launch {
+            viewModel.showTemporaryError(
+                errorMessage,
+                authenticateAfterError = restart,
+                messageAfterError = helpAfterError,
+            )
+        }
+
+        assertThat(size).isEqualTo(PromptSize.MEDIUM)
+        assertThat(message).isEqualTo(PromptMessage.Error(errorMessage))
+        assertThat(messageVisible).isTrue()
+        assertThat(legacyState).isEqualTo(AuthBiometricView.STATE_ERROR)
+
+        // temporary error should disappear after a delay
+        errorJob.join()
+        if (helpAfterError.isNotBlank()) {
+            assertThat(message).isEqualTo(PromptMessage.Help(helpAfterError))
+            assertThat(messageVisible).isTrue()
+        } else {
+            assertThat(message).isEqualTo(PromptMessage.Empty)
+            assertThat(messageVisible).isFalse()
+        }
+        assertThat(legacyState)
+            .isEqualTo(
+                if (restart) {
+                    AuthBiometricView.STATE_AUTHENTICATING
+                } else {
+                    AuthBiometricView.STATE_HELP
+                }
+            )
+
+        assertThat(authenticating).isEqualTo(restart)
+        assertThat(authenticated?.isNotAuthenticated).isTrue()
+        assertThat(canTryAgainNow).isFalse()
+
+        block()
+    }
+
+    @Test
+    fun `no errors or temporary help after authenticated`() = runGenericTest {
+        val authenticating by collectLastValue(viewModel.isAuthenticating)
+        val authenticated by collectLastValue(viewModel.isAuthenticated)
+        val message by collectLastValue(viewModel.message)
+        val messageIsShowing by collectLastValue(viewModel.isIndicatorMessageVisible)
+        val canTryAgain by collectLastValue(viewModel.canTryAgainNow)
+
+        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+
+        val verifyNoError = {
+            assertThat(authenticating).isFalse()
+            assertThat(authenticated?.isAuthenticated).isTrue()
+            assertThat(message).isEqualTo(PromptMessage.Empty)
+            assertThat(canTryAgain).isFalse()
+        }
+
+        val errorJob = launch { viewModel.showTemporaryError("error") }
+        verifyNoError()
+        errorJob.join()
+        verifyNoError()
+
+        val helpJob = launch { viewModel.showTemporaryHelp("hi") }
+        verifyNoError()
+        helpJob.join()
+        verifyNoError()
+
+        // persistent help is allowed
+        val stickyHelpMessage = "blah"
+        viewModel.showHelp(stickyHelpMessage)
+        assertThat(authenticating).isFalse()
+        assertThat(authenticated?.isAuthenticated).isTrue()
+        assertThat(message).isEqualTo(PromptMessage.Help(stickyHelpMessage))
+        assertThat(messageIsShowing).isTrue()
+    }
+
+    //    @Test
+    fun `suppress errors`() = runGenericTest {
+        val errorMessage = "woot"
+        val message by collectLastValue(viewModel.message)
+
+        val errorJob = launch { viewModel.showTemporaryError(errorMessage) }
+    }
+
+    @Test
+    fun `authenticated at most once`() = runGenericTest {
+        val authenticating by collectLastValue(viewModel.isAuthenticating)
+        val authenticated by collectLastValue(viewModel.isAuthenticated)
+
+        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+
+        assertThat(authenticating).isFalse()
+        assertThat(authenticated?.isAuthenticated).isTrue()
+
+        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+
+        assertThat(authenticating).isFalse()
+        assertThat(authenticated?.isAuthenticated).isTrue()
+    }
+
+    @Test
+    fun `authenticating cannot restart after authenticated`() = runGenericTest {
+        val authenticating by collectLastValue(viewModel.isAuthenticating)
+        val authenticated by collectLastValue(viewModel.isAuthenticated)
+
+        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+
+        assertThat(authenticating).isFalse()
+        assertThat(authenticated?.isAuthenticated).isTrue()
+
+        viewModel.showAuthenticating("again!")
+
+        assertThat(authenticating).isFalse()
+        assertThat(authenticated?.isAuthenticated).isTrue()
+    }
+
+    @Test
+    fun `confirm authentication`() = runGenericTest {
+        val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
+
+        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+
+        val authenticating by collectLastValue(viewModel.isAuthenticating)
+        val authenticated by collectLastValue(viewModel.isAuthenticated)
+        val message by collectLastValue(viewModel.message)
+        val size by collectLastValue(viewModel.size)
+        val legacyState by collectLastValue(viewModel.legacyState)
+        val canTryAgain by collectLastValue(viewModel.canTryAgainNow)
+
+        assertThat(authenticated?.needsUserConfirmation).isEqualTo(expectConfirmation)
+        if (expectConfirmation) {
+            assertThat(size).isEqualTo(PromptSize.MEDIUM)
+            assertButtonsVisible(
+                cancel = true,
+                confirm = true,
+            )
+
+            viewModel.confirmAuthenticated()
+            assertThat(message).isEqualTo(PromptMessage.Empty)
+            assertButtonsVisible()
+        }
+
+        assertThat(authenticating).isFalse()
+        assertThat(authenticated?.isAuthenticated).isTrue()
+        assertThat(legacyState).isEqualTo(AuthBiometricView.STATE_AUTHENTICATED)
+        assertThat(canTryAgain).isFalse()
+    }
+
+    @Test
+    fun `cannot confirm unless authenticated`() = runGenericTest {
+        val authenticating by collectLastValue(viewModel.isAuthenticating)
+        val authenticated by collectLastValue(viewModel.isAuthenticated)
+
+        viewModel.confirmAuthenticated()
+        assertThat(authenticating).isTrue()
+        assertThat(authenticated?.isNotAuthenticated).isTrue()
+
+        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+
+        // reconfirm should be a no-op
+        viewModel.confirmAuthenticated()
+        viewModel.confirmAuthenticated()
+
+        assertThat(authenticating).isFalse()
+        assertThat(authenticated?.isNotAuthenticated).isFalse()
+    }
+
+    @Test
+    fun `shows help - before authenticated`() = runGenericTest {
+        val helpMessage = "please help yourself to some cookies"
+        val message by collectLastValue(viewModel.message)
+        val messageVisible by collectLastValue(viewModel.isIndicatorMessageVisible)
+        val size by collectLastValue(viewModel.size)
+        val legacyState by collectLastValue(viewModel.legacyState)
+
+        viewModel.showHelp(helpMessage)
+
+        assertThat(size).isEqualTo(PromptSize.MEDIUM)
+        assertThat(legacyState).isEqualTo(AuthBiometricView.STATE_HELP)
+        assertThat(message).isEqualTo(PromptMessage.Help(helpMessage))
+        assertThat(messageVisible).isTrue()
+
+        assertThat(viewModel.isAuthenticating.first()).isFalse()
+        assertThat(viewModel.isAuthenticated.first().isNotAuthenticated).isTrue()
+    }
+
+    @Test
+    fun `shows help - after authenticated`() = runGenericTest {
+        val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
+        val helpMessage = "more cookies please"
+        val authenticating by collectLastValue(viewModel.isAuthenticating)
+        val authenticated by collectLastValue(viewModel.isAuthenticated)
+        val message by collectLastValue(viewModel.message)
+        val messageVisible by collectLastValue(viewModel.isIndicatorMessageVisible)
+        val size by collectLastValue(viewModel.size)
+        val legacyState by collectLastValue(viewModel.legacyState)
+
+        if (testCase.isCoex && testCase.authenticatedByFingerprint) {
+            viewModel.ensureFingerprintHasStarted(isDelayed = true)
+        }
+        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+        viewModel.showHelp(helpMessage)
+
+        assertThat(size).isEqualTo(PromptSize.MEDIUM)
+        assertThat(legacyState).isEqualTo(AuthBiometricView.STATE_PENDING_CONFIRMATION)
+        assertThat(message).isEqualTo(PromptMessage.Help(helpMessage))
+        assertThat(messageVisible).isTrue()
+        assertThat(authenticating).isFalse()
+        assertThat(authenticated?.isAuthenticated).isTrue()
+        assertThat(authenticated?.needsUserConfirmation).isEqualTo(expectConfirmation)
+        assertButtonsVisible(
+            cancel = expectConfirmation,
+            confirm = expectConfirmation,
+        )
+    }
+
+    @Test
+    fun `retries after failure`() = runGenericTest {
+        val errorMessage = "bad"
+        val helpMessage = "again?"
+        val expectTryAgainButton = testCase.isFaceOnly
+        val authenticating by collectLastValue(viewModel.isAuthenticating)
+        val authenticated by collectLastValue(viewModel.isAuthenticated)
+        val message by collectLastValue(viewModel.message)
+        val messageVisible by collectLastValue(viewModel.isIndicatorMessageVisible)
+        val canTryAgain by collectLastValue(viewModel.canTryAgainNow)
+
+        viewModel.showAuthenticating("go")
+        val errorJob = launch {
+            viewModel.showTemporaryError(
+                errorMessage,
+                messageAfterError = helpMessage,
+                authenticateAfterError = false,
+                failedModality = testCase.authenticatedModality
+            )
+        }
+
+        assertThat(authenticating).isFalse()
+        assertThat(authenticated?.isAuthenticated).isFalse()
+        assertThat(message).isEqualTo(PromptMessage.Error(errorMessage))
+        assertThat(messageVisible).isTrue()
+        assertThat(canTryAgain).isEqualTo(testCase.authenticatedByFace)
+        assertButtonsVisible(negative = true, tryAgain = expectTryAgainButton)
+
+        errorJob.join()
+
+        assertThat(authenticating).isFalse()
+        assertThat(authenticated?.isAuthenticated).isFalse()
+        assertThat(message).isEqualTo(PromptMessage.Help(helpMessage))
+        assertThat(messageVisible).isTrue()
+        assertThat(canTryAgain).isEqualTo(testCase.authenticatedByFace)
+        assertButtonsVisible(negative = true, tryAgain = expectTryAgainButton)
+
+        val helpMessage2 = "foo"
+        viewModel.showAuthenticating(helpMessage2, isRetry = true)
+        assertThat(authenticating).isTrue()
+        assertThat(authenticated?.isAuthenticated).isFalse()
+        assertThat(message).isEqualTo(PromptMessage.Help(helpMessage2))
+        assertThat(messageVisible).isTrue()
+        assertButtonsVisible(negative = true)
+    }
+
+    @Test
+    fun `switch to credential fallback`() = runGenericTest {
+        val size by collectLastValue(viewModel.size)
+
+        // TODO(b/251476085): remove Spaghetti, migrate logic, and update this test
+        viewModel.onSwitchToCredential()
+
+        assertThat(size).isEqualTo(PromptSize.LARGE)
+    }
+
+    /** Asserts that the selected buttons are visible now. */
+    private suspend fun TestScope.assertButtonsVisible(
+        tryAgain: Boolean = false,
+        confirm: Boolean = false,
+        cancel: Boolean = false,
+        negative: Boolean = false,
+        credential: Boolean = false,
+    ) {
+        runCurrent()
+        assertThat(viewModel.isTryAgainButtonVisible.first()).isEqualTo(tryAgain)
+        assertThat(viewModel.isConfirmButtonVisible.first()).isEqualTo(confirm)
+        assertThat(viewModel.isCancelButtonVisible.first()).isEqualTo(cancel)
+        assertThat(viewModel.isNegativeButtonVisible.first()).isEqualTo(negative)
+        assertThat(viewModel.isCredentialButtonVisible.first()).isEqualTo(credential)
+    }
+
+    private fun runGenericTest(
+        doNotStart: Boolean = false,
+        allowCredentialFallback: Boolean = false,
+        block: suspend TestScope.() -> Unit
+    ) {
+        selector.initializePrompt(
+            requireConfirmation = testCase.confirmationRequested,
+            allowCredentialFallback = allowCredentialFallback,
+            fingerprint = testCase.fingerprint,
+            face = testCase.face,
+        )
+
+        // put the view model in the initial authenticating state, unless explicitly skipped
+        val startMode =
+            when {
+                doNotStart -> null
+                testCase.isCoex -> FingerprintStartMode.Delayed
+                else -> FingerprintStartMode.Normal
+            }
+        when (startMode) {
+            FingerprintStartMode.Normal -> {
+                viewModel.ensureFingerprintHasStarted(isDelayed = false)
+                viewModel.showAuthenticating()
+            }
+            FingerprintStartMode.Delayed -> {
+                viewModel.showAuthenticating()
+            }
+            else -> {
+                /* skip */
+            }
+        }
+
+        testScope.runTest { block() }
+    }
+
+    companion object {
+        @JvmStatic
+        @Parameterized.Parameters(name = "{0}")
+        fun data(): Collection<TestCase> = singleModalityTestCases + coexTestCases
+
+        private val singleModalityTestCases =
+            listOf(
+                TestCase(
+                    face = faceSensorPropertiesInternal(strong = true).first(),
+                    authenticatedModality = BiometricModality.Face,
+                ),
+                TestCase(
+                    fingerprint = fingerprintSensorPropertiesInternal(strong = true).first(),
+                    authenticatedModality = BiometricModality.Fingerprint,
+                ),
+                TestCase(
+                    face = faceSensorPropertiesInternal(strong = true).first(),
+                    authenticatedModality = BiometricModality.Face,
+                    confirmationRequested = true,
+                ),
+                TestCase(
+                    fingerprint = fingerprintSensorPropertiesInternal(strong = true).first(),
+                    authenticatedModality = BiometricModality.Fingerprint,
+                    confirmationRequested = true,
+                ),
+            )
+
+        private val coexTestCases =
+            listOf(
+                TestCase(
+                    face = faceSensorPropertiesInternal(strong = true).first(),
+                    fingerprint = fingerprintSensorPropertiesInternal(strong = true).first(),
+                    authenticatedModality = BiometricModality.Face,
+                ),
+                TestCase(
+                    face = faceSensorPropertiesInternal(strong = true).first(),
+                    fingerprint = fingerprintSensorPropertiesInternal(strong = true).first(),
+                    authenticatedModality = BiometricModality.Fingerprint,
+                ),
+                TestCase(
+                    face = faceSensorPropertiesInternal(strong = true).first(),
+                    fingerprint = fingerprintSensorPropertiesInternal(strong = true).first(),
+                    authenticatedModality = BiometricModality.Face,
+                    confirmationRequested = true,
+                ),
+                TestCase(
+                    face = faceSensorPropertiesInternal(strong = true).first(),
+                    fingerprint = fingerprintSensorPropertiesInternal(strong = true).first(),
+                    authenticatedModality = BiometricModality.Fingerprint,
+                    confirmationRequested = true,
+                ),
+            )
+    }
+}
+
+internal data class TestCase(
+    val fingerprint: FingerprintSensorPropertiesInternal? = null,
+    val face: FaceSensorPropertiesInternal? = null,
+    val authenticatedModality: BiometricModality,
+    val confirmationRequested: Boolean = false,
+) {
+    override fun toString(): String {
+        val modality =
+            when {
+                fingerprint != null && face != null -> "coex"
+                fingerprint != null -> "fingerprint only"
+                face != null -> "face only"
+                else -> "?"
+            }
+        return "[$modality, by: $authenticatedModality, confirm: $confirmationRequested]"
+    }
+
+    fun expectConfirmation(atLeastOneFailure: Boolean): Boolean =
+        when {
+            isCoex && authenticatedModality == BiometricModality.Face ->
+                atLeastOneFailure || confirmationRequested
+            isFaceOnly -> confirmationRequested
+            else -> false
+        }
+
+    val authenticatedByFingerprint: Boolean
+        get() = authenticatedModality == BiometricModality.Fingerprint
+
+    val authenticatedByFace: Boolean
+        get() = authenticatedModality == BiometricModality.Face
+
+    val isFaceOnly: Boolean
+        get() = face != null && fingerprint == null
+
+    val isFingerprintOnly: Boolean
+        get() = face == null && fingerprint != null
+
+    val isCoex: Boolean
+        get() = face != null && fingerprint != null
+
+    val shouldStartAsImplicitFlow: Boolean
+        get() = (isFaceOnly || isCoex) && !confirmationRequested
+}
+
+/** Initialize the test by selecting the give [fingerprint] or [face] configuration(s). */
+private fun PromptSelectorInteractor.initializePrompt(
+    fingerprint: FingerprintSensorPropertiesInternal? = null,
+    face: FaceSensorPropertiesInternal? = null,
+    requireConfirmation: Boolean = false,
+    allowCredentialFallback: Boolean = false,
+) {
+    val info =
+        PromptInfo().apply {
+            title = "t"
+            subtitle = "s"
+            authenticators = listOf(face, fingerprint).extractAuthenticatorTypes()
+            isDeviceCredentialAllowed = allowCredentialFallback
+            isConfirmationRequested = requireConfirmation
+        }
+    useBiometricsForAuthentication(
+        info,
+        requireConfirmation,
+        USER_ID,
+        CHALLENGE,
+        BiometricModalities(fingerprintProperties = fingerprint, faceProperties = face),
+    )
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
index 7dd376e..9f5c181 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
@@ -19,18 +19,15 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.authentication.data.repository.AuthenticationRepositoryImpl
-import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
-import com.android.systemui.bouncer.data.repo.BouncerRepository
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.scene.data.repository.fakeSceneContainerRepository
-import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.SceneTestUtils
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -44,23 +41,16 @@
 class BouncerInteractorTest : SysuiTestCase() {
 
     private val testScope = TestScope()
+    private val utils = SceneTestUtils(this, testScope)
     private val authenticationInteractor =
-        AuthenticationInteractor(
-            applicationScope = testScope.backgroundScope,
-            repository = AuthenticationRepositoryImpl(),
+        utils.authenticationInteractor(
+            repository = utils.authenticationRepository(),
         )
-    private val sceneInteractor =
-        SceneInteractor(
-            repository = fakeSceneContainerRepository(),
-        )
+    private val sceneInteractor = utils.sceneInteractor()
     private val underTest =
-        BouncerInteractor(
-            applicationScope = testScope.backgroundScope,
-            applicationContext = context,
-            repository = BouncerRepository(),
+        utils.bouncerInteractor(
             authenticationInteractor = authenticationInteractor,
             sceneInteractor = sceneInteractor,
-            containerName = "container1",
         )
 
     @Before
@@ -86,7 +76,7 @@
             assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PIN)
 
             underTest.clearMessage()
-            assertThat(message).isNull()
+            assertThat(message).isEmpty()
 
             underTest.resetMessage()
             assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PIN)
@@ -118,7 +108,7 @@
             assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PASSWORD)
 
             underTest.clearMessage()
-            assertThat(message).isNull()
+            assertThat(message).isEmpty()
 
             underTest.resetMessage()
             assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PASSWORD)
@@ -150,7 +140,7 @@
             assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PATTERN)
 
             underTest.clearMessage()
-            assertThat(message).isNull()
+            assertThat(message).isEmpty()
 
             underTest.resetMessage()
             assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PATTERN)
@@ -212,6 +202,56 @@
             assertThat(message).isEqualTo(customMessage)
         }
 
+    @Test
+    fun throttling() =
+        testScope.runTest {
+            val throttling by collectLastValue(underTest.throttling)
+            val message by collectLastValue(underTest.message)
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            assertThat(throttling).isNull()
+            assertThat(message).isEqualTo("")
+            assertThat(isUnlocked).isFalse()
+            repeat(BouncerInteractor.THROTTLE_EVERY) { times ->
+                // Wrong PIN.
+                underTest.authenticate(listOf(6, 7, 8, 9))
+                if (times < BouncerInteractor.THROTTLE_EVERY - 1) {
+                    assertThat(message).isEqualTo(MESSAGE_WRONG_PIN)
+                }
+            }
+            assertThat(throttling).isNotNull()
+            assertTryAgainMessage(message, BouncerInteractor.THROTTLE_DURATION_SEC)
+
+            // Correct PIN, but throttled, so doesn't unlock:
+            underTest.authenticate(listOf(1, 2, 3, 4))
+            assertThat(isUnlocked).isFalse()
+            assertTryAgainMessage(message, BouncerInteractor.THROTTLE_DURATION_SEC)
+
+            throttling?.totalDurationSec?.let { seconds ->
+                repeat(seconds) { time ->
+                    advanceTimeBy(1000)
+                    val remainingTime = seconds - time - 1
+                    if (remainingTime > 0) {
+                        assertTryAgainMessage(message, remainingTime)
+                    }
+                }
+            }
+            assertThat(message).isEqualTo("")
+            assertThat(throttling).isNull()
+            assertThat(isUnlocked).isFalse()
+
+            // Correct PIN and no longer throttled so unlocks:
+            underTest.authenticate(listOf(1, 2, 3, 4))
+            assertThat(isUnlocked).isTrue()
+        }
+
+    private fun assertTryAgainMessage(
+        message: String?,
+        time: Int,
+    ) {
+        assertThat(message).isEqualTo("Try again in $time seconds.")
+    }
+
     companion object {
         private const val MESSAGE_ENTER_YOUR_PIN = "Enter your PIN"
         private const val MESSAGE_ENTER_YOUR_PASSWORD = "Enter your password"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
new file mode 100644
index 0000000..b942ccb
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bouncer.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.scene.SceneTestUtils
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class BouncerViewModelTest : SysuiTestCase() {
+
+    private val testScope = TestScope()
+    private val utils = SceneTestUtils(this, testScope)
+    private val authenticationInteractor =
+        utils.authenticationInteractor(
+            repository = utils.authenticationRepository(),
+        )
+    private val bouncerInteractor =
+        utils.bouncerInteractor(
+            authenticationInteractor = authenticationInteractor,
+            sceneInteractor = utils.sceneInteractor(),
+        )
+    private val underTest = utils.bouncerViewModel(bouncerInteractor)
+
+    @Test
+    fun authMethod_nonNullForSecureMethods_nullForNotSecureMethods() =
+        testScope.runTest {
+            val authMethodViewModel: AuthMethodBouncerViewModel? by
+                collectLastValue(underTest.authMethod)
+            authMethodsToTest().forEach { authMethod ->
+                authenticationInteractor.setAuthenticationMethod(authMethod)
+
+                if (authMethod.isSecure) {
+                    assertThat(authMethodViewModel).isNotNull()
+                } else {
+                    assertThat(authMethodViewModel).isNull()
+                }
+            }
+        }
+
+    @Test
+    fun authMethod_reusesInstances() =
+        testScope.runTest {
+            val seen = mutableMapOf<AuthenticationMethodModel, AuthMethodBouncerViewModel>()
+            val authMethodViewModel: AuthMethodBouncerViewModel? by
+                collectLastValue(underTest.authMethod)
+            // First pass, populate our "seen" map:
+            authMethodsToTest().forEach { authMethod ->
+                authenticationInteractor.setAuthenticationMethod(authMethod)
+                authMethodViewModel?.let { seen[authMethod] = it }
+            }
+
+            // Second pass, assert same instances are reused:
+            authMethodsToTest().forEach { authMethod ->
+                authenticationInteractor.setAuthenticationMethod(authMethod)
+                authMethodViewModel?.let { assertThat(it).isSameInstanceAs(seen[authMethod]) }
+            }
+        }
+
+    @Test
+    fun authMethodsToTest_returnsCompleteSampleOfAllAuthMethodTypes() {
+        assertThat(authMethodsToTest().map { it::class }.toSet())
+            .isEqualTo(AuthenticationMethodModel::class.sealedSubclasses.toSet())
+    }
+
+    @Test
+    fun isMessageUpdateAnimationsEnabled() =
+        testScope.runTest {
+            val isMessageUpdateAnimationsEnabled by
+                collectLastValue(underTest.isMessageUpdateAnimationsEnabled)
+            val throttling by collectLastValue(bouncerInteractor.throttling)
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            assertThat(isMessageUpdateAnimationsEnabled).isTrue()
+
+            repeat(BouncerInteractor.THROTTLE_EVERY) {
+                // Wrong PIN.
+                bouncerInteractor.authenticate(listOf(3, 4, 5, 6))
+            }
+            assertThat(isMessageUpdateAnimationsEnabled).isFalse()
+
+            throttling?.totalDurationSec?.let { seconds -> advanceTimeBy(seconds * 1000L) }
+            assertThat(isMessageUpdateAnimationsEnabled).isTrue()
+        }
+
+    @Test
+    fun isInputEnabled() =
+        testScope.runTest {
+            val isInputEnabled by
+                collectLastValue(
+                    underTest.authMethod.flatMapLatest { authViewModel ->
+                        authViewModel?.isInputEnabled ?: emptyFlow()
+                    }
+                )
+            val throttling by collectLastValue(bouncerInteractor.throttling)
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            assertThat(isInputEnabled).isTrue()
+
+            repeat(BouncerInteractor.THROTTLE_EVERY) {
+                // Wrong PIN.
+                bouncerInteractor.authenticate(listOf(3, 4, 5, 6))
+            }
+            assertThat(isInputEnabled).isFalse()
+
+            throttling?.totalDurationSec?.let { seconds -> advanceTimeBy(seconds * 1000L) }
+            assertThat(isInputEnabled).isTrue()
+        }
+
+    @Test
+    fun throttlingDialogMessage() =
+        testScope.runTest {
+            val throttlingDialogMessage by collectLastValue(underTest.throttlingDialogMessage)
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+
+            repeat(BouncerInteractor.THROTTLE_EVERY) {
+                // Wrong PIN.
+                assertThat(throttlingDialogMessage).isNull()
+                bouncerInteractor.authenticate(listOf(3, 4, 5, 6))
+            }
+            assertThat(throttlingDialogMessage).isNotEmpty()
+
+            underTest.onThrottlingDialogDismissed()
+            assertThat(throttlingDialogMessage).isNull()
+        }
+
+    private fun authMethodsToTest(): List<AuthenticationMethodModel> {
+        return listOf(
+            AuthenticationMethodModel.None,
+            AuthenticationMethodModel.Swipe,
+            AuthenticationMethodModel.PIN(1234),
+            AuthenticationMethodModel.Password("password"),
+            AuthenticationMethodModel.Pattern(
+                listOf(AuthenticationMethodModel.Pattern.PatternCoordinate(1, 1))
+            ),
+        )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
new file mode 100644
index 0000000..b7b90de
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bouncer.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.scene.SceneTestUtils
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class PasswordBouncerViewModelTest : SysuiTestCase() {
+
+    private val testScope = TestScope()
+    private val utils = SceneTestUtils(this, testScope)
+    private val authenticationInteractor =
+        utils.authenticationInteractor(
+            repository = utils.authenticationRepository(),
+        )
+    private val sceneInteractor = utils.sceneInteractor()
+    private val bouncerInteractor =
+        utils.bouncerInteractor(
+            authenticationInteractor = authenticationInteractor,
+            sceneInteractor = sceneInteractor,
+        )
+    private val bouncerViewModel =
+        utils.bouncerViewModel(
+            bouncerInteractor = bouncerInteractor,
+        )
+    private val underTest =
+        PasswordBouncerViewModel(
+            interactor = bouncerInteractor,
+            isInputEnabled = MutableStateFlow(true).asStateFlow(),
+        )
+
+    @Before
+    fun setUp() {
+        overrideResource(R.string.keyguard_enter_your_password, ENTER_YOUR_PASSWORD)
+        overrideResource(R.string.kg_wrong_password, WRONG_PASSWORD)
+    }
+
+    @Test
+    fun onShown() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val message by collectLastValue(bouncerViewModel.message)
+            val password by collectLastValue(underTest.password)
+            authenticationInteractor.setAuthenticationMethod(
+                AuthenticationMethodModel.Password("password")
+            )
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+
+            underTest.onShown()
+
+            assertThat(message).isEqualTo(ENTER_YOUR_PASSWORD)
+            assertThat(password).isEqualTo("")
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
+    fun onPasswordInputChanged() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val message by collectLastValue(bouncerViewModel.message)
+            val password by collectLastValue(underTest.password)
+            authenticationInteractor.setAuthenticationMethod(
+                AuthenticationMethodModel.Password("password")
+            )
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+
+            underTest.onPasswordInputChanged("password")
+
+            assertThat(message).isEmpty()
+            assertThat(password).isEqualTo("password")
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
+    fun onAuthenticateKeyPressed_whenCorrect() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            authenticationInteractor.setAuthenticationMethod(
+                AuthenticationMethodModel.Password("password")
+            )
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+            underTest.onPasswordInputChanged("password")
+
+            underTest.onAuthenticateKeyPressed()
+
+            assertThat(isUnlocked).isTrue()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+        }
+
+    @Test
+    fun onAuthenticateKeyPressed_whenWrong() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val message by collectLastValue(bouncerViewModel.message)
+            val password by collectLastValue(underTest.password)
+            authenticationInteractor.setAuthenticationMethod(
+                AuthenticationMethodModel.Password("password")
+            )
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+            underTest.onPasswordInputChanged("wrong")
+
+            underTest.onAuthenticateKeyPressed()
+
+            assertThat(password).isEqualTo("")
+            assertThat(message).isEqualTo(WRONG_PASSWORD)
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
+    fun onAuthenticateKeyPressed_correctAfterWrong() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val message by collectLastValue(bouncerViewModel.message)
+            val password by collectLastValue(underTest.password)
+            authenticationInteractor.setAuthenticationMethod(
+                AuthenticationMethodModel.Password("password")
+            )
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+            underTest.onPasswordInputChanged("wrong")
+            underTest.onAuthenticateKeyPressed()
+            assertThat(password).isEqualTo("")
+            assertThat(message).isEqualTo(WRONG_PASSWORD)
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+
+            // Enter the correct password:
+            underTest.onPasswordInputChanged("password")
+            assertThat(message).isEmpty()
+
+            underTest.onAuthenticateKeyPressed()
+
+            assertThat(isUnlocked).isTrue()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+        }
+
+    companion object {
+        private const val CONTAINER_NAME = "container1"
+        private const val ENTER_YOUR_PASSWORD = "Enter your password"
+        private const val WRONG_PASSWORD = "Wrong password"
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
new file mode 100644
index 0000000..b588ba2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bouncer.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.scene.SceneTestUtils
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class PatternBouncerViewModelTest : SysuiTestCase() {
+
+    private val testScope = TestScope()
+    private val utils = SceneTestUtils(this, testScope)
+    private val authenticationInteractor =
+        utils.authenticationInteractor(
+            repository = utils.authenticationRepository(),
+        )
+    private val sceneInteractor = utils.sceneInteractor()
+    private val bouncerInteractor =
+        utils.bouncerInteractor(
+            authenticationInteractor = authenticationInteractor,
+            sceneInteractor = sceneInteractor,
+        )
+    private val bouncerViewModel =
+        utils.bouncerViewModel(
+            bouncerInteractor = bouncerInteractor,
+        )
+    private val underTest =
+        PatternBouncerViewModel(
+            applicationContext = context,
+            applicationScope = testScope.backgroundScope,
+            interactor = bouncerInteractor,
+            isInputEnabled = MutableStateFlow(true).asStateFlow(),
+        )
+
+    @Before
+    fun setUp() {
+        overrideResource(R.string.keyguard_enter_your_pattern, ENTER_YOUR_PATTERN)
+        overrideResource(R.string.kg_wrong_pattern, WRONG_PATTERN)
+    }
+
+    @Test
+    fun onShown() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val message by collectLastValue(bouncerViewModel.message)
+            val selectedDots by collectLastValue(underTest.selectedDots)
+            val currentDot by collectLastValue(underTest.currentDot)
+            authenticationInteractor.setAuthenticationMethod(
+                AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
+            )
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+
+            underTest.onShown()
+
+            assertThat(message).isEqualTo(ENTER_YOUR_PATTERN)
+            assertThat(selectedDots).isEmpty()
+            assertThat(currentDot).isNull()
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
+    fun onDragStart() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val message by collectLastValue(bouncerViewModel.message)
+            val selectedDots by collectLastValue(underTest.selectedDots)
+            val currentDot by collectLastValue(underTest.currentDot)
+            authenticationInteractor.setAuthenticationMethod(
+                AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
+            )
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+
+            underTest.onDragStart()
+
+            assertThat(message).isEmpty()
+            assertThat(selectedDots).isEmpty()
+            assertThat(currentDot).isNull()
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
+    fun onDragEnd_whenCorrect() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val selectedDots by collectLastValue(underTest.selectedDots)
+            val currentDot by collectLastValue(underTest.currentDot)
+            authenticationInteractor.setAuthenticationMethod(
+                AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
+            )
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+            underTest.onDragStart()
+            assertThat(currentDot).isNull()
+            CORRECT_PATTERN.forEachIndexed { index, coordinate ->
+                underTest.onDrag(
+                    xPx = 30f * coordinate.x + 15,
+                    yPx = 30f * coordinate.y + 15,
+                    containerSizePx = 90,
+                    verticalOffsetPx = 0f,
+                )
+                assertWithMessage("Wrong selected dots for index $index")
+                    .that(selectedDots)
+                    .isEqualTo(
+                        CORRECT_PATTERN.subList(0, index + 1).map {
+                            PatternDotViewModel(
+                                x = it.x,
+                                y = it.y,
+                            )
+                        }
+                    )
+                assertWithMessage("Wrong current dot for index $index")
+                    .that(currentDot)
+                    .isEqualTo(
+                        PatternDotViewModel(
+                            x = CORRECT_PATTERN.subList(0, index + 1).last().x,
+                            y = CORRECT_PATTERN.subList(0, index + 1).last().y,
+                        )
+                    )
+            }
+
+            underTest.onDragEnd()
+
+            assertThat(isUnlocked).isTrue()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+        }
+
+    @Test
+    fun onDragEnd_whenWrong() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val message by collectLastValue(bouncerViewModel.message)
+            val selectedDots by collectLastValue(underTest.selectedDots)
+            val currentDot by collectLastValue(underTest.currentDot)
+            authenticationInteractor.setAuthenticationMethod(
+                AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
+            )
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+            underTest.onDragStart()
+            CORRECT_PATTERN.subList(0, 3).forEach { coordinate ->
+                underTest.onDrag(
+                    xPx = 30f * coordinate.x + 15,
+                    yPx = 30f * coordinate.y + 15,
+                    containerSizePx = 90,
+                    verticalOffsetPx = 0f,
+                )
+            }
+
+            underTest.onDragEnd()
+
+            assertThat(selectedDots).isEmpty()
+            assertThat(currentDot).isNull()
+            assertThat(message).isEqualTo(WRONG_PATTERN)
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
+    fun onDragEnd_correctAfterWrong() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val message by collectLastValue(bouncerViewModel.message)
+            val selectedDots by collectLastValue(underTest.selectedDots)
+            val currentDot by collectLastValue(underTest.currentDot)
+            authenticationInteractor.setAuthenticationMethod(
+                AuthenticationMethodModel.Pattern(CORRECT_PATTERN)
+            )
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+            underTest.onDragStart()
+            CORRECT_PATTERN.subList(2, 7).forEach { coordinate ->
+                underTest.onDrag(
+                    xPx = 30f * coordinate.x + 15,
+                    yPx = 30f * coordinate.y + 15,
+                    containerSizePx = 90,
+                    verticalOffsetPx = 0f,
+                )
+            }
+            underTest.onDragEnd()
+            assertThat(selectedDots).isEmpty()
+            assertThat(currentDot).isNull()
+            assertThat(message).isEqualTo(WRONG_PATTERN)
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+
+            // Enter the correct pattern:
+            CORRECT_PATTERN.forEach { coordinate ->
+                underTest.onDrag(
+                    xPx = 30f * coordinate.x + 15,
+                    yPx = 30f * coordinate.y + 15,
+                    containerSizePx = 90,
+                    verticalOffsetPx = 0f,
+                )
+            }
+
+            underTest.onDragEnd()
+
+            assertThat(isUnlocked).isTrue()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+        }
+
+    companion object {
+        private const val CONTAINER_NAME = "container1"
+        private const val ENTER_YOUR_PATTERN = "Enter your pattern"
+        private const val WRONG_PATTERN = "Wrong pattern"
+        private val CORRECT_PATTERN =
+            listOf(
+                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 1, y = 1),
+                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 0, y = 1),
+                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 0, y = 0),
+                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 1, y = 0),
+                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 2, y = 0),
+                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 2, y = 1),
+                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 2, y = 2),
+                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 1, y = 2),
+                AuthenticationMethodModel.Pattern.PatternCoordinate(x = 0, y = 2),
+            )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
new file mode 100644
index 0000000..83f9687
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bouncer.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.scene.SceneTestUtils
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class PinBouncerViewModelTest : SysuiTestCase() {
+
+    private val testScope = TestScope()
+    private val utils = SceneTestUtils(this, testScope)
+    private val sceneInteractor = utils.sceneInteractor()
+    private val authenticationInteractor =
+        utils.authenticationInteractor(
+            repository = utils.authenticationRepository(),
+        )
+    private val bouncerInteractor =
+        utils.bouncerInteractor(
+            authenticationInteractor = authenticationInteractor,
+            sceneInteractor = sceneInteractor,
+        )
+    private val bouncerViewModel =
+        BouncerViewModel(
+            applicationContext = context,
+            applicationScope = testScope.backgroundScope,
+            interactorFactory =
+                object : BouncerInteractor.Factory {
+                    override fun create(containerName: String): BouncerInteractor {
+                        return bouncerInteractor
+                    }
+                },
+            containerName = CONTAINER_NAME,
+        )
+    private val underTest =
+        PinBouncerViewModel(
+            applicationScope = testScope.backgroundScope,
+            interactor = bouncerInteractor,
+            isInputEnabled = MutableStateFlow(true).asStateFlow(),
+        )
+
+    @Before
+    fun setUp() {
+        overrideResource(R.string.keyguard_enter_your_pin, ENTER_YOUR_PIN)
+        overrideResource(R.string.kg_wrong_pin, WRONG_PIN)
+    }
+
+    @Test
+    fun onShown() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val message by collectLastValue(bouncerViewModel.message)
+            val pinLengths by collectLastValue(underTest.pinLengths)
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+
+            underTest.onShown()
+
+            assertThat(message).isEqualTo(ENTER_YOUR_PIN)
+            assertThat(pinLengths).isEqualTo(0 to 0)
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
+    fun onPinButtonClicked() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val message by collectLastValue(bouncerViewModel.message)
+            val pinLengths by collectLastValue(underTest.pinLengths)
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+
+            underTest.onPinButtonClicked(1)
+
+            assertThat(message).isEmpty()
+            assertThat(pinLengths).isEqualTo(0 to 1)
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
+    fun onBackspaceButtonClicked() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val message by collectLastValue(bouncerViewModel.message)
+            val pinLengths by collectLastValue(underTest.pinLengths)
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+            underTest.onPinButtonClicked(1)
+            assertThat(pinLengths).isEqualTo(0 to 1)
+
+            underTest.onBackspaceButtonClicked()
+
+            assertThat(message).isEmpty()
+            assertThat(pinLengths).isEqualTo(1 to 0)
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
+    fun onBackspaceButtonLongPressed() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val message by collectLastValue(bouncerViewModel.message)
+            val pinLengths by collectLastValue(underTest.pinLengths)
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+            underTest.onPinButtonClicked(1)
+            underTest.onPinButtonClicked(2)
+            underTest.onPinButtonClicked(3)
+            underTest.onPinButtonClicked(4)
+
+            underTest.onBackspaceButtonLongPressed()
+            repeat(4) { index ->
+                assertThat(pinLengths).isEqualTo(4 - index to 3 - index)
+                advanceTimeBy(PinBouncerViewModel.BACKSPACE_LONG_PRESS_DELAY_MS)
+            }
+
+            assertThat(message).isEmpty()
+            assertThat(pinLengths).isEqualTo(1 to 0)
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
+    fun onAuthenticateButtonClicked_whenCorrect() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+            underTest.onPinButtonClicked(1)
+            underTest.onPinButtonClicked(2)
+            underTest.onPinButtonClicked(3)
+            underTest.onPinButtonClicked(4)
+
+            underTest.onAuthenticateButtonClicked()
+
+            assertThat(isUnlocked).isTrue()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+        }
+
+    @Test
+    fun onAuthenticateButtonClicked_whenWrong() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val message by collectLastValue(bouncerViewModel.message)
+            val pinLengths by collectLastValue(underTest.pinLengths)
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+            underTest.onPinButtonClicked(1)
+            underTest.onPinButtonClicked(2)
+            underTest.onPinButtonClicked(3)
+            underTest.onPinButtonClicked(4)
+            underTest.onPinButtonClicked(5) // PIN is now wrong!
+
+            underTest.onAuthenticateButtonClicked()
+
+            assertThat(pinLengths).isEqualTo(0 to 0)
+            assertThat(message).isEqualTo(WRONG_PIN)
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
+    fun onAuthenticateButtonClicked_correctAfterWrong() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+            val message by collectLastValue(bouncerViewModel.message)
+            val pinLengths by collectLastValue(underTest.pinLengths)
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+            underTest.onShown()
+            underTest.onPinButtonClicked(1)
+            underTest.onPinButtonClicked(2)
+            underTest.onPinButtonClicked(3)
+            underTest.onPinButtonClicked(4)
+            underTest.onPinButtonClicked(5) // PIN is now wrong!
+            underTest.onAuthenticateButtonClicked()
+            assertThat(message).isEqualTo(WRONG_PIN)
+            assertThat(pinLengths).isEqualTo(0 to 0)
+            assertThat(isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+
+            // Enter the correct PIN:
+            underTest.onPinButtonClicked(1)
+            underTest.onPinButtonClicked(2)
+            underTest.onPinButtonClicked(3)
+            underTest.onPinButtonClicked(4)
+            assertThat(message).isEmpty()
+
+            underTest.onAuthenticateButtonClicked()
+
+            assertThat(isUnlocked).isTrue()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+        }
+
+    companion object {
+        private const val CONTAINER_NAME = "container1"
+        private const val ENTER_YOUR_PIN = "Enter your pin"
+        private const val WRONG_PIN = "Wrong pin"
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
index 4cb99a2..6afbde0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
@@ -120,7 +120,6 @@
                 gestureCompleteListenerCaptor.capture());
 
         mGestureFinalizedListener = gestureCompleteListenerCaptor.getValue();
-        mFakeFeatureFlags.set(Flags.MEDIA_FALSING_PENALTY, true);
         mFakeFeatureFlags.set(Flags.FALSING_OFF_FOR_UNFOLDED, true);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java
index 3cbb249..63b0b25 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java
@@ -29,6 +29,7 @@
 
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.res.Resources;
 import android.testing.AndroidTestingRunner;
 import android.view.View;
 
@@ -73,6 +74,9 @@
     private Context mContext;
 
     @Mock
+    private Resources mResources;
+
+    @Mock
     private ControlsComponent mControlsComponent;
 
     @Mock
@@ -118,7 +122,7 @@
     @Test
     public void complicationType() {
         final DreamHomeControlsComplication complication =
-                new DreamHomeControlsComplication(mComponentFactory);
+                new DreamHomeControlsComplication(mResources, mComponentFactory);
         assertThat(complication.getRequiredTypeAvailability()).isEqualTo(
                 COMPLICATION_TYPE_HOME_CONTROLS);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
index 1a620d2..fcd6568 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
@@ -70,7 +70,9 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.doAnswer
 import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.isNull
 import org.mockito.Mockito.never
 import org.mockito.Mockito.spy
 import org.mockito.Mockito.verify
@@ -104,6 +106,9 @@
     private lateinit var parent: FrameLayout
     private lateinit var underTest: ControlsUiControllerImpl
 
+    private var isKeyguardDismissed: Boolean = true
+    private var isRemoveAppDialogCreated: Boolean = false
+
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
@@ -140,11 +145,23 @@
                 authorizedPanelsRepository,
                 preferredPanelRepository,
                 featureFlags,
-                ControlsDialogsFactory { fakeDialogController.dialog },
+                ControlsDialogsFactory {
+                    isRemoveAppDialogCreated = true
+                    fakeDialogController.dialog
+                },
                 dumpManager,
             )
         `when`(userTracker.userId).thenReturn(0)
         `when`(userTracker.userHandle).thenReturn(UserHandle.of(0))
+        doAnswer {
+                if (isKeyguardDismissed) {
+                    it.getArgument<ActivityStarter.OnDismissAction>(0).onDismiss()
+                } else {
+                    it.getArgument<Runnable?>(1)?.run()
+                }
+            }
+            .whenever(activityStarter)
+            .dismissKeyguardThenExecute(any(), isNull(), any())
     }
 
     @Test
@@ -414,6 +431,26 @@
     }
 
     @Test
+    fun testKeyguardRemovingAppsNotShowingDialog() {
+        isKeyguardDismissed = false
+        val componentName = ComponentName(context, "cls")
+        whenever(controlsController.removeFavorites(eq(componentName))).thenReturn(true)
+        val panel = SelectedItem.PanelItem("App name", componentName)
+        preferredPanelRepository.setSelectedComponent(
+            SelectedComponentRepository.SelectedComponent(panel)
+        )
+        underTest.show(parent, {}, context)
+        underTest.startRemovingApp(componentName, "Test App")
+
+        assertThat(isRemoveAppDialogCreated).isFalse()
+        verify(controlsController, never()).removeFavorites(eq(componentName))
+        assertThat(underTest.getPreferredSelectedItem(emptyList())).isEqualTo(panel)
+        assertThat(preferredPanelRepository.shouldAddDefaultComponent()).isTrue()
+        assertThat(preferredPanelRepository.getSelectedComponent())
+            .isEqualTo(SelectedComponentRepository.SelectedComponent(panel))
+    }
+
+    @Test
     fun testCancelRemovingAppsDoesntRemoveFavorite() {
         val componentName = ComponentName(context, "cls")
         whenever(controlsController.removeFavorites(eq(componentName))).thenReturn(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/backlight/ui/KeyboardBacklightDialogCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/backlight/ui/KeyboardBacklightDialogCoordinatorTest.kt
new file mode 100644
index 0000000..7207fbf
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/backlight/ui/KeyboardBacklightDialogCoordinatorTest.kt
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyboard.backlight.ui
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.keyboard.backlight.domain.interactor.KeyboardBacklightInteractor
+import com.android.systemui.keyboard.backlight.ui.view.KeyboardBacklightDialog
+import com.android.systemui.keyboard.backlight.ui.viewmodel.BacklightDialogViewModel
+import com.android.systemui.keyboard.data.repository.FakeKeyboardRepository
+import com.android.systemui.keyboard.shared.model.BacklightModel
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class KeyboardBacklightDialogCoordinatorTest : SysuiTestCase() {
+
+    @Mock private lateinit var accessibilityManagerWrapper: AccessibilityManagerWrapper
+    @Mock private lateinit var dialog: KeyboardBacklightDialog
+
+    private val keyboardRepository = FakeKeyboardRepository()
+    private lateinit var underTest: KeyboardBacklightDialogCoordinator
+    private val timeoutMillis = 3000L
+    private val testScope = TestScope(StandardTestDispatcher())
+
+    private val createDialog = { value: Int, maxValue: Int ->
+        dialogCreationValue = value
+        dialogCreationMaxValue = maxValue
+        dialog
+    }
+    private var dialogCreationValue = -1
+    private var dialogCreationMaxValue = -1
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        whenever(accessibilityManagerWrapper.getRecommendedTimeoutMillis(any(), any()))
+            .thenReturn(timeoutMillis.toInt())
+        val viewModel =
+            BacklightDialogViewModel(
+                KeyboardBacklightInteractor(keyboardRepository),
+                accessibilityManagerWrapper
+            )
+        underTest =
+            KeyboardBacklightDialogCoordinator(testScope.backgroundScope, viewModel, createDialog)
+        underTest.startListening()
+        keyboardRepository.setIsAnyKeyboardConnected(true)
+    }
+
+    @Test
+    fun showsDialog_afterBacklightChange() =
+        testScope.runTest {
+            setBacklightValue(1)
+
+            verify(dialog).show()
+        }
+
+    @Test
+    fun updatesDialog_withLatestValues_afterBacklightChange() =
+        testScope.runTest {
+            setBacklightValue(value = 1, maxValue = 5)
+            setBacklightValue(value = 2, maxValue = 5)
+
+            verify(dialog).updateState(2, 5)
+        }
+
+    @Test
+    fun showsDialog_withDataFromBacklightChange() =
+        testScope.runTest {
+            setBacklightValue(value = 4, maxValue = 5)
+
+            Truth.assertThat(dialogCreationValue).isEqualTo(4)
+            Truth.assertThat(dialogCreationMaxValue).isEqualTo(5)
+        }
+
+    @Test
+    fun dismissesDialog_afterTimeout() =
+        testScope.runTest {
+            setBacklightValue(1)
+
+            advanceTimeBy(timeoutMillis + 1)
+
+            verify(dialog).dismiss()
+        }
+
+    @Test
+    fun dismissesDialog_onlyAfterTimeout_fromLastBacklightChange() =
+        testScope.runTest {
+            setBacklightValue(1)
+            advanceTimeBy(timeoutMillis * 2 / 3)
+            // majority of timeout passed
+
+            // this should restart timeout
+            setBacklightValue(2)
+            advanceTimeBy(timeoutMillis * 2 / 3)
+            verify(dialog, never()).dismiss()
+
+            advanceTimeBy(timeoutMillis * 2 / 3)
+            // finally timeout reached and dialog was dismissed
+            verify(dialog, times(1)).dismiss()
+        }
+
+    @Test
+    fun showsDialog_ifItWasAlreadyShownAndDismissedBySomethingElse() =
+        testScope.runTest {
+            setBacklightValue(1)
+            // let's pretend dialog is dismissed e.g. by user tapping on the screen
+            whenever(dialog.isShowing).thenReturn(false)
+
+            // no advancing time, we're still in timeout period
+            setBacklightValue(2)
+
+            verify(dialog, times(2)).show()
+        }
+
+    private fun TestScope.setBacklightValue(value: Int, maxValue: Int = MAX_BACKLIGHT) {
+        keyboardRepository.setBacklight(BacklightModel(value, maxValue))
+        runCurrent()
+    }
+
+    private companion object {
+        const val MAX_BACKLIGHT = 5
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/backlight/ui/viewmodel/BacklightDialogViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/backlight/ui/viewmodel/BacklightDialogViewModelTest.kt
deleted file mode 100644
index 1fec5a4..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/backlight/ui/viewmodel/BacklightDialogViewModelTest.kt
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package com.android.systemui.keyboard.backlight.ui.viewmodel
-
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyboard.backlight.domain.interactor.KeyboardBacklightInteractor
-import com.android.systemui.keyboard.data.repository.FakeKeyboardRepository
-import com.android.systemui.keyboard.shared.model.BacklightModel
-import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.whenever
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.test.advanceTimeBy
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
-
-@OptIn(ExperimentalCoroutinesApi::class)
-@SmallTest
-@RunWith(JUnit4::class)
-class BacklightDialogViewModelTest : SysuiTestCase() {
-
-    private val keyboardRepository = FakeKeyboardRepository()
-    private lateinit var underTest: BacklightDialogViewModel
-    @Mock private lateinit var accessibilityManagerWrapper: AccessibilityManagerWrapper
-    private val timeoutMillis = 3000L
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        whenever(accessibilityManagerWrapper.getRecommendedTimeoutMillis(any(), any()))
-            .thenReturn(timeoutMillis.toInt())
-        underTest =
-            BacklightDialogViewModel(
-                KeyboardBacklightInteractor(keyboardRepository),
-                accessibilityManagerWrapper
-            )
-        keyboardRepository.setIsAnyKeyboardConnected(true)
-    }
-
-    @Test
-    fun emitsViewModel_whenBacklightChanged() = runTest {
-        keyboardRepository.setBacklight(BacklightModel(1, 5))
-
-        assertThat(underTest.dialogContent.first()).isEqualTo(BacklightDialogContentViewModel(1, 5))
-    }
-
-    @Test
-    fun emitsNull_afterTimeout() = runTest {
-        val latest by collectLastValue(underTest.dialogContent)
-        keyboardRepository.setBacklight(BacklightModel(1, 5))
-
-        assertThat(latest).isEqualTo(BacklightDialogContentViewModel(1, 5))
-        advanceTimeBy(timeoutMillis + 1)
-        assertThat(latest).isNull()
-    }
-
-    @Test
-    fun emitsNull_after5secDelay_fromLastBacklightChange() = runTest {
-        val latest by collectLastValue(underTest.dialogContent)
-        keyboardRepository.setIsAnyKeyboardConnected(true)
-
-        keyboardRepository.setBacklight(BacklightModel(1, 5))
-        assertThat(latest).isEqualTo(BacklightDialogContentViewModel(1, 5))
-
-        advanceTimeBy(timeoutMillis * 2 / 3)
-        // timeout yet to pass, no new emission
-        keyboardRepository.setBacklight(BacklightModel(2, 5))
-        assertThat(latest).isEqualTo(BacklightDialogContentViewModel(2, 5))
-
-        advanceTimeBy(timeoutMillis * 2 / 3)
-        // timeout refreshed because of last `setBacklight`, still content present
-        assertThat(latest).isEqualTo(BacklightDialogContentViewModel(2, 5))
-
-        advanceTimeBy(timeoutMillis * 2 / 3)
-        // finally timeout reached and null emitted
-        assertThat(latest).isNull()
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
index 9cf988e..8ee7d3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -30,6 +30,7 @@
 import android.view.SurfaceControlViewHost
 import androidx.test.filters.SmallTest
 import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.R
 import com.android.systemui.SystemUIAppComponentFactoryBase
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogLaunchAnimator
@@ -67,6 +68,7 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
+import org.junit.After
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -103,6 +105,7 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
+        overrideResource(R.bool.custom_lockscreen_shortcuts_enabled, true)
         whenever(previewRenderer.surfacePackage).thenReturn(previewSurfacePackage)
         whenever(previewRendererFactory.create(any())).thenReturn(previewRenderer)
         whenever(backgroundHandler.looper).thenReturn(TestableLooper.get(this).looper)
@@ -195,6 +198,7 @@
                 devicePolicyManager = devicePolicyManager,
                 dockManager = dockManager,
                 backgroundDispatcher = testDispatcher,
+                appContext = mContext,
             )
         underTest.previewManager =
             KeyguardRemotePreviewManager(
@@ -216,6 +220,13 @@
         )
     }
 
+    @After
+    fun tearDown() {
+        mContext
+            .getOrCreateTestableResources()
+            .removeOverride(R.bool.custom_lockscreen_shortcuts_enabled)
+    }
+
     @Test
     fun onAttachInfo_reportsContext() {
         val callback: SystemUIAppComponentFactoryBase.ContextAvailableCallback = mock()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
index 0a9618c..477e076 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
@@ -10,6 +10,7 @@
 import android.view.RemoteAnimationTarget
 import android.view.SurfaceControl
 import android.view.SyncRtSurfaceTransactionApplier
+import android.view.View
 import android.view.ViewRootImpl
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardViewController
@@ -32,6 +33,7 @@
 import org.mockito.Mock
 import org.mockito.Mockito.atLeastOnce
 import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
@@ -114,7 +116,6 @@
     @After
     fun tearDown() {
         keyguardUnlockAnimationController.notifyFinishedKeyguardExitAnimation(true)
-        keyguardUnlockAnimationController.wallpaperAlphaAnimator.cancel()
     }
 
     /**
@@ -375,6 +376,83 @@
         verifyNoMoreInteractions(surfaceTransactionApplier)
     }
 
+    @Test
+    fun unlockToLauncherWithInWindowAnimations_ssViewIsVisible() {
+        val mockLockscreenSmartspaceView = mock(View::class.java)
+        whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.VISIBLE)
+        keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
+
+        keyguardUnlockAnimationController.unlockToLauncherWithInWindowAnimations()
+
+        verify(mockLockscreenSmartspaceView).visibility = View.INVISIBLE
+    }
+
+    @Test
+    fun unlockToLauncherWithInWindowAnimations_ssViewIsInvisible() {
+        val mockLockscreenSmartspaceView = mock(View::class.java)
+        whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.INVISIBLE)
+        keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
+
+        keyguardUnlockAnimationController.unlockToLauncherWithInWindowAnimations()
+
+        verify(mockLockscreenSmartspaceView, never()).visibility = View.INVISIBLE
+    }
+
+    @Test
+    fun unlockToLauncherWithInWindowAnimations_ssViewIsGone() {
+        val mockLockscreenSmartspaceView = mock(View::class.java)
+        whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.GONE)
+        keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
+
+        keyguardUnlockAnimationController.unlockToLauncherWithInWindowAnimations()
+
+        verify(mockLockscreenSmartspaceView, never()).visibility = View.INVISIBLE
+    }
+
+    @Test
+    fun notifyFinishedKeyguardExitAnimation_ssViewIsInvisibleAndCancelledIsTrue() {
+        val mockLockscreenSmartspaceView = mock(View::class.java)
+        whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.INVISIBLE)
+        keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
+
+        keyguardUnlockAnimationController.notifyFinishedKeyguardExitAnimation(true)
+
+        verify(mockLockscreenSmartspaceView).visibility = View.VISIBLE
+    }
+
+    @Test
+    fun notifyFinishedKeyguardExitAnimation_ssViewIsGoneAndCancelledIsTrue() {
+        val mockLockscreenSmartspaceView = mock(View::class.java)
+        whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.GONE)
+        keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
+
+        keyguardUnlockAnimationController.notifyFinishedKeyguardExitAnimation(true)
+
+        verify(mockLockscreenSmartspaceView, never()).visibility = View.VISIBLE
+    }
+
+    @Test
+    fun notifyFinishedKeyguardExitAnimation_ssViewIsInvisibleAndCancelledIsFalse() {
+        val mockLockscreenSmartspaceView = mock(View::class.java)
+        whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.INVISIBLE)
+        keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
+
+        keyguardUnlockAnimationController.notifyFinishedKeyguardExitAnimation(false)
+
+        verify(mockLockscreenSmartspaceView).visibility = View.VISIBLE
+    }
+
+    @Test
+    fun notifyFinishedKeyguardExitAnimation_ssViewIsGoneAndCancelledIsFalse() {
+        val mockLockscreenSmartspaceView = mock(View::class.java)
+        whenever(mockLockscreenSmartspaceView.visibility).thenReturn(View.GONE)
+        keyguardUnlockAnimationController.lockscreenSmartspace = mockLockscreenSmartspaceView
+
+        keyguardUnlockAnimationController.notifyFinishedKeyguardExitAnimation(false)
+
+        verify(mockLockscreenSmartspaceView, never()).visibility = View.VISIBLE
+    }
+
     private class ArgThatCaptor<T> {
         private var allArgs: MutableList<T> = mutableListOf()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 489dc4d..f31ac00 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -95,6 +95,7 @@
 import com.android.systemui.util.DeviceConfigProxyFake;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
+import com.android.wm.shell.keyguard.KeyguardTransitions;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -135,6 +136,7 @@
     private @Mock ScreenOffAnimationController mScreenOffAnimationController;
     private @Mock InteractionJankMonitor mInteractionJankMonitor;
     private @Mock ScreenOnCoordinator mScreenOnCoordinator;
+    private @Mock KeyguardTransitions mKeyguardTransitions;
     private @Mock ShadeController mShadeController;
     private NotificationShadeWindowController mNotificationShadeWindowController;
     private @Mock DreamOverlayStateController mDreamOverlayStateController;
@@ -620,6 +622,7 @@
                 mScreenOffAnimationController,
                 () -> mNotificationShadeDepthController,
                 mScreenOnCoordinator,
+                mKeyguardTransitions,
                 mInteractionJankMonitor,
                 mDreamOverlayStateController,
                 () -> mShadeController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
new file mode 100644
index 0000000..78a65a8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
@@ -0,0 +1,229 @@
+package com.android.systemui.keyguard
+
+import android.content.ComponentCallbacks2
+import android.graphics.HardwareRenderer
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.FakeCommandQueue
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.shared.model.WakeSleepReason
+import com.android.systemui.keyguard.shared.model.WakefulnessModel
+import com.android.systemui.keyguard.shared.model.WakefulnessState
+import com.android.systemui.utils.GlobalWindowManager
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+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.Mock
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class ResourceTrimmerTest : SysuiTestCase() {
+
+    private val testDispatcher = UnconfinedTestDispatcher()
+    private val testScope = TestScope(testDispatcher)
+    private val keyguardRepository = FakeKeyguardRepository()
+    private val featureFlags = FakeFeatureFlags()
+    private val keyguardTransitionRepository = FakeKeyguardTransitionRepository()
+
+    @Mock private lateinit var globalWindowManager: GlobalWindowManager
+    private lateinit var resourceTrimmer: ResourceTrimmer
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        featureFlags.set(Flags.TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK, true)
+        featureFlags.set(Flags.TRIM_FONT_CACHES_AT_UNLOCK, true)
+        featureFlags.set(Flags.FACE_AUTH_REFACTOR, false)
+        keyguardRepository.setWakefulnessModel(
+            WakefulnessModel(WakefulnessState.AWAKE, WakeSleepReason.OTHER, WakeSleepReason.OTHER)
+        )
+        keyguardRepository.setDozeAmount(0f)
+        keyguardRepository.setKeyguardGoingAway(false)
+
+        val keyguardInteractor =
+            KeyguardInteractor(
+                keyguardRepository,
+                FakeCommandQueue(),
+                featureFlags,
+                FakeKeyguardBouncerRepository()
+            )
+        resourceTrimmer =
+            ResourceTrimmer(
+                keyguardInteractor,
+                KeyguardTransitionInteractor(keyguardTransitionRepository),
+                globalWindowManager,
+                testScope.backgroundScope,
+                testDispatcher,
+                featureFlags
+            )
+        resourceTrimmer.start()
+    }
+
+    @Test
+    fun noChange_noOutputChanges() =
+        testScope.runTest {
+            testScope.runCurrent()
+            verifyZeroInteractions(globalWindowManager)
+        }
+
+    @Test
+    fun dozeAodDisabled_sleep_trimsMemory() =
+        testScope.runTest {
+            keyguardRepository.setWakefulnessModel(
+                WakefulnessModel(
+                    WakefulnessState.ASLEEP,
+                    WakeSleepReason.OTHER,
+                    WakeSleepReason.OTHER
+                )
+            )
+            testScope.runCurrent()
+            verify(globalWindowManager, times(1))
+                .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
+            verify(globalWindowManager, times(1)).trimCaches(HardwareRenderer.CACHE_TRIM_ALL)
+        }
+
+    @Test
+    fun dozeEnabled_sleepWithFullDozeAmount_trimsMemory() =
+        testScope.runTest {
+            keyguardRepository.setDreaming(true)
+            keyguardRepository.setDozeAmount(1f)
+            keyguardRepository.setWakefulnessModel(
+                WakefulnessModel(
+                    WakefulnessState.ASLEEP,
+                    WakeSleepReason.OTHER,
+                    WakeSleepReason.OTHER
+                )
+            )
+            testScope.runCurrent()
+            verify(globalWindowManager, times(1))
+                .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
+            verify(globalWindowManager, times(1)).trimCaches(HardwareRenderer.CACHE_TRIM_ALL)
+        }
+
+    @Test
+    fun dozeEnabled_sleepWithoutFullDozeAmount_doesntTrimMemory() =
+        testScope.runTest {
+            keyguardRepository.setDreaming(true)
+            keyguardRepository.setDozeAmount(0f)
+            keyguardRepository.setWakefulnessModel(
+                WakefulnessModel(
+                    WakefulnessState.ASLEEP,
+                    WakeSleepReason.OTHER,
+                    WakeSleepReason.OTHER
+                )
+            )
+            testScope.runCurrent()
+            verifyZeroInteractions(globalWindowManager)
+        }
+
+    @Test
+    fun aodEnabled_sleepWithFullDozeAmount_trimsMemoryOnce() {
+        testScope.runTest {
+            keyguardRepository.setDreaming(true)
+            keyguardRepository.setDozeAmount(0f)
+            keyguardRepository.setWakefulnessModel(
+                WakefulnessModel(
+                    WakefulnessState.ASLEEP,
+                    WakeSleepReason.OTHER,
+                    WakeSleepReason.OTHER
+                )
+            )
+
+            testScope.runCurrent()
+            verifyZeroInteractions(globalWindowManager)
+
+            generateSequence(0f) { it + 0.1f }
+                .takeWhile { it < 1f }
+                .forEach {
+                    keyguardRepository.setDozeAmount(it)
+                    testScope.runCurrent()
+                }
+            verifyZeroInteractions(globalWindowManager)
+
+            keyguardRepository.setDozeAmount(1f)
+            testScope.runCurrent()
+            verify(globalWindowManager, times(1))
+                .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
+            verify(globalWindowManager, times(1)).trimCaches(HardwareRenderer.CACHE_TRIM_ALL)
+        }
+    }
+
+    @Test
+    fun aodEnabled_deviceWakesHalfWayThrough_doesNotTrimMemory() {
+        testScope.runTest {
+            keyguardRepository.setDreaming(true)
+            keyguardRepository.setDozeAmount(0f)
+            keyguardRepository.setWakefulnessModel(
+                WakefulnessModel(
+                    WakefulnessState.ASLEEP,
+                    WakeSleepReason.OTHER,
+                    WakeSleepReason.OTHER
+                )
+            )
+
+            testScope.runCurrent()
+            verifyZeroInteractions(globalWindowManager)
+
+            generateSequence(0f) { it + 0.1f }
+                .takeWhile { it < 0.8f }
+                .forEach {
+                    keyguardRepository.setDozeAmount(it)
+                    testScope.runCurrent()
+                }
+            verifyZeroInteractions(globalWindowManager)
+
+            generateSequence(0.8f) { it - 0.1f }
+                .takeWhile { it >= 0f }
+                .forEach {
+                    keyguardRepository.setDozeAmount(it)
+                    testScope.runCurrent()
+                }
+
+            keyguardRepository.setDozeAmount(0f)
+            testScope.runCurrent()
+            verifyZeroInteractions(globalWindowManager)
+        }
+    }
+
+    @Test
+    fun keyguardTransitionsToGone_trimsFontCache() =
+        testScope.runTest {
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE)
+            )
+            verify(globalWindowManager, times(1))
+                .trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
+            verify(globalWindowManager, times(1)).trimCaches(HardwareRenderer.CACHE_TRIM_FONT)
+            verifyNoMoreInteractions(globalWindowManager)
+        }
+
+    @Test
+    fun keyguardTransitionsToGone_flagDisabled_doesNotTrimFontCache() =
+        testScope.runTest {
+            featureFlags.set(Flags.TRIM_FONT_CACHES_AT_UNLOCK, false)
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE)
+            )
+            verifyNoMoreInteractions(globalWindowManager)
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/bouncer/data/factory/BouncerMessageFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/bouncer/data/factory/BouncerMessageFactoryTest.kt
new file mode 100644
index 0000000..9e79849
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/bouncer/data/factory/BouncerMessageFactoryTest.kt
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.bouncer.data.factory
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardSecurityModel
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode.PIN
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode.Password
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode.Pattern
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_DEFAULT
+import com.android.keyguard.KeyguardSecurityView.PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.keyguard.bouncer.shared.model.BouncerMessageModel
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.StringSubject
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BouncerMessageFactoryTest : SysuiTestCase() {
+    private lateinit var underTest: BouncerMessageFactory
+
+    @Mock private lateinit var updateMonitor: KeyguardUpdateMonitor
+
+    @Mock private lateinit var securityModel: KeyguardSecurityModel
+
+    private lateinit var testScope: TestScope
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        testScope = TestScope()
+        underTest = BouncerMessageFactory(updateMonitor, securityModel)
+    }
+
+    @Test
+    fun bouncerMessages_choosesTheRightMessage_basedOnSecurityModeAndFpAllowedInBouncer() =
+        testScope.runTest {
+            primaryMessage(PROMPT_REASON_DEFAULT, mode = PIN, fpAllowedInBouncer = false)
+                .isEqualTo("Enter PIN")
+            primaryMessage(PROMPT_REASON_DEFAULT, mode = PIN, fpAllowedInBouncer = true)
+                .isEqualTo("Unlock with PIN or fingerprint")
+
+            primaryMessage(PROMPT_REASON_DEFAULT, mode = Password, fpAllowedInBouncer = false)
+                .isEqualTo("Enter password")
+            primaryMessage(PROMPT_REASON_DEFAULT, mode = Password, fpAllowedInBouncer = true)
+                .isEqualTo("Unlock with password or fingerprint")
+
+            primaryMessage(PROMPT_REASON_DEFAULT, mode = Pattern, fpAllowedInBouncer = false)
+                .isEqualTo("Draw pattern")
+            primaryMessage(PROMPT_REASON_DEFAULT, mode = Pattern, fpAllowedInBouncer = true)
+                .isEqualTo("Unlock with pattern or fingerprint")
+        }
+
+    @Test
+    fun bouncerMessages_setsPrimaryAndSecondaryMessage_basedOnSecurityModeAndFpAllowedInBouncer() =
+        testScope.runTest {
+            primaryMessage(
+                    PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
+                    mode = PIN,
+                    fpAllowedInBouncer = true
+                )
+                .isEqualTo("Wrong PIN. Try again.")
+            secondaryMessage(
+                    PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
+                    mode = PIN,
+                    fpAllowedInBouncer = true
+                )
+                .isEqualTo("Or unlock with fingerprint")
+
+            primaryMessage(
+                    PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
+                    mode = Password,
+                    fpAllowedInBouncer = true
+                )
+                .isEqualTo("Wrong password. Try again.")
+            secondaryMessage(
+                    PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
+                    mode = Password,
+                    fpAllowedInBouncer = true
+                )
+                .isEqualTo("Or unlock with fingerprint")
+
+            primaryMessage(
+                    PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
+                    mode = Pattern,
+                    fpAllowedInBouncer = true
+                )
+                .isEqualTo("Wrong pattern. Try again.")
+            secondaryMessage(
+                    PROMPT_REASON_INCORRECT_PRIMARY_AUTH_INPUT,
+                    mode = Pattern,
+                    fpAllowedInBouncer = true
+                )
+                .isEqualTo("Or unlock with fingerprint")
+        }
+
+    private fun primaryMessage(
+        reason: Int,
+        mode: KeyguardSecurityModel.SecurityMode,
+        fpAllowedInBouncer: Boolean
+    ): StringSubject {
+        return assertThat(
+            context.resources.getString(
+                bouncerMessageModel(mode, fpAllowedInBouncer, reason)!!.message!!.messageResId!!
+            )
+        )!!
+    }
+
+    private fun secondaryMessage(
+        reason: Int,
+        mode: KeyguardSecurityModel.SecurityMode,
+        fpAllowedInBouncer: Boolean
+    ): StringSubject {
+        return assertThat(
+            context.resources.getString(
+                bouncerMessageModel(mode, fpAllowedInBouncer, reason)!!
+                    .secondaryMessage!!
+                    .messageResId!!
+            )
+        )!!
+    }
+
+    private fun bouncerMessageModel(
+        mode: KeyguardSecurityModel.SecurityMode,
+        fpAllowedInBouncer: Boolean,
+        reason: Int
+    ): BouncerMessageModel? {
+        whenever(securityModel.getSecurityMode(0)).thenReturn(mode)
+        whenever(updateMonitor.isFingerprintAllowedInBouncer).thenReturn(fpAllowedInBouncer)
+
+        return underTest.createFromPromptReason(reason, 0)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/bouncer/data/repository/BouncerMessageRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/bouncer/data/repository/BouncerMessageRepositoryTest.kt
new file mode 100644
index 0000000..1277fc0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/bouncer/data/repository/BouncerMessageRepositoryTest.kt
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.bouncer.data.repository
+
+import android.content.pm.UserInfo
+import android.hardware.biometrics.BiometricSourceType
+import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE
+import com.android.keyguard.KeyguardSecurityModel
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode.PIN
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.R
+import com.android.systemui.R.string.keyguard_enter_pin
+import com.android.systemui.R.string.kg_prompt_after_dpm_lock
+import com.android.systemui.R.string.kg_prompt_after_user_lockdown_pin
+import com.android.systemui.R.string.kg_prompt_auth_timeout
+import com.android.systemui.R.string.kg_prompt_pin_auth_timeout
+import com.android.systemui.R.string.kg_prompt_reason_restart_pin
+import com.android.systemui.R.string.kg_prompt_unattended_update
+import com.android.systemui.R.string.kg_trust_agent_disabled
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.bouncer.data.factory.BouncerMessageFactory
+import com.android.systemui.keyguard.bouncer.shared.model.BouncerMessageModel
+import com.android.systemui.keyguard.bouncer.shared.model.Message
+import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.data.repository.FakeTrustRepository
+import com.android.systemui.keyguard.shared.model.AuthenticationFlags
+import com.android.systemui.user.data.repository.FakeUserRepository
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@RunWith(AndroidJUnit4::class)
+class BouncerMessageRepositoryTest : SysuiTestCase() {
+
+    @Mock private lateinit var updateMonitor: KeyguardUpdateMonitor
+    @Mock private lateinit var securityModel: KeyguardSecurityModel
+    @Captor
+    private lateinit var updateMonitorCallback: ArgumentCaptor<KeyguardUpdateMonitorCallback>
+
+    private lateinit var underTest: BouncerMessageRepository
+    private lateinit var trustRepository: FakeTrustRepository
+    private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
+    private lateinit var userRepository: FakeUserRepository
+    private lateinit var fingerprintRepository: FakeDeviceEntryFingerprintAuthRepository
+    private lateinit var testScope: TestScope
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        trustRepository = FakeTrustRepository()
+        biometricSettingsRepository = FakeBiometricSettingsRepository()
+        userRepository = FakeUserRepository()
+        userRepository.setUserInfos(listOf(PRIMARY_USER))
+        fingerprintRepository = FakeDeviceEntryFingerprintAuthRepository()
+        testScope = TestScope()
+
+        whenever(updateMonitor.isFingerprintAllowedInBouncer).thenReturn(false)
+        whenever(securityModel.getSecurityMode(PRIMARY_USER_ID)).thenReturn(PIN)
+        underTest =
+            BouncerMessageRepositoryImpl(
+                trustRepository = trustRepository,
+                biometricSettingsRepository = biometricSettingsRepository,
+                updateMonitor = updateMonitor,
+                bouncerMessageFactory = BouncerMessageFactory(updateMonitor, securityModel),
+                userRepository = userRepository,
+                fingerprintAuthRepository = fingerprintRepository
+            )
+    }
+
+    @Test
+    fun setCustomMessage_propagatesState() =
+        testScope.runTest {
+            underTest.setCustomMessage(message("not empty"))
+
+            val customMessage = collectLastValue(underTest.customMessage)
+
+            assertThat(customMessage()).isEqualTo(message("not empty"))
+        }
+
+    @Test
+    fun setFaceMessage_propagatesState() =
+        testScope.runTest {
+            underTest.setFaceAcquisitionMessage(message("not empty"))
+
+            val faceAcquisitionMessage = collectLastValue(underTest.faceAcquisitionMessage)
+
+            assertThat(faceAcquisitionMessage()).isEqualTo(message("not empty"))
+        }
+
+    @Test
+    fun setFpMessage_propagatesState() =
+        testScope.runTest {
+            underTest.setFingerprintAcquisitionMessage(message("not empty"))
+
+            val fpAcquisitionMsg = collectLastValue(underTest.fingerprintAcquisitionMessage)
+
+            assertThat(fpAcquisitionMsg()).isEqualTo(message("not empty"))
+        }
+
+    @Test
+    fun setPrimaryAuthMessage_propagatesState() =
+        testScope.runTest {
+            underTest.setPrimaryAuthMessage(message("not empty"))
+
+            val primaryAuthMessage = collectLastValue(underTest.primaryAuthMessage)
+
+            assertThat(primaryAuthMessage()).isEqualTo(message("not empty"))
+        }
+
+    @Test
+    fun biometricAuthMessage_propagatesBiometricAuthMessages() =
+        testScope.runTest {
+            userRepository.setSelectedUserInfo(PRIMARY_USER)
+            val biometricAuthMessage = collectLastValue(underTest.biometricAuthMessage)
+            runCurrent()
+
+            verify(updateMonitor).registerCallback(updateMonitorCallback.capture())
+
+            updateMonitorCallback.value.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT)
+
+            assertThat(biometricAuthMessage())
+                .isEqualTo(message(R.string.kg_fp_not_recognized, R.string.kg_bio_try_again_or_pin))
+
+            updateMonitorCallback.value.onBiometricAuthFailed(BiometricSourceType.FACE)
+
+            assertThat(biometricAuthMessage())
+                .isEqualTo(
+                    message(R.string.bouncer_face_not_recognized, R.string.kg_bio_try_again_or_pin)
+                )
+
+            updateMonitorCallback.value.onBiometricAcquired(BiometricSourceType.FACE, 0)
+
+            assertThat(biometricAuthMessage()).isNull()
+        }
+
+    @Test
+    fun onFaceLockout_propagatesState() =
+        testScope.runTest {
+            userRepository.setSelectedUserInfo(PRIMARY_USER)
+            val lockoutMessage = collectLastValue(underTest.biometricLockedOutMessage)
+            runCurrent()
+            verify(updateMonitor).registerCallback(updateMonitorCallback.capture())
+
+            whenever(updateMonitor.isFaceLockedOut).thenReturn(true)
+            updateMonitorCallback.value.onLockedOutStateChanged(BiometricSourceType.FACE)
+
+            assertThat(lockoutMessage())
+                .isEqualTo(message(keyguard_enter_pin, R.string.kg_face_locked_out))
+
+            whenever(updateMonitor.isFaceLockedOut).thenReturn(false)
+            updateMonitorCallback.value.onLockedOutStateChanged(BiometricSourceType.FACE)
+            assertThat(lockoutMessage()).isNull()
+        }
+
+    @Test
+    fun onFingerprintLockout_propagatesState() =
+        testScope.runTest {
+            userRepository.setSelectedUserInfo(PRIMARY_USER)
+            val lockedOutMessage = collectLastValue(underTest.biometricLockedOutMessage)
+            runCurrent()
+
+            fingerprintRepository.setLockedOut(true)
+
+            assertThat(lockedOutMessage())
+                .isEqualTo(message(keyguard_enter_pin, R.string.kg_fp_locked_out))
+
+            fingerprintRepository.setLockedOut(false)
+            assertThat(lockedOutMessage()).isNull()
+        }
+
+    @Test
+    fun onAuthFlagsChanged_withTrustNotManagedAndNoBiometrics_isANoop() =
+        testScope.runTest {
+            userRepository.setSelectedUserInfo(PRIMARY_USER)
+            trustRepository.setCurrentUserTrustManaged(false)
+            biometricSettingsRepository.setFaceEnrolled(false)
+            biometricSettingsRepository.setFingerprintEnrolled(false)
+
+            verifyMessagesForAuthFlag(
+                STRONG_AUTH_NOT_REQUIRED to null,
+                STRONG_AUTH_REQUIRED_AFTER_BOOT to null,
+                SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
+                STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to null,
+                STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to null,
+                STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to null,
+                STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to null,
+                SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to null,
+                STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to null,
+                STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
+                    Pair(keyguard_enter_pin, kg_prompt_after_dpm_lock),
+            )
+        }
+
+    @Test
+    fun authFlagsChanges_withTrustManaged_providesDifferentMessages() =
+        testScope.runTest {
+            userRepository.setSelectedUserInfo(PRIMARY_USER)
+            biometricSettingsRepository.setFaceEnrolled(false)
+            biometricSettingsRepository.setFingerprintEnrolled(false)
+
+            trustRepository.setCurrentUserTrustManaged(true)
+
+            verifyMessagesForAuthFlag(
+                STRONG_AUTH_NOT_REQUIRED to null,
+                STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to null,
+                STRONG_AUTH_REQUIRED_AFTER_BOOT to
+                    Pair(keyguard_enter_pin, kg_prompt_reason_restart_pin),
+                STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
+                    Pair(keyguard_enter_pin, kg_prompt_pin_auth_timeout),
+                STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
+                    Pair(keyguard_enter_pin, kg_prompt_after_dpm_lock),
+                SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to
+                    Pair(keyguard_enter_pin, kg_trust_agent_disabled),
+                SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
+                    Pair(keyguard_enter_pin, kg_trust_agent_disabled),
+                STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
+                    Pair(keyguard_enter_pin, kg_prompt_after_user_lockdown_pin),
+                STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
+                    Pair(keyguard_enter_pin, kg_prompt_unattended_update),
+                STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
+                    Pair(keyguard_enter_pin, kg_prompt_auth_timeout),
+            )
+        }
+
+    @Test
+    fun authFlagsChanges_withFaceEnrolled_providesDifferentMessages() =
+        testScope.runTest {
+            userRepository.setSelectedUserInfo(PRIMARY_USER)
+            trustRepository.setCurrentUserTrustManaged(false)
+            biometricSettingsRepository.setFingerprintEnrolled(false)
+
+            biometricSettingsRepository.setIsFaceAuthEnabled(true)
+            biometricSettingsRepository.setFaceEnrolled(true)
+
+            verifyMessagesForAuthFlag(
+                STRONG_AUTH_NOT_REQUIRED to null,
+                STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to null,
+                SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
+                SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to null,
+                STRONG_AUTH_REQUIRED_AFTER_BOOT to
+                    Pair(keyguard_enter_pin, kg_prompt_reason_restart_pin),
+                STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
+                    Pair(keyguard_enter_pin, kg_prompt_pin_auth_timeout),
+                STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
+                    Pair(keyguard_enter_pin, kg_prompt_after_dpm_lock),
+                STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
+                    Pair(keyguard_enter_pin, kg_prompt_after_user_lockdown_pin),
+                STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
+                    Pair(keyguard_enter_pin, kg_prompt_unattended_update),
+                STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
+                    Pair(keyguard_enter_pin, kg_prompt_auth_timeout),
+            )
+        }
+
+    @Test
+    fun authFlagsChanges_withFingerprintEnrolled_providesDifferentMessages() =
+        testScope.runTest {
+            userRepository.setSelectedUserInfo(PRIMARY_USER)
+            trustRepository.setCurrentUserTrustManaged(false)
+            biometricSettingsRepository.setIsFaceAuthEnabled(false)
+            biometricSettingsRepository.setFaceEnrolled(false)
+
+            biometricSettingsRepository.setFingerprintEnrolled(true)
+            biometricSettingsRepository.setFingerprintEnabledByDevicePolicy(true)
+
+            verifyMessagesForAuthFlag(
+                STRONG_AUTH_NOT_REQUIRED to null,
+                STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to null,
+                SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
+                SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to null,
+                STRONG_AUTH_REQUIRED_AFTER_BOOT to
+                    Pair(keyguard_enter_pin, kg_prompt_reason_restart_pin),
+                STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
+                    Pair(keyguard_enter_pin, kg_prompt_pin_auth_timeout),
+                STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
+                    Pair(keyguard_enter_pin, kg_prompt_after_dpm_lock),
+                STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
+                    Pair(keyguard_enter_pin, kg_prompt_after_user_lockdown_pin),
+                STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
+                    Pair(keyguard_enter_pin, kg_prompt_unattended_update),
+                STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
+                    Pair(keyguard_enter_pin, kg_prompt_auth_timeout),
+            )
+        }
+
+    private fun TestScope.verifyMessagesForAuthFlag(
+        vararg authFlagToExpectedMessages: Pair<Int, Pair<Int, Int>?>
+    ) {
+        val authFlagsMessage = collectLastValue(underTest.authFlagsMessage)
+
+        authFlagToExpectedMessages.forEach { (flag, messagePair) ->
+            biometricSettingsRepository.setAuthenticationFlags(
+                AuthenticationFlags(PRIMARY_USER_ID, flag)
+            )
+
+            assertThat(authFlagsMessage())
+                .isEqualTo(messagePair?.let { message(it.first, it.second) })
+        }
+    }
+
+    private fun message(primaryResId: Int, secondaryResId: Int): BouncerMessageModel {
+        return BouncerMessageModel(
+            message = Message(messageResId = primaryResId),
+            secondaryMessage = Message(messageResId = secondaryResId)
+        )
+    }
+    private fun message(value: String): BouncerMessageModel {
+        return BouncerMessageModel(message = Message(message = value))
+    }
+
+    companion object {
+        private const val PRIMARY_USER_ID = 0
+        private val PRIMARY_USER =
+            UserInfo(
+                /* id= */ PRIMARY_USER_ID,
+                /* name= */ "primary user",
+                /* flags= */ UserInfo.FLAG_PRIMARY
+            )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/bouncer/domain/interactor/BouncerMessageInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/bouncer/domain/interactor/BouncerMessageInteractorTest.kt
new file mode 100644
index 0000000..b0af310
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/bouncer/domain/interactor/BouncerMessageInteractorTest.kt
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.bouncer.domain.interactor
+
+import android.content.pm.UserInfo
+import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardSecurityModel
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode.PIN
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.R.string.keyguard_enter_pin
+import com.android.systemui.R.string.kg_too_many_failed_attempts_countdown
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.FlowValue
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.bouncer.data.factory.BouncerMessageFactory
+import com.android.systemui.keyguard.bouncer.shared.model.BouncerMessageModel
+import com.android.systemui.keyguard.bouncer.shared.model.Message
+import com.android.systemui.keyguard.data.repository.FakeBouncerMessageRepository
+import com.android.systemui.user.data.repository.FakeUserRepository
+import com.android.systemui.util.mockito.KotlinArgumentCaptor
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@RunWith(AndroidJUnit4::class)
+class BouncerMessageInteractorTest : SysuiTestCase() {
+
+    @Mock private lateinit var securityModel: KeyguardSecurityModel
+    @Mock private lateinit var updateMonitor: KeyguardUpdateMonitor
+    @Mock private lateinit var countDownTimerUtil: CountDownTimerUtil
+    private lateinit var countDownTimerCallback: KotlinArgumentCaptor<CountDownTimerCallback>
+    private lateinit var underTest: BouncerMessageInteractor
+    private lateinit var repository: FakeBouncerMessageRepository
+    private lateinit var userRepository: FakeUserRepository
+    private lateinit var testScope: TestScope
+    private lateinit var bouncerMessage: FlowValue<BouncerMessageModel?>
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        repository = FakeBouncerMessageRepository()
+        userRepository = FakeUserRepository()
+        userRepository.setUserInfos(listOf(PRIMARY_USER))
+        testScope = TestScope()
+        countDownTimerCallback = KotlinArgumentCaptor(CountDownTimerCallback::class.java)
+
+        allowTestableLooperAsMainThread()
+        whenever(securityModel.getSecurityMode(PRIMARY_USER_ID)).thenReturn(PIN)
+        whenever(updateMonitor.isFingerprintAllowedInBouncer).thenReturn(false)
+    }
+
+    suspend fun TestScope.init() {
+        userRepository.setSelectedUserInfo(PRIMARY_USER)
+        val featureFlags = FakeFeatureFlags()
+        featureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true)
+        underTest =
+            BouncerMessageInteractor(
+                repository = repository,
+                factory = BouncerMessageFactory(updateMonitor, securityModel),
+                userRepository = userRepository,
+                countDownTimerUtil = countDownTimerUtil,
+                featureFlags = featureFlags
+            )
+        bouncerMessage = collectLastValue(underTest.bouncerMessage)
+    }
+
+    @Test
+    fun onIncorrectSecurityInput_setsTheBouncerModelInTheRepository() =
+        testScope.runTest {
+            init()
+            underTest.onPrimaryAuthIncorrectAttempt()
+
+            assertThat(repository.primaryAuthMessage).isNotNull()
+            assertThat(
+                    context.resources.getString(
+                        repository.primaryAuthMessage.value!!.message!!.messageResId!!
+                    )
+                )
+                .isEqualTo("Wrong PIN. Try again.")
+        }
+
+    @Test
+    fun onUserStartsPrimaryAuthInput_clearsAllSetBouncerMessages() =
+        testScope.runTest {
+            init()
+            repository.setCustomMessage(message("not empty"))
+            repository.setFaceAcquisitionMessage(message("not empty"))
+            repository.setFingerprintAcquisitionMessage(message("not empty"))
+            repository.setPrimaryAuthMessage(message("not empty"))
+
+            underTest.onPrimaryBouncerUserInput()
+
+            assertThat(repository.customMessage.value).isNull()
+            assertThat(repository.faceAcquisitionMessage.value).isNull()
+            assertThat(repository.fingerprintAcquisitionMessage.value).isNull()
+            assertThat(repository.primaryAuthMessage.value).isNull()
+        }
+
+    @Test
+    fun onBouncerBeingHidden_clearsAllSetBouncerMessages() =
+        testScope.runTest {
+            init()
+            repository.setCustomMessage(message("not empty"))
+            repository.setFaceAcquisitionMessage(message("not empty"))
+            repository.setFingerprintAcquisitionMessage(message("not empty"))
+            repository.setPrimaryAuthMessage(message("not empty"))
+
+            underTest.onBouncerBeingHidden()
+
+            assertThat(repository.customMessage.value).isNull()
+            assertThat(repository.faceAcquisitionMessage.value).isNull()
+            assertThat(repository.fingerprintAcquisitionMessage.value).isNull()
+            assertThat(repository.primaryAuthMessage.value).isNull()
+        }
+
+    @Test
+    fun setCustomMessage_setsRepositoryValue() =
+        testScope.runTest {
+            init()
+
+            underTest.setCustomMessage("not empty")
+
+            assertThat(repository.customMessage.value)
+                .isEqualTo(BouncerMessageModel(secondaryMessage = Message(message = "not empty")))
+
+            underTest.setCustomMessage(null)
+            assertThat(repository.customMessage.value).isNull()
+        }
+
+    @Test
+    fun setFaceMessage_setsRepositoryValue() =
+        testScope.runTest {
+            init()
+
+            underTest.setFaceAcquisitionMessage("not empty")
+
+            assertThat(repository.faceAcquisitionMessage.value)
+                .isEqualTo(BouncerMessageModel(secondaryMessage = Message(message = "not empty")))
+
+            underTest.setFaceAcquisitionMessage(null)
+            assertThat(repository.faceAcquisitionMessage.value).isNull()
+        }
+
+    @Test
+    fun setFingerprintMessage_setsRepositoryValue() =
+        testScope.runTest {
+            init()
+
+            underTest.setFingerprintAcquisitionMessage("not empty")
+
+            assertThat(repository.fingerprintAcquisitionMessage.value)
+                .isEqualTo(BouncerMessageModel(secondaryMessage = Message(message = "not empty")))
+
+            underTest.setFingerprintAcquisitionMessage(null)
+            assertThat(repository.fingerprintAcquisitionMessage.value).isNull()
+        }
+
+    @Test
+    fun onPrimaryAuthLockout_startsTimerForSpecifiedNumberOfSeconds() =
+        testScope.runTest {
+            init()
+
+            underTest.onPrimaryAuthLockedOut(3)
+
+            verify(countDownTimerUtil)
+                .startNewTimer(eq(3000L), eq(1000L), countDownTimerCallback.capture())
+
+            countDownTimerCallback.value.onTick(2000L)
+
+            val primaryMessage = repository.primaryAuthMessage.value!!.message!!
+            assertThat(primaryMessage.messageResId!!)
+                .isEqualTo(kg_too_many_failed_attempts_countdown)
+            assertThat(primaryMessage.formatterArgs).isEqualTo(mapOf(Pair("count", 2)))
+        }
+
+    @Test
+    fun onPrimaryAuthLockout_timerComplete_resetsRepositoryMessages() =
+        testScope.runTest {
+            init()
+            repository.setCustomMessage(message("not empty"))
+            repository.setFaceAcquisitionMessage(message("not empty"))
+            repository.setFingerprintAcquisitionMessage(message("not empty"))
+            repository.setPrimaryAuthMessage(message("not empty"))
+
+            underTest.onPrimaryAuthLockedOut(3)
+
+            verify(countDownTimerUtil)
+                .startNewTimer(eq(3000L), eq(1000L), countDownTimerCallback.capture())
+
+            countDownTimerCallback.value.onFinish()
+
+            assertThat(repository.customMessage.value).isNull()
+            assertThat(repository.faceAcquisitionMessage.value).isNull()
+            assertThat(repository.fingerprintAcquisitionMessage.value).isNull()
+            assertThat(repository.primaryAuthMessage.value).isNull()
+        }
+
+    @Test
+    fun bouncerMessage_hasPriorityOrderOfMessages() =
+        testScope.runTest {
+            init()
+            repository.setBiometricAuthMessage(message("biometric message"))
+            repository.setFaceAcquisitionMessage(message("face acquisition message"))
+            repository.setFingerprintAcquisitionMessage(message("fingerprint acquisition message"))
+            repository.setPrimaryAuthMessage(message("primary auth message"))
+            repository.setAuthFlagsMessage(message("auth flags message"))
+            repository.setBiometricLockedOutMessage(message("biometrics locked out"))
+            repository.setCustomMessage(message("custom message"))
+
+            assertThat(bouncerMessage()).isEqualTo(message("primary auth message"))
+
+            repository.setPrimaryAuthMessage(null)
+
+            assertThat(bouncerMessage()).isEqualTo(message("biometric message"))
+
+            repository.setBiometricAuthMessage(null)
+
+            assertThat(bouncerMessage()).isEqualTo(message("fingerprint acquisition message"))
+
+            repository.setFingerprintAcquisitionMessage(null)
+
+            assertThat(bouncerMessage()).isEqualTo(message("face acquisition message"))
+
+            repository.setFaceAcquisitionMessage(null)
+
+            assertThat(bouncerMessage()).isEqualTo(message("custom message"))
+
+            repository.setCustomMessage(null)
+
+            assertThat(bouncerMessage()).isEqualTo(message("auth flags message"))
+
+            repository.setAuthFlagsMessage(null)
+
+            assertThat(bouncerMessage()).isEqualTo(message("biometrics locked out"))
+
+            repository.setBiometricLockedOutMessage(null)
+
+            // sets the default message if everything else is null
+            assertThat(bouncerMessage()!!.message!!.messageResId).isEqualTo(keyguard_enter_pin)
+        }
+
+    private fun message(value: String): BouncerMessageModel {
+        return BouncerMessageModel(message = Message(message = value))
+    }
+
+    companion object {
+        private const val PRIMARY_USER_ID = 0
+        private val PRIMARY_USER =
+            UserInfo(
+                /* id= */ PRIMARY_USER_ID,
+                /* name= */ "primary user",
+                /* flags= */ UserInfo.FLAG_PRIMARY
+            )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
index 1bab817..b925aeb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
@@ -310,19 +310,38 @@
             createBiometricSettingsRepository()
             verify(biometricManager)
                 .registerEnabledOnKeyguardCallback(biometricManagerCallback.capture())
-
             whenever(devicePolicyManager.getKeyguardDisabledFeatures(isNull(), eq(PRIMARY_USER_ID)))
                 .thenReturn(0)
             broadcastDPMStateChange()
-
-            biometricManagerCallback.value.onChanged(true, PRIMARY_USER_ID)
             val isFaceAuthEnabled = collectLastValue(underTest.isFaceAuthenticationEnabled)
 
-            assertThat(isFaceAuthEnabled()).isTrue()
+            assertThat(isFaceAuthEnabled()).isFalse()
 
-            biometricManagerCallback.value.onChanged(false, PRIMARY_USER_ID)
+            // Value changes for another user
+            biometricManagerCallback.value.onChanged(true, ANOTHER_USER_ID)
 
             assertThat(isFaceAuthEnabled()).isFalse()
+
+            // Value changes for current user.
+            biometricManagerCallback.value.onChanged(true, PRIMARY_USER_ID)
+
+            assertThat(isFaceAuthEnabled()).isTrue()
+        }
+
+    @Test
+    fun userChange_biometricEnabledChange_handlesRaceCondition() =
+        testScope.runTest {
+            createBiometricSettingsRepository()
+            verify(biometricManager)
+                .registerEnabledOnKeyguardCallback(biometricManagerCallback.capture())
+            val isFaceAuthEnabled = collectLastValue(underTest.isFaceAuthenticationEnabled)
+            biometricManagerCallback.value.onChanged(true, ANOTHER_USER_ID)
+            runCurrent()
+
+            userRepository.setSelectedUserInfo(ANOTHER_USER)
+            runCurrent()
+
+            assertThat(isFaceAuthEnabled()).isTrue()
         }
 
     @Test
@@ -382,7 +401,7 @@
         }
 
     @Test
-    fun userInLockdownUsesStrongAuthFlagsToDetermineValue() =
+    fun userInLockdownUsesAuthFlagsToDetermineValue() =
         testScope.runTest {
             createBiometricSettingsRepository()
 
@@ -405,6 +424,38 @@
             assertThat(isUserInLockdown()).isTrue()
         }
 
+    @Test
+    fun authFlagChangesForCurrentUserArePropagated() =
+        testScope.runTest {
+            createBiometricSettingsRepository()
+
+            val authFlags = collectLastValue(underTest.authenticationFlags)
+            // has default value.
+            val defaultStrongAuthValue = STRONG_AUTH_REQUIRED_AFTER_BOOT
+            assertThat(authFlags()!!.flag).isEqualTo(defaultStrongAuthValue)
+
+            // change strong auth flags for another user.
+            // Combine with one more flag to check if we do the bitwise and
+            val inLockdown =
+                STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN or STRONG_AUTH_REQUIRED_AFTER_TIMEOUT
+            onStrongAuthChanged(inLockdown, ANOTHER_USER_ID)
+
+            // Still false.
+            assertThat(authFlags()!!.flag).isEqualTo(defaultStrongAuthValue)
+
+            // change strong auth flags for current user.
+            onStrongAuthChanged(inLockdown, PRIMARY_USER_ID)
+
+            assertThat(authFlags()!!.flag).isEqualTo(inLockdown)
+
+            onStrongAuthChanged(STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, ANOTHER_USER_ID)
+
+            assertThat(authFlags()!!.flag).isEqualTo(inLockdown)
+
+            userRepository.setSelectedUserInfo(ANOTHER_USER)
+            assertThat(authFlags()!!.flag).isEqualTo(STRONG_AUTH_REQUIRED_AFTER_TIMEOUT)
+        }
+
     private fun enrollmentChange(biometricType: BiometricType, userId: Int, enabled: Boolean) {
         authControllerCallback.value.onEnrollmentsChanged(biometricType, userId, enabled)
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
index 8611359..29d7500 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
@@ -64,7 +64,6 @@
         testScope = TestScope()
         userRepository = FakeUserRepository()
         userRepository.setUserInfos(users)
-
         val logger =
             TrustRepositoryLogger(
                 LogBuffer("TestBuffer", 1, mock(LogcatEchoTracker::class.java), false)
@@ -224,4 +223,41 @@
 
             assertThat(isCurrentUserTrusted()).isTrue()
         }
+
+    @Test
+    fun isCurrentUserActiveUnlockRunning_runningFirstBeforeUserInfoChanges_emitsCorrectValue() =
+        testScope.runTest {
+            runCurrent()
+            verify(trustManager).registerTrustListener(listener.capture())
+            val isCurrentUserActiveUnlockRunning by
+                collectLastValue(underTest.isCurrentUserActiveUnlockRunning)
+            userRepository.setSelectedUserInfo(users[1])
+
+            // active unlock running = true for users[0].id, but not the current user
+            listener.value.onIsActiveUnlockRunningChanged(true, users[0].id)
+            assertThat(isCurrentUserActiveUnlockRunning).isFalse()
+
+            // current user is now users[0].id
+            userRepository.setSelectedUserInfo(users[0])
+            assertThat(isCurrentUserActiveUnlockRunning).isTrue()
+        }
+
+    @Test
+    fun isCurrentUserActiveUnlockRunning_whenActiveUnlockRunningForCurrentUser_emitsNewValue() =
+        testScope.runTest {
+            runCurrent()
+            verify(trustManager).registerTrustListener(listener.capture())
+            val isCurrentUserActiveUnlockRunning by
+                collectLastValue(underTest.isCurrentUserActiveUnlockRunning)
+            userRepository.setSelectedUserInfo(users[0])
+
+            listener.value.onIsActiveUnlockRunningChanged(true, users[0].id)
+            assertThat(isCurrentUserActiveUnlockRunning).isTrue()
+
+            listener.value.onIsActiveUnlockRunningChanged(false, users[0].id)
+            assertThat(isCurrentUserActiveUnlockRunning).isFalse()
+
+            listener.value.onIsActiveUnlockRunningChanged(true, users[0].id)
+            assertThat(isCurrentUserActiveUnlockRunning).isTrue()
+        }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
index e261982..6af1220 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
@@ -35,7 +35,7 @@
 import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.data.repository.TrustRepository
+import com.android.systemui.keyguard.data.repository.FakeTrustRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
@@ -100,8 +100,9 @@
                     mock(DismissCallbackRegistry::class.java),
                     context,
                     keyguardUpdateMonitor,
-                    mock(TrustRepository::class.java),
-                    FakeFeatureFlags(),
+                    FakeTrustRepository(),
+                    FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) },
+                    testScope.backgroundScope,
                 ),
                 AlternateBouncerInteractor(
                     mock(StatusBarStateController::class.java),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
index dfef947..5de24e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
@@ -21,6 +21,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
+import com.android.systemui.R
 import com.android.systemui.RoboPilotTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -39,6 +40,7 @@
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
+import org.junit.After
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -65,6 +67,7 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
+        overrideResource(R.bool.long_press_keyguard_customize_lockscreen_enabled, true)
         whenever(accessibilityManager.getRecommendedTimeoutMillis(anyInt(), anyInt())).thenAnswer {
             it.arguments[0]
         }
@@ -76,6 +79,13 @@
         runBlocking { createUnderTest() }
     }
 
+    @After
+    fun tearDown() {
+        mContext
+            .getOrCreateTestableResources()
+            .removeOverride(R.bool.long_press_keyguard_customize_lockscreen_enabled)
+    }
+
     @Test
     fun isEnabled() =
         testScope.runTest {
@@ -108,6 +118,17 @@
         }
 
     @Test
+    fun isEnabled_alwaysFalseWhenConfigEnabledBooleanIsFalse() =
+        testScope.runTest {
+            overrideResource(R.bool.long_press_keyguard_customize_lockscreen_enabled, false)
+            createUnderTest()
+            val isEnabled by collectLastValue(underTest.isLongPressHandlingEnabled)
+            runCurrent()
+
+            assertThat(isEnabled).isFalse()
+        }
+
+    @Test
     fun longPressed_menuClicked_showsSettings() =
         testScope.runTest {
             val isMenuVisible by collectLastValue(underTest.isMenuVisible)
@@ -267,6 +288,7 @@
     ) {
         underTest =
             KeyguardLongPressInteractor(
+                appContext = mContext,
                 scope = testScope.backgroundScope,
                 transitionInteractor =
                     KeyguardTransitionInteractor(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
index a75e11a..fb21847 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
@@ -340,6 +340,7 @@
                 devicePolicyManager = devicePolicyManager,
                 dockManager = dockManager,
                 backgroundDispatcher = testDispatcher,
+                appContext = mContext,
             )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index 3336e3b..5d2c3ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -200,6 +200,7 @@
                 devicePolicyManager = devicePolicyManager,
                 dockManager = dockManager,
                 backgroundDispatcher = testDispatcher,
+                appContext = mContext,
             )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockScreenSceneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockScreenSceneInteractorTest.kt
deleted file mode 100644
index 749e7a0..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockScreenSceneInteractorTest.kt
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.keyguard.domain.interactor
-
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.authentication.data.repository.AuthenticationRepositoryImpl
-import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
-import com.android.systemui.bouncer.data.repo.BouncerRepository
-import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.scene.data.repository.fakeSceneContainerRepository
-import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.model.SceneKey
-import com.android.systemui.scene.shared.model.SceneModel
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@OptIn(ExperimentalCoroutinesApi::class)
-@SmallTest
-@RunWith(JUnit4::class)
-class LockScreenSceneInteractorTest : SysuiTestCase() {
-
-    private val testScope = TestScope()
-    private val sceneInteractor =
-        SceneInteractor(
-            repository = fakeSceneContainerRepository(),
-        )
-    private val mAuthenticationInteractor =
-        AuthenticationInteractor(
-            applicationScope = testScope.backgroundScope,
-            repository = AuthenticationRepositoryImpl(),
-        )
-    private val underTest =
-        LockScreenSceneInteractor(
-            applicationScope = testScope.backgroundScope,
-            authenticationInteractor = mAuthenticationInteractor,
-            bouncerInteractorFactory =
-                object : BouncerInteractor.Factory {
-                    override fun create(containerName: String): BouncerInteractor {
-                        return BouncerInteractor(
-                            applicationScope = testScope.backgroundScope,
-                            applicationContext = context,
-                            repository = BouncerRepository(),
-                            authenticationInteractor = mAuthenticationInteractor,
-                            sceneInteractor = sceneInteractor,
-                            containerName = containerName,
-                        )
-                    }
-                },
-            sceneInteractor = sceneInteractor,
-            containerName = CONTAINER_NAME,
-        )
-
-    @Test
-    fun isDeviceLocked() =
-        testScope.runTest {
-            val isDeviceLocked by collectLastValue(underTest.isDeviceLocked)
-
-            mAuthenticationInteractor.lockDevice()
-            assertThat(isDeviceLocked).isTrue()
-
-            mAuthenticationInteractor.unlockDevice()
-            assertThat(isDeviceLocked).isFalse()
-        }
-
-    @Test
-    fun isSwipeToDismissEnabled_deviceLockedAndAuthMethodSwipe_true() =
-        testScope.runTest {
-            val isSwipeToDismissEnabled by collectLastValue(underTest.isSwipeToDismissEnabled)
-
-            mAuthenticationInteractor.lockDevice()
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
-
-            assertThat(isSwipeToDismissEnabled).isTrue()
-        }
-
-    @Test
-    fun isSwipeToDismissEnabled_deviceUnlockedAndAuthMethodSwipe_false() =
-        testScope.runTest {
-            val isSwipeToDismissEnabled by collectLastValue(underTest.isSwipeToDismissEnabled)
-
-            mAuthenticationInteractor.unlockDevice()
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
-
-            assertThat(isSwipeToDismissEnabled).isFalse()
-        }
-
-    @Test
-    fun dismissLockScreen_deviceLockedWithSecureAuthMethod_switchesToBouncer() =
-        testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            mAuthenticationInteractor.lockDevice()
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
-
-            underTest.dismissLockScreen()
-
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
-        }
-
-    @Test
-    fun dismissLockScreen_deviceUnlocked_switchesToGone() =
-        testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            mAuthenticationInteractor.unlockDevice()
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
-
-            underTest.dismissLockScreen()
-
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
-        }
-
-    @Test
-    fun dismissLockScreen_deviceLockedWithInsecureAuthMethod_switchesToGone() =
-        testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            mAuthenticationInteractor.lockDevice()
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
-
-            underTest.dismissLockScreen()
-
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
-        }
-
-    @Test
-    fun deviceLockedInNonLockScreenScene_switchesToLockScreenScene() =
-        testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            runCurrent()
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Gone))
-            runCurrent()
-            mAuthenticationInteractor.unlockDevice()
-            runCurrent()
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
-
-            mAuthenticationInteractor.lockDevice()
-
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
-        }
-
-    @Test
-    fun deviceBiometricUnlockedInLockScreen_bypassEnabled_switchesToGone() =
-        testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            mAuthenticationInteractor.lockDevice()
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.LockScreen))
-            if (!mAuthenticationInteractor.isBypassEnabled.value) {
-                mAuthenticationInteractor.toggleBypassEnabled()
-            }
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
-
-            mAuthenticationInteractor.biometricUnlock()
-
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
-        }
-
-    @Test
-    fun deviceBiometricUnlockedInLockScreen_bypassNotEnabled_doesNotSwitch() =
-        testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            mAuthenticationInteractor.lockDevice()
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.LockScreen))
-            if (mAuthenticationInteractor.isBypassEnabled.value) {
-                mAuthenticationInteractor.toggleBypassEnabled()
-            }
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
-
-            mAuthenticationInteractor.biometricUnlock()
-
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
-        }
-
-    @Test
-    fun switchFromLockScreenToGone_authMethodSwipe_unlocksDevice() =
-        testScope.runTest {
-            val isUnlocked by collectLastValue(mAuthenticationInteractor.isUnlocked)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.LockScreen))
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
-            assertThat(isUnlocked).isFalse()
-
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Gone))
-
-            assertThat(isUnlocked).isTrue()
-        }
-
-    @Test
-    fun switchFromLockScreenToGone_authMethodNotSwipe_doesNotUnlockDevice() =
-        testScope.runTest {
-            val isUnlocked by collectLastValue(mAuthenticationInteractor.isUnlocked)
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.LockScreen))
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
-            assertThat(isUnlocked).isFalse()
-
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Gone))
-
-            assertThat(isUnlocked).isFalse()
-        }
-
-    @Test
-    fun switchFromNonLockScreenToGone_authMethodSwipe_doesNotUnlockDevice() =
-        testScope.runTest {
-            val isUnlocked by collectLastValue(mAuthenticationInteractor.isUnlocked)
-            runCurrent()
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Shade))
-            runCurrent()
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
-            runCurrent()
-            assertThat(isUnlocked).isFalse()
-
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Gone))
-
-            assertThat(isUnlocked).isFalse()
-        }
-
-    @Test
-    fun authMethodChangedToNone_onLockScreenScene_dismissesLockScreen() =
-        testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.LockScreen))
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
-
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.None)
-
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
-        }
-
-    @Test
-    fun authMethodChangedToNone_notOnLockScreenScene_doesNotDismissLockScreen() =
-        testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
-            runCurrent()
-            sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.QuickSettings))
-            runCurrent()
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.QuickSettings))
-
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.None)
-
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.QuickSettings))
-        }
-
-    companion object {
-        private const val CONTAINER_NAME = "container1"
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
new file mode 100644
index 0000000..d622f1c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.domain.interactor
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.scene.SceneTestUtils
+import com.android.systemui.scene.SceneTestUtils.Companion.CONTAINER_1
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class LockscreenSceneInteractorTest : SysuiTestCase() {
+
+    private val testScope = TestScope()
+    private val utils = SceneTestUtils(this, testScope)
+    private val sceneInteractor = utils.sceneInteractor()
+    private val authenticationInteractor =
+        utils.authenticationInteractor(
+            repository = utils.authenticationRepository(),
+        )
+    private val underTest =
+        utils.lockScreenSceneInteractor(
+            authenticationInteractor = authenticationInteractor,
+            sceneInteractor = sceneInteractor,
+            bouncerInteractor =
+                utils.bouncerInteractor(
+                    authenticationInteractor = authenticationInteractor,
+                    sceneInteractor = sceneInteractor,
+                ),
+        )
+
+    @Test
+    fun isDeviceLocked() =
+        testScope.runTest {
+            val isDeviceLocked by collectLastValue(underTest.isDeviceLocked)
+
+            authenticationInteractor.lockDevice()
+            assertThat(isDeviceLocked).isTrue()
+
+            authenticationInteractor.unlockDevice()
+            assertThat(isDeviceLocked).isFalse()
+        }
+
+    @Test
+    fun isSwipeToDismissEnabled_deviceLockedAndAuthMethodSwipe_true() =
+        testScope.runTest {
+            val isSwipeToDismissEnabled by collectLastValue(underTest.isSwipeToDismissEnabled)
+
+            authenticationInteractor.lockDevice()
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
+
+            assertThat(isSwipeToDismissEnabled).isTrue()
+        }
+
+    @Test
+    fun isSwipeToDismissEnabled_deviceUnlockedAndAuthMethodSwipe_false() =
+        testScope.runTest {
+            val isSwipeToDismissEnabled by collectLastValue(underTest.isSwipeToDismissEnabled)
+
+            authenticationInteractor.unlockDevice()
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
+
+            assertThat(isSwipeToDismissEnabled).isFalse()
+        }
+
+    @Test
+    fun dismissLockScreen_deviceLockedWithSecureAuthMethod_switchesToBouncer() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            authenticationInteractor.lockDevice()
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
+
+            underTest.dismissLockscreen()
+
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
+    fun dismissLockScreen_deviceUnlocked_switchesToGone() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            authenticationInteractor.unlockDevice()
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
+
+            underTest.dismissLockscreen()
+
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+        }
+
+    @Test
+    fun dismissLockScreen_deviceLockedWithInsecureAuthMethod_switchesToGone() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            authenticationInteractor.lockDevice()
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
+
+            underTest.dismissLockscreen()
+
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+        }
+
+    @Test
+    fun deviceLockedInNonLockScreenScene_switchesToLockScreenScene() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            runCurrent()
+            sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone))
+            runCurrent()
+            authenticationInteractor.unlockDevice()
+            runCurrent()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+
+            authenticationInteractor.lockDevice()
+
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
+        }
+
+    @Test
+    fun deviceBiometricUnlockedInLockScreen_bypassEnabled_switchesToGone() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
+            if (!authenticationInteractor.isBypassEnabled.value) {
+                authenticationInteractor.toggleBypassEnabled()
+            }
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
+
+            authenticationInteractor.biometricUnlock()
+
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+        }
+
+    @Test
+    fun deviceBiometricUnlockedInLockScreen_bypassNotEnabled_doesNotSwitch() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            authenticationInteractor.lockDevice()
+            sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
+            if (authenticationInteractor.isBypassEnabled.value) {
+                authenticationInteractor.toggleBypassEnabled()
+            }
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
+
+            authenticationInteractor.biometricUnlock()
+
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
+        }
+
+    @Test
+    fun switchFromLockScreenToGone_authMethodSwipe_unlocksDevice() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
+            assertThat(isUnlocked).isFalse()
+
+            sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone))
+
+            assertThat(isUnlocked).isTrue()
+        }
+
+    @Test
+    fun switchFromLockScreenToGone_authMethodNotSwipe_doesNotUnlockDevice() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            assertThat(isUnlocked).isFalse()
+
+            sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone))
+
+            assertThat(isUnlocked).isFalse()
+        }
+
+    @Test
+    fun switchFromNonLockScreenToGone_authMethodSwipe_doesNotUnlockDevice() =
+        testScope.runTest {
+            val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+            runCurrent()
+            sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Shade))
+            runCurrent()
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
+            runCurrent()
+            assertThat(isUnlocked).isFalse()
+
+            sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone))
+
+            assertThat(isUnlocked).isFalse()
+        }
+
+    @Test
+    fun authMethodChangedToNone_onLockScreenScene_dismissesLockScreen() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
+
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.None)
+
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+        }
+
+    @Test
+    fun authMethodChangedToNone_notOnLockScreenScene_doesNotDismissLockScreen() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
+            runCurrent()
+            sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.QuickSettings))
+            runCurrent()
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.QuickSettings))
+
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.None)
+
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.QuickSettings))
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
index eed1e739..b5cb44a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
@@ -44,6 +44,8 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.utils.os.FakeHandler
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -75,6 +77,7 @@
     private lateinit var resources: TestableResources
     private lateinit var trustRepository: FakeTrustRepository
     private lateinit var featureFlags: FakeFeatureFlags
+    private lateinit var testScope: TestScope
 
     @Before
     fun setUp() {
@@ -83,9 +86,10 @@
             .thenReturn(KeyguardSecurityModel.SecurityMode.PIN)
 
         DejankUtils.setImmediate(true)
+        testScope = TestScope()
         mainHandler = FakeHandler(android.os.Looper.getMainLooper())
         trustRepository = FakeTrustRepository()
-        featureFlags = FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, false) }
+        featureFlags = FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) }
         underTest =
             PrimaryBouncerInteractor(
                 repository,
@@ -100,6 +104,7 @@
                 keyguardUpdateMonitor,
                 trustRepository,
                 featureFlags,
+                testScope.backgroundScope,
             )
         whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
         whenever(repository.primaryBouncerShow.value).thenReturn(false)
@@ -154,6 +159,7 @@
         verify(repository).setPrimaryShow(false)
         verify(mPrimaryBouncerCallbackInteractor).dispatchVisibilityChanged(View.INVISIBLE)
         verify(repository).setPrimaryStartDisappearAnimation(null)
+        verify(repository).setPanelExpansion(EXPANSION_HIDDEN)
     }
 
     @Test
@@ -398,7 +404,6 @@
         mainHandler.setMode(FakeHandler.Mode.QUEUEING)
 
         // GIVEN bouncer should be delayed due to face auth
-        featureFlags.apply { set(Flags.DELAY_BOUNCER, true) }
         whenever(keyguardStateController.isFaceAuthEnabled).thenReturn(true)
         whenever(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE))
             .thenReturn(true)
@@ -420,26 +425,29 @@
 
     @Test
     fun delayBouncerWhenActiveUnlockPossible() {
-        mainHandler.setMode(FakeHandler.Mode.QUEUEING)
+        testScope.run {
+            mainHandler.setMode(FakeHandler.Mode.QUEUEING)
 
-        // GIVEN bouncer should be delayed due to active unlock
-        featureFlags.apply { set(Flags.DELAY_BOUNCER, true) }
-        trustRepository.setCurrentUserActiveUnlockAvailable(true)
-        whenever(keyguardUpdateMonitor.canTriggerActiveUnlockBasedOnDeviceState()).thenReturn(true)
+            // GIVEN bouncer should be delayed due to active unlock
+            trustRepository.setCurrentUserActiveUnlockAvailable(true)
+            whenever(keyguardUpdateMonitor.canTriggerActiveUnlockBasedOnDeviceState())
+                .thenReturn(true)
+            runCurrent()
 
-        // WHEN bouncer show is requested
-        underTest.show(true)
+            // WHEN bouncer show is requested
+            underTest.show(true)
 
-        // THEN primary show & primary showing soon were scheduled to update
-        verify(repository, never()).setPrimaryShow(true)
-        verify(repository, never()).setPrimaryShowingSoon(false)
+            // THEN primary show & primary showing soon were scheduled to update
+            verify(repository, never()).setPrimaryShow(true)
+            verify(repository, never()).setPrimaryShowingSoon(false)
 
-        // WHEN all queued messages are dispatched
-        mainHandler.dispatchQueuedMessages()
+            // WHEN all queued messages are dispatched
+            mainHandler.dispatchQueuedMessages()
 
-        // THEN primary show & primary showing soon are updated
-        verify(repository).setPrimaryShow(true)
-        verify(repository).setPrimaryShowingSoon(false)
+            // THEN primary show & primary showing soon are updated
+            verify(repository).setPrimaryShow(true)
+            verify(repository).setPrimaryShowingSoon(false)
+        }
     }
 
     private fun updateSideFpsVisibilityParameters(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
index 5056b43..b288fbc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.BouncerView
 import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
@@ -34,6 +35,7 @@
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.utils.os.FakeHandler
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -75,7 +77,8 @@
                 context,
                 keyguardUpdateMonitor,
                 Mockito.mock(TrustRepository::class.java),
-                FakeFeatureFlags(),
+                FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) },
+                TestScope().backgroundScope,
             )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
index 69d43af..8a36dbc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
@@ -211,6 +211,7 @@
             )
         val keyguardLongPressInteractor =
             KeyguardLongPressInteractor(
+                appContext = mContext,
                 scope = testScope.backgroundScope,
                 transitionInteractor =
                     KeyguardTransitionInteractor(
@@ -240,6 +241,7 @@
                         devicePolicyManager = devicePolicyManager,
                         dockManager = dockManager,
                         backgroundDispatcher = testDispatcher,
+                        appContext = mContext,
                     ),
                 bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository),
                 burnInHelperWrapper = burnInHelperWrapper,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt
index e9f1ac1..15707c9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.BouncerView
 import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
@@ -38,6 +39,7 @@
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -81,7 +83,8 @@
                 context,
                 keyguardUpdateMonitor,
                 Mockito.mock(TrustRepository::class.java),
-                FakeFeatureFlags(),
+                FakeFeatureFlags().apply { set(Flags.DELAY_BOUNCER, true) },
+                TestScope().backgroundScope,
             )
         underTest = KeyguardBouncerViewModel(bouncerView, bouncerInteractor)
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockScreenSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockScreenSceneViewModelTest.kt
deleted file mode 100644
index d335b09..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockScreenSceneViewModelTest.kt
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.keyguard.ui.viewmodel
-
-import androidx.test.filters.SmallTest
-import com.android.systemui.R
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.authentication.data.repository.AuthenticationRepositoryImpl
-import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
-import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
-import com.android.systemui.bouncer.data.repo.BouncerRepository
-import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
-import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.domain.interactor.LockScreenSceneInteractor
-import com.android.systemui.scene.data.repository.fakeSceneContainerRepository
-import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.model.SceneKey
-import com.android.systemui.scene.shared.model.SceneModel
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@OptIn(ExperimentalCoroutinesApi::class)
-@SmallTest
-@RunWith(JUnit4::class)
-class LockScreenSceneViewModelTest : SysuiTestCase() {
-
-    private val testScope = TestScope()
-    private val sceneInteractor =
-        SceneInteractor(
-            repository = fakeSceneContainerRepository(),
-        )
-    private val mAuthenticationInteractor =
-        AuthenticationInteractor(
-            applicationScope = testScope.backgroundScope,
-            repository = AuthenticationRepositoryImpl(),
-        )
-
-    private val underTest =
-        LockScreenSceneViewModel(
-            applicationScope = testScope.backgroundScope,
-            interactorFactory =
-                object : LockScreenSceneInteractor.Factory {
-                    override fun create(containerName: String): LockScreenSceneInteractor {
-                        return LockScreenSceneInteractor(
-                            applicationScope = testScope.backgroundScope,
-                            authenticationInteractor = mAuthenticationInteractor,
-                            bouncerInteractorFactory =
-                                object : BouncerInteractor.Factory {
-                                    override fun create(containerName: String): BouncerInteractor {
-                                        return BouncerInteractor(
-                                            applicationScope = testScope.backgroundScope,
-                                            applicationContext = context,
-                                            repository = BouncerRepository(),
-                                            authenticationInteractor = mAuthenticationInteractor,
-                                            sceneInteractor = sceneInteractor,
-                                            containerName = containerName,
-                                        )
-                                    }
-                                },
-                            sceneInteractor = sceneInteractor,
-                            containerName = CONTAINER_NAME,
-                        )
-                    }
-                },
-            containerName = CONTAINER_NAME
-        )
-
-    @Test
-    fun lockButtonIcon_whenLocked() =
-        testScope.runTest {
-            val lockButtonIcon by collectLastValue(underTest.lockButtonIcon)
-            mAuthenticationInteractor.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
-            )
-            mAuthenticationInteractor.lockDevice()
-
-            assertThat((lockButtonIcon as? Icon.Resource)?.res)
-                .isEqualTo(R.drawable.ic_device_lock_on)
-        }
-
-    @Test
-    fun lockButtonIcon_whenUnlocked() =
-        testScope.runTest {
-            val lockButtonIcon by collectLastValue(underTest.lockButtonIcon)
-            mAuthenticationInteractor.setAuthenticationMethod(
-                AuthenticationMethodModel.Password("password")
-            )
-            mAuthenticationInteractor.unlockDevice()
-
-            assertThat((lockButtonIcon as? Icon.Resource)?.res)
-                .isEqualTo(R.drawable.ic_device_lock_off)
-        }
-
-    @Test
-    fun upTransitionSceneKey_swipeToUnlockedEnabled_gone() =
-        testScope.runTest {
-            val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
-            mAuthenticationInteractor.lockDevice()
-
-            assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Gone)
-        }
-
-    @Test
-    fun upTransitionSceneKey_swipeToUnlockedNotEnabled_bouncer() =
-        testScope.runTest {
-            val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
-            mAuthenticationInteractor.lockDevice()
-
-            assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Bouncer)
-        }
-
-    @Test
-    fun onLockButtonClicked_deviceLockedSecurely_switchesToBouncer() =
-        testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
-            mAuthenticationInteractor.lockDevice()
-            runCurrent()
-
-            underTest.onLockButtonClicked()
-
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
-        }
-
-    @Test
-    fun onContentClicked_deviceUnlocked_switchesToGone() =
-        testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
-            mAuthenticationInteractor.unlockDevice()
-            runCurrent()
-
-            underTest.onContentClicked()
-
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
-        }
-
-    @Test
-    fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
-        testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
-            mAuthenticationInteractor.lockDevice()
-            runCurrent()
-
-            underTest.onContentClicked()
-
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
-        }
-
-    @Test
-    fun onLockButtonClicked_deviceUnlocked_switchesToGone() =
-        testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
-            mAuthenticationInteractor.unlockDevice()
-            runCurrent()
-
-            underTest.onLockButtonClicked()
-
-            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
-        }
-
-    companion object {
-        private const val CONTAINER_NAME = "container1"
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
new file mode 100644
index 0000000..8ba3f0f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
+import com.android.systemui.scene.SceneTestUtils
+import com.android.systemui.scene.SceneTestUtils.Companion.CONTAINER_1
+import com.android.systemui.scene.shared.model.SceneKey
+import com.android.systemui.scene.shared.model.SceneModel
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class LockscreenSceneViewModelTest : SysuiTestCase() {
+
+    private val testScope = TestScope()
+    private val utils = SceneTestUtils(this, testScope)
+    private val sceneInteractor = utils.sceneInteractor()
+    private val authenticationInteractor =
+        utils.authenticationInteractor(
+            repository = utils.authenticationRepository(),
+        )
+
+    private val underTest =
+        LockscreenSceneViewModel(
+            applicationScope = testScope.backgroundScope,
+            interactorFactory =
+                object : LockscreenSceneInteractor.Factory {
+                    override fun create(containerName: String): LockscreenSceneInteractor {
+                        return utils.lockScreenSceneInteractor(
+                            authenticationInteractor = authenticationInteractor,
+                            sceneInteractor = sceneInteractor,
+                            bouncerInteractor =
+                                utils.bouncerInteractor(
+                                    authenticationInteractor = authenticationInteractor,
+                                    sceneInteractor = sceneInteractor,
+                                ),
+                        )
+                    }
+                },
+            containerName = CONTAINER_1
+        )
+
+    @Test
+    fun lockButtonIcon_whenLocked() =
+        testScope.runTest {
+            val lockButtonIcon by collectLastValue(underTest.lockButtonIcon)
+            authenticationInteractor.setAuthenticationMethod(
+                AuthenticationMethodModel.Password("password")
+            )
+            authenticationInteractor.lockDevice()
+
+            assertThat((lockButtonIcon as? Icon.Resource)?.res)
+                .isEqualTo(R.drawable.ic_device_lock_on)
+        }
+
+    @Test
+    fun lockButtonIcon_whenUnlocked() =
+        testScope.runTest {
+            val lockButtonIcon by collectLastValue(underTest.lockButtonIcon)
+            authenticationInteractor.setAuthenticationMethod(
+                AuthenticationMethodModel.Password("password")
+            )
+            authenticationInteractor.unlockDevice()
+
+            assertThat((lockButtonIcon as? Icon.Resource)?.res)
+                .isEqualTo(R.drawable.ic_device_lock_off)
+        }
+
+    @Test
+    fun upTransitionSceneKey_swipeToUnlockedEnabled_gone() =
+        testScope.runTest {
+            val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
+            authenticationInteractor.lockDevice()
+
+            assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Gone)
+        }
+
+    @Test
+    fun upTransitionSceneKey_swipeToUnlockedNotEnabled_bouncer() =
+        testScope.runTest {
+            val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.lockDevice()
+
+            assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Bouncer)
+        }
+
+    @Test
+    fun onLockButtonClicked_deviceLockedSecurely_switchesToBouncer() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.lockDevice()
+            runCurrent()
+
+            underTest.onLockButtonClicked()
+
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
+    fun onContentClicked_deviceUnlocked_switchesToGone() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.unlockDevice()
+            runCurrent()
+
+            underTest.onContentClicked()
+
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+        }
+
+    @Test
+    fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.lockDevice()
+            runCurrent()
+
+            underTest.onContentClicked()
+
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+        }
+
+    @Test
+    fun onLockButtonClicked_deviceUnlocked_switchesToGone() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.unlockDevice()
+            runCurrent()
+
+            underTest.onLockButtonClicked()
+
+            assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
index d428db7b..56698e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
@@ -25,6 +25,7 @@
 import android.app.smartspace.SmartspaceManager
 import android.app.smartspace.SmartspaceTarget
 import android.content.Intent
+import android.content.pm.PackageManager
 import android.graphics.Bitmap
 import android.graphics.drawable.Icon
 import android.media.MediaDescription
@@ -76,6 +77,7 @@
 import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito
+import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
@@ -192,7 +194,7 @@
                 mediaFlags = mediaFlags,
                 logger = logger,
                 smartspaceManager = smartspaceManager,
-                keyguardUpdateMonitor = keyguardUpdateMonitor
+                keyguardUpdateMonitor = keyguardUpdateMonitor,
             )
         verify(tunerService)
             .addTunable(capture(tunableCaptor), eq(Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION))
@@ -517,19 +519,120 @@
     }
 
     @Test
-    fun testOnNotificationRemoved_emptyTitle_notConverted() {
-        // GIVEN that the manager has a notification with a resume action and empty title.
+    fun testOnNotificationAdded_emptyTitle_hasPlaceholder() {
+        // When the manager has a notification with an empty title, and the app is not
+        // required to include a non-empty title
+        val mockPackageManager = mock(PackageManager::class.java)
+        context.setMockPackageManager(mockPackageManager)
+        whenever(mockPackageManager.getApplicationLabel(any())).thenReturn(APP_NAME)
         whenever(controller.metadata)
             .thenReturn(
                 metadataBuilder
                     .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_EMPTY_TITLE)
                     .build()
             )
+        mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+
+        // Then a media control is created with a placeholder title string
+        assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+        assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+        verify(listener)
+            .onMediaDataLoaded(
+                eq(KEY),
+                eq(null),
+                capture(mediaDataCaptor),
+                eq(true),
+                eq(0),
+                eq(false)
+            )
+        val placeholderTitle = context.getString(R.string.controls_media_empty_title, APP_NAME)
+        assertThat(mediaDataCaptor.value.song).isEqualTo(placeholderTitle)
+    }
+
+    @Test
+    fun testOnNotificationAdded_blankTitle_hasPlaceholder() {
+        // GIVEN that the manager has a notification with a blank title, and the app is not
+        // required to include a non-empty title
+        val mockPackageManager = mock(PackageManager::class.java)
+        context.setMockPackageManager(mockPackageManager)
+        whenever(mockPackageManager.getApplicationLabel(any())).thenReturn(APP_NAME)
+        whenever(controller.metadata)
+            .thenReturn(
+                metadataBuilder
+                    .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_BLANK_TITLE)
+                    .build()
+            )
+        mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+
+        // Then a media control is created with a placeholder title string
+        assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+        assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+        verify(listener)
+            .onMediaDataLoaded(
+                eq(KEY),
+                eq(null),
+                capture(mediaDataCaptor),
+                eq(true),
+                eq(0),
+                eq(false)
+            )
+        val placeholderTitle = context.getString(R.string.controls_media_empty_title, APP_NAME)
+        assertThat(mediaDataCaptor.value.song).isEqualTo(placeholderTitle)
+    }
+
+    @Test
+    fun testOnNotificationAdded_emptyMetadata_usesNotificationTitle() {
+        // When the app sets the metadata title fields to empty strings, but does include a
+        // non-blank notification title
+        val mockPackageManager = mock(PackageManager::class.java)
+        context.setMockPackageManager(mockPackageManager)
+        whenever(mockPackageManager.getApplicationLabel(any())).thenReturn(APP_NAME)
+        whenever(controller.metadata)
+            .thenReturn(
+                metadataBuilder
+                    .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_EMPTY_TITLE)
+                    .putString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE, SESSION_EMPTY_TITLE)
+                    .build()
+            )
+        mediaNotification =
+            SbnBuilder().run {
+                setPkg(PACKAGE_NAME)
+                modifyNotification(context).also {
+                    it.setSmallIcon(android.R.drawable.ic_media_pause)
+                    it.setContentTitle(SESSION_TITLE)
+                    it.setStyle(MediaStyle().apply { setMediaSession(session.sessionToken) })
+                }
+                build()
+            }
+        mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+
+        // Then the media control is added using the notification's title
+        assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+        assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+        verify(listener)
+            .onMediaDataLoaded(
+                eq(KEY),
+                eq(null),
+                capture(mediaDataCaptor),
+                eq(true),
+                eq(0),
+                eq(false)
+            )
+        assertThat(mediaDataCaptor.value.song).isEqualTo(SESSION_TITLE)
+    }
+
+    @Test
+    fun testOnNotificationRemoved_emptyTitle_notConverted() {
+        // GIVEN that the manager has a notification with a resume action and empty title.
         addNotificationAndLoad()
         val data = mediaDataCaptor.value
         val instanceId = data.instanceId
         assertThat(data.resumption).isFalse()
-        mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
+        mediaDataManager.onMediaDataLoaded(
+            KEY,
+            null,
+            data.copy(song = SESSION_EMPTY_TITLE, resumeAction = Runnable {})
+        )
 
         // WHEN the notification is removed
         reset(listener)
@@ -554,17 +657,15 @@
     @Test
     fun testOnNotificationRemoved_blankTitle_notConverted() {
         // GIVEN that the manager has a notification with a resume action and blank title.
-        whenever(controller.metadata)
-            .thenReturn(
-                metadataBuilder
-                    .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_BLANK_TITLE)
-                    .build()
-            )
         addNotificationAndLoad()
         val data = mediaDataCaptor.value
         val instanceId = data.instanceId
         assertThat(data.resumption).isFalse()
-        mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
+        mediaDataManager.onMediaDataLoaded(
+            KEY,
+            null,
+            data.copy(song = SESSION_BLANK_TITLE, resumeAction = Runnable {})
+        )
 
         // WHEN the notification is removed
         reset(listener)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
index 1e465c7..f030a03 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
@@ -230,7 +230,6 @@
         FakeFeatureFlags().apply {
             this.set(Flags.UMO_SURFACE_RIPPLE, false)
             this.set(Flags.UMO_TURBULENCE_NOISE, false)
-            this.set(Flags.MEDIA_FALSING_PENALTY, true)
             this.set(Flags.MEDIA_EXPLICIT_INDICATOR, true)
             this.set(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE, false)
         }
@@ -530,6 +529,8 @@
         verify(collapsedSet).setVisibility(R.id.actionPlayPause, ConstraintSet.VISIBLE)
 
         assertThat(actionNext.isEnabled()).isTrue()
+        assertThat(actionNext.isFocusable()).isTrue()
+        assertThat(actionNext.isClickable()).isTrue()
         assertThat(actionNext.contentDescription).isEqualTo("next")
         verify(collapsedSet).setVisibility(R.id.actionNext, ConstraintSet.VISIBLE)
 
@@ -576,6 +577,8 @@
 
         assertThat(actionPrev.isEnabled()).isFalse()
         assertThat(actionPrev.drawable).isNull()
+        assertThat(actionPrev.isFocusable()).isFalse()
+        assertThat(actionPrev.isClickable()).isFalse()
         verify(expandedSet).setVisibility(R.id.actionPrev, ConstraintSet.INVISIBLE)
 
         assertThat(actionNext.isEnabled()).isFalse()
@@ -610,6 +613,8 @@
 
         assertThat(actionNext.isEnabled()).isFalse()
         assertThat(actionNext.drawable).isNull()
+        assertThat(actionNext.isFocusable()).isFalse()
+        assertThat(actionNext.isClickable()).isFalse()
         verify(expandedSet).setVisibility(R.id.actionNext, ConstraintSet.INVISIBLE)
     }
 
@@ -2376,35 +2381,27 @@
     }
 
     @Test
-    fun onButtonClick_turbulenceNoiseFlagEnabled_createsRipplesFinishedListener() {
-        fakeFeatureFlag.set(Flags.UMO_SURFACE_RIPPLE, true)
-        fakeFeatureFlag.set(Flags.UMO_TURBULENCE_NOISE, true)
-
-        player.attachPlayer(viewHolder)
-
-        assertThat(player.mRipplesFinishedListener).isNotNull()
-    }
-
-    @Test
-    fun onButtonClick_turbulenceNoiseFlagDisabled_doesNotCreateRipplesFinishedListener() {
-        fakeFeatureFlag.set(Flags.UMO_SURFACE_RIPPLE, true)
-        fakeFeatureFlag.set(Flags.UMO_TURBULENCE_NOISE, false)
-
-        player.attachPlayer(viewHolder)
-
-        assertThat(player.mRipplesFinishedListener).isNull()
-    }
-
-    @Test
     fun playTurbulenceNoise_finishesAfterDuration() {
         fakeFeatureFlag.set(Flags.UMO_SURFACE_RIPPLE, true)
         fakeFeatureFlag.set(Flags.UMO_TURBULENCE_NOISE, true)
 
+        val semanticActions =
+            MediaButton(
+                playOrPause =
+                    MediaAction(
+                        icon = null,
+                        action = {},
+                        contentDescription = "play",
+                        background = null
+                    )
+            )
+        val data = mediaData.copy(semanticActions = semanticActions)
         player.attachPlayer(viewHolder)
+        player.bindPlayer(data, KEY)
+
+        viewHolder.actionPlayPause.callOnClick()
 
         mainExecutor.execute {
-            player.mRipplesFinishedListener.onRipplesFinish()
-
             assertThat(turbulenceNoiseView.visibility).isEqualTo(View.VISIBLE)
 
             clock.advanceTime(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
index faca8a91d..c89897c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
@@ -22,6 +22,7 @@
 
 import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_GO_TO_APP;
 import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_NONE;
+import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_TRANSFER;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -94,10 +95,7 @@
 
     @Before
     public void setUp() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(false);
-        when(mMediaOutputController.isSubStatusSupported()).thenReturn(false);
         when(mMediaOutputController.getMediaItemList()).thenReturn(mMediaItems);
-        when(mMediaOutputController.getMediaDevices()).thenReturn(mMediaDevices);
         when(mMediaOutputController.hasAdjustVolumeUserRestriction()).thenReturn(false);
         when(mMediaOutputController.isAnyDeviceTransferring()).thenReturn(false);
         when(mMediaOutputController.getDeviceIconCompat(mMediaDevice1)).thenReturn(mIconCompat);
@@ -126,85 +124,24 @@
     }
 
     @Test
-    public void getItemCount_containExtraOneForPairNew() {
-        assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size() + 1);
-    }
-
-    @Test
-    public void getItemId_validPosition_returnCorrespondingId() {
-        assertThat(mMediaOutputAdapter.getItemId(0)).isEqualTo(mMediaDevices.get(
-                0).getId().hashCode());
-    }
-
-    @Test
-    public void getItemId_invalidPosition_returnPosition() {
-        int invalidPosition = mMediaDevices.size() + 1;
-        assertThat(mMediaOutputAdapter.getItemId(invalidPosition)).isEqualTo(invalidPosition);
-    }
-
-    @Test
-    public void advanced_getItemCount_returnsMediaItemSize() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
+    public void getItemCount_returnsMediaItemSize() {
         assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaItems.size());
     }
 
     @Test
-    public void advanced_getItemId_validPosition_returnCorrespondingId() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
+    public void getItemId_validPosition_returnCorrespondingId() {
         assertThat(mMediaOutputAdapter.getItemId(0)).isEqualTo(mMediaItems.get(
                 0).getMediaDevice().get().getId().hashCode());
     }
 
     @Test
-    public void advanced_getItemId_invalidPosition_returnPosition() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
+    public void getItemId_invalidPosition_returnPosition() {
         int invalidPosition = mMediaItems.size() + 1;
         assertThat(mMediaOutputAdapter.getItemId(invalidPosition)).isEqualTo(invalidPosition);
     }
 
     @Test
     public void onBindViewHolder_bindPairNew_verifyView() {
-        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2);
-
-        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mViewHolder.mTitleText.getText()).isEqualTo(mContext.getText(
-                R.string.media_output_dialog_pairing_new));
-    }
-
-    @Test
-    public void onBindViewHolder_bindGroup_withSessionName_verifyView() {
-        when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
-        when(mMediaOutputController.getSessionName()).thenReturn(TEST_SESSION_NAME);
-        mMediaOutputAdapter.getItemCount();
-        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
-
-        assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
-    }
-
-    @Test
-    public void onBindViewHolder_bindGroup_noSessionName_verifyView() {
-        when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
-        when(mMediaOutputController.getSessionName()).thenReturn(null);
-        mMediaOutputAdapter.getItemCount();
-        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
-
-        assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
-    }
-
-    @Test
-    public void advanced_onBindViewHolder_bindPairNew_verifyView() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
         mMediaOutputAdapter = new MediaOutputAdapter(mMediaOutputController);
         mMediaOutputAdapter.updateItems();
         mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
@@ -222,8 +159,7 @@
     }
 
     @Test
-    public void advanced_onBindViewHolder_bindGroup_withSessionName_verifyView() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
+    public void onBindViewHolder_bindGroup_withSessionName_verifyView() {
         when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(
                 mMediaItems.stream().map((item) -> item.getMediaDevice().get()).collect(
                         Collectors.toList()));
@@ -243,8 +179,7 @@
     }
 
     @Test
-    public void advanced_onBindViewHolder_bindGroup_noSessionName_verifyView() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
+    public void onBindViewHolder_bindGroup_noSessionName_verifyView() {
         when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(
                 mMediaItems.stream().map((item) -> item.getMediaDevice().get()).collect(
                         Collectors.toList()));
@@ -277,8 +212,7 @@
     }
 
     @Test
-    public void advanced_onBindViewHolder_bindNonRemoteConnectedDevice_verifyView() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
+    public void onBindViewHolder_bindNonRemoteConnectedDevice_verifyView() {
         when(mMediaOutputController.isActiveRemoteDevice(mMediaDevice1)).thenReturn(false);
         mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
                 .onCreateViewHolder(new LinearLayout(mContext), 0);
@@ -294,8 +228,7 @@
     }
 
     @Test
-    public void advanced_onBindViewHolder_bindConnectedRemoteDevice_verifyView() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
+    public void onBindViewHolder_bindConnectedRemoteDevice_verifyView() {
         when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(
                 ImmutableList.of(mMediaDevice2));
         when(mMediaOutputController.isCurrentConnectedDeviceRemote()).thenReturn(true);
@@ -314,8 +247,7 @@
     }
 
     @Test
-    public void advanced_onBindViewHolder_bindSingleConnectedRemoteDevice_verifyView() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
+    public void onBindViewHolder_bindSingleConnectedRemoteDevice_verifyView() {
         when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(
                 ImmutableList.of());
         when(mMediaOutputController.isCurrentConnectedDeviceRemote()).thenReturn(true);
@@ -351,6 +283,8 @@
         when(mMediaDevice1.isMutingExpectedDevice()).thenReturn(true);
         when(mMediaOutputController.isCurrentConnectedDeviceRemote()).thenReturn(false);
         when(mMediaOutputController.isActiveRemoteDevice(mMediaDevice1)).thenReturn(false);
+        mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+                .onCreateViewHolder(new LinearLayout(mContext), 0);
         mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
 
         assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.GONE);
@@ -446,8 +380,6 @@
 
     @Test
     public void subStatusSupported_onBindViewHolder_bindHostDeviceWithOngoingSession_verifyView() {
-        when(mMediaOutputController.isSubStatusSupported()).thenReturn(true);
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
         when(mMediaOutputController.isVolumeControlEnabled(mMediaDevice1)).thenReturn(true);
         when(mMediaDevice1.isHostForOngoingSession()).thenReturn(true);
         when(mMediaDevice1.hasSubtext()).thenReturn(true);
@@ -477,8 +409,6 @@
     public void subStatusSupported_onBindViewHolder_bindDeviceRequirePremium_verifyView() {
         String deviceStatus = (String) mContext.getText(
                 R.string.media_output_status_require_premium);
-        when(mMediaOutputController.isSubStatusSupported()).thenReturn(true);
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
         when(mMediaDevice2.hasSubtext()).thenReturn(true);
         when(mMediaDevice2.getSubtext()).thenReturn(SUBTEXT_SUBSCRIPTION_REQUIRED);
         when(mMediaDevice2.getSubtextString()).thenReturn(deviceStatus);
@@ -503,8 +433,6 @@
     public void subStatusSupported_onBindViewHolder_bindDeviceWithAdPlaying_verifyView() {
         String deviceStatus = (String) mContext.getText(
                 R.string.media_output_status_try_after_ad);
-        when(mMediaOutputController.isSubStatusSupported()).thenReturn(true);
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
         when(mMediaDevice2.hasSubtext()).thenReturn(true);
         when(mMediaDevice2.getSubtext()).thenReturn(SUBTEXT_AD_ROUTING_DISALLOWED);
         when(mMediaDevice2.getSubtextString()).thenReturn(deviceStatus);
@@ -528,8 +456,6 @@
 
     @Test
     public void subStatusSupported_onBindViewHolder_bindDeviceWithOngoingSession_verifyView() {
-        when(mMediaOutputController.isSubStatusSupported()).thenReturn(true);
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
         when(mMediaDevice1.hasSubtext()).thenReturn(true);
         when(mMediaDevice1.getSubtext()).thenReturn(SUBTEXT_CUSTOM);
         when(mMediaDevice1.getSubtextString()).thenReturn(TEST_CUSTOM_SUBTEXT);
@@ -600,15 +526,6 @@
 
     @Test
     public void onItemClick_clickPairNew_verifyLaunchBluetoothPairing() {
-        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2);
-        mViewHolder.mContainerLayout.performClick();
-
-        verify(mMediaOutputController).launchBluetoothPairing(mViewHolder.mContainerLayout);
-    }
-
-    @Test
-    public void advanced_onItemClick_clickPairNew_verifyLaunchBluetoothPairing() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
         mMediaOutputAdapter = new MediaOutputAdapter(mMediaOutputController);
         mMediaOutputAdapter.updateItems();
         mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
@@ -626,6 +543,12 @@
         when(mMediaOutputController.isCurrentOutputDeviceHasSessionOngoing()).thenReturn(false);
         assertThat(mMediaDevice2.getState()).isEqualTo(
                 LocalMediaManager.MediaDeviceState.STATE_DISCONNECTED);
+        when(mMediaDevice2.getSelectionBehavior()).thenReturn(SELECTION_BEHAVIOR_TRANSFER);
+        mMediaOutputAdapter = new MediaOutputAdapter(mMediaOutputController);
+        mMediaOutputAdapter.updateItems();
+        mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+                .onCreateViewHolder(new LinearLayout(mContext), 0);
+        mMediaOutputAdapter.getItemCount();
         mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
         mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
         mViewHolder.mContainerLayout.performClick();
@@ -638,7 +561,13 @@
         when(mMediaOutputController.isCurrentOutputDeviceHasSessionOngoing()).thenReturn(true);
         assertThat(mMediaDevice2.getState()).isEqualTo(
                 LocalMediaManager.MediaDeviceState.STATE_DISCONNECTED);
+        when(mMediaDevice2.getSelectionBehavior()).thenReturn(SELECTION_BEHAVIOR_TRANSFER);
+        mMediaOutputAdapter = new MediaOutputAdapter(mMediaOutputController);
+        mMediaOutputAdapter.updateItems();
+        mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+                .onCreateViewHolder(new LinearLayout(mContext), 0);
         MediaOutputAdapter.MediaDeviceViewHolder spyMediaDeviceViewHolder = spy(mViewHolder);
+        mMediaOutputAdapter.getItemCount();
 
         mMediaOutputAdapter.onBindViewHolder(spyMediaDeviceViewHolder, 0);
         mMediaOutputAdapter.onBindViewHolder(spyMediaDeviceViewHolder, 1);
@@ -662,20 +591,7 @@
     }
 
     @Test
-    public void onItemClick_clicksSelectableDevice_triggerGrouping() {
-        List<MediaDevice> selectableDevices = new ArrayList<>();
-        selectableDevices.add(mMediaDevice2);
-        when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(selectableDevices);
-        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
-
-        mViewHolder.mContainerLayout.performClick();
-
-        verify(mMediaOutputController).addDeviceToPlayMedia(mMediaDevice2);
-    }
-
-    @Test
-    public void advanced_onGroupActionTriggered_clicksEndAreaOfSelectableDevice_triggerGrouping() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
+    public void onGroupActionTriggered_clicksEndAreaOfSelectableDevice_triggerGrouping() {
         List<MediaDevice> selectableDevices = new ArrayList<>();
         selectableDevices.add(mMediaDevice2);
         when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(selectableDevices);
@@ -689,8 +605,7 @@
     }
 
     @Test
-    public void advanced_onGroupActionTriggered_clickSelectedRemoteDevice_triggerUngrouping() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
+    public void onGroupActionTriggered_clickSelectedRemoteDevice_triggerUngrouping() {
         when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(
                 ImmutableList.of(mMediaDevice2));
         when(mMediaOutputController.getDeselectableMediaDevice()).thenReturn(
@@ -707,21 +622,6 @@
 
     @Test
     public void onItemClick_onGroupActionTriggered_verifySeekbarDisabled() {
-        when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
-        List<MediaDevice> selectableDevices = new ArrayList<>();
-        selectableDevices.add(mMediaDevice1);
-        when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(selectableDevices);
-        when(mMediaOutputController.hasAdjustVolumeUserRestriction()).thenReturn(true);
-        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
-
-        mViewHolder.mContainerLayout.performClick();
-
-        assertThat(mViewHolder.mSeekBar.isEnabled()).isFalse();
-    }
-
-    @Test
-    public void advanced_onItemClick_onGroupActionTriggered_verifySeekbarDisabled() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
         when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(
                 mMediaItems.stream().map((item) -> item.getMediaDevice().get()).collect(
                         Collectors.toList()));
@@ -764,7 +664,6 @@
 
     @Test
     public void updateItems_controllerItemsUpdated_notUpdatesInAdapterUntilUpdateItems() {
-        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
         mMediaOutputAdapter.updateItems();
         List<MediaItem> updatedList = new ArrayList<>();
         updatedList.add(new MediaItem());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index 480d59c..f79c53d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -54,6 +54,7 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 
 import org.junit.Before;
@@ -91,6 +92,7 @@
     private PowerExemptionManager mPowerExemptionManager = mock(PowerExemptionManager.class);
     private KeyguardManager mKeyguardManager = mock(KeyguardManager.class);
     private FeatureFlags mFlags = mock(FeatureFlags.class);
+    private UserTracker mUserTracker = mock(UserTracker.class);
 
     private List<MediaController> mMediaControllers = new ArrayList<>();
     private MediaOutputBaseDialogImpl mMediaOutputBaseDialogImpl;
@@ -123,7 +125,7 @@
                 mMediaSessionManager, mLocalBluetoothManager, mStarter,
                 mNotifCollection, mDialogLaunchAnimator,
                 Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags);
+                mKeyguardManager, mFlags, mUserTracker);
         mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext, mBroadcastSender,
                 mMediaOutputController);
         mMediaOutputBaseDialogImpl.onCreate(new Bundle());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java
index 891a6f8..705b485 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogTest.java
@@ -50,6 +50,7 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 
 import org.junit.After;
@@ -95,6 +96,7 @@
     private PowerExemptionManager mPowerExemptionManager = mock(PowerExemptionManager.class);
     private KeyguardManager mKeyguardManager = mock(KeyguardManager.class);
     private FeatureFlags mFlags = mock(FeatureFlags.class);
+    private UserTracker mUserTracker = mock(UserTracker.class);
 
     private MediaOutputBroadcastDialog mMediaOutputBroadcastDialog;
     private MediaOutputController mMediaOutputController;
@@ -109,7 +111,7 @@
                 mMediaSessionManager, mLocalBluetoothManager, mStarter,
                 mNotifCollection, mDialogLaunchAnimator,
                 Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags);
+                mKeyguardManager, mFlags, mUserTracker);
         mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
         mMediaOutputBroadcastDialog = new MediaOutputBroadcastDialog(mContext, false,
                 mBroadcastSender, mMediaOutputController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
index 299303d..9f06b5f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
@@ -30,6 +30,7 @@
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.KeyguardManager;
@@ -48,13 +49,18 @@
 import android.media.MediaRoute2Info;
 import android.media.NearbyDevice;
 import android.media.RoutingSessionInfo;
+import android.media.session.ISessionController;
 import android.media.session.MediaController;
+import android.media.session.MediaSession;
 import android.media.session.MediaSessionManager;
 import android.media.session.PlaybackState;
+import android.os.Bundle;
 import android.os.PowerExemptionManager;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
 import android.text.TextUtils;
 import android.view.View;
 
@@ -70,9 +76,9 @@
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 
@@ -91,6 +97,7 @@
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class MediaOutputControllerTest extends SysuiTestCase {
 
     private static final String TEST_PACKAGE_NAME = "com.test.package.name";
@@ -111,7 +118,7 @@
     private NearbyMediaDevicesManager mNearbyMediaDevicesManager;
     // Mock
     @Mock
-    private MediaController mMediaController;
+    private MediaController mSessionMediaController;
     @Mock
     private MediaSessionManager mMediaSessionManager;
     @Mock
@@ -151,10 +158,15 @@
     @Mock
     private PlaybackState mPlaybackState;
 
+    @Mock
+    private UserTracker mUserTracker;
+
     private FeatureFlags mFlags = mock(FeatureFlags.class);
     private View mDialogLaunchView = mock(View.class);
     private MediaOutputController.Callback mCallback = mock(MediaOutputController.Callback.class);
 
+    final Notification mNotification = mock(Notification.class);
+
     private Context mSpyContext;
     private MediaOutputController mMediaOutputController;
     private LocalMediaManager mLocalMediaManager;
@@ -169,10 +181,14 @@
         MockitoAnnotations.initMocks(this);
         mContext.setMockPackageManager(mPackageManager);
         mSpyContext = spy(mContext);
-        when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
-        when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
-        mMediaControllers.add(mMediaController);
-        when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllers);
+        final UserHandle userHandle = mock(UserHandle.class);
+        when(mUserTracker.getUserHandle()).thenReturn(userHandle);
+        when(mSessionMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
+        when(mSessionMediaController.getPlaybackState()).thenReturn(mPlaybackState);
+        mMediaControllers.add(mSessionMediaController);
+        when(mMediaSessionManager.getActiveSessionsForUser(any(),
+                Mockito.eq(userHandle))).thenReturn(
+                mMediaControllers);
         doReturn(mMediaSessionManager).when(mSpyContext).getSystemService(
                 MediaSessionManager.class);
         when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(
@@ -182,9 +198,7 @@
                 mMediaSessionManager, mLocalBluetoothManager, mStarter,
                 mNotifCollection, mDialogLaunchAnimator,
                 Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags);
-        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(false);
-        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ROUTES_PROCESSING)).thenReturn(false);
+                mKeyguardManager, mFlags, mUserTracker);
         mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager);
         when(mLocalMediaManager.isPreferenceRouteListingExist()).thenReturn(false);
         mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
@@ -205,6 +219,24 @@
         when(mNearbyDevice2.getRangeZone()).thenReturn(NearbyDevice.RANGE_CLOSE);
         mNearbyDevices.add(mNearbyDevice1);
         mNearbyDevices.add(mNearbyDevice2);
+
+        final List<NotificationEntry> entryList = new ArrayList<>();
+        final NotificationEntry entry = mock(NotificationEntry.class);
+        final StatusBarNotification sbn = mock(StatusBarNotification.class);
+        final Bundle bundle = mock(Bundle.class);
+        final MediaSession.Token token = mock(MediaSession.Token.class);
+        final ISessionController binder = mock(ISessionController.class);
+        entryList.add(entry);
+
+        when(mNotification.isMediaNotification()).thenReturn(false);
+        when(mNotifCollection.getAllNotifs()).thenReturn(entryList);
+        when(entry.getSbn()).thenReturn(sbn);
+        when(sbn.getNotification()).thenReturn(mNotification);
+        when(sbn.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
+        mNotification.extras = bundle;
+        when(bundle.getParcelable(Notification.EXTRA_MEDIA_SESSION,
+                MediaSession.Token.class)).thenReturn(token);
+        when(token.getBinder()).thenReturn(binder);
     }
 
     @Test
@@ -227,10 +259,19 @@
     }
 
     @Test
-    public void start_withPackageName_verifyMediaControllerInit() {
+    public void start_notificationNotFound_mediaControllerInitFromSession() {
         mMediaOutputController.start(mCb);
 
-        verify(mMediaController).registerCallback(any());
+        verify(mSessionMediaController).registerCallback(any());
+    }
+
+    @Test
+    public void start_MediaNotificationFound_mediaControllerNotInitFromSession() {
+        when(mNotification.isMediaNotification()).thenReturn(true);
+        mMediaOutputController.start(mCb);
+
+        verify(mSessionMediaController, never()).registerCallback(any());
+        verifyZeroInteractions(mMediaSessionManager);
     }
 
     @Test
@@ -239,11 +280,11 @@
                 mMediaSessionManager, mLocalBluetoothManager, mStarter,
                 mNotifCollection, mDialogLaunchAnimator,
                 Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags);
+                mKeyguardManager, mFlags, mUserTracker);
 
         mMediaOutputController.start(mCb);
 
-        verify(mMediaController, never()).registerCallback(any());
+        verify(mSessionMediaController, never()).registerCallback(any());
     }
 
     @Test
@@ -256,11 +297,11 @@
     @Test
     public void stop_withPackageName_verifyMediaControllerDeinit() {
         mMediaOutputController.start(mCb);
-        reset(mMediaController);
+        reset(mSessionMediaController);
 
         mMediaOutputController.stop();
 
-        verify(mMediaController).unregisterCallback(any());
+        verify(mSessionMediaController).unregisterCallback(any());
     }
 
     @Test
@@ -269,19 +310,19 @@
                 mMediaSessionManager, mLocalBluetoothManager, mStarter,
                 mNotifCollection, mDialogLaunchAnimator,
                 Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags);
+                mKeyguardManager, mFlags, mUserTracker);
 
         mMediaOutputController.start(mCb);
 
         mMediaOutputController.stop();
 
-        verify(mMediaController, never()).unregisterCallback(any());
+        verify(mSessionMediaController, never()).unregisterCallback(any());
     }
 
     @Test
     public void stop_nearbyMediaDevicesManagerNotNull_unregistersNearbyDevicesCallback() {
         mMediaOutputController.start(mCb);
-        reset(mMediaController);
+        reset(mSessionMediaController);
 
         mMediaOutputController.stop();
 
@@ -358,24 +399,9 @@
     }
 
     @Test
-    public void onDeviceListUpdate_verifyDeviceListCallback() {
-        mMediaOutputController.start(mCb);
-        reset(mCb);
-
-        mMediaOutputController.onDeviceListUpdate(mMediaDevices);
-        final List<MediaDevice> devices = new ArrayList<>(mMediaOutputController.getMediaDevices());
-
-        assertThat(devices.containsAll(mMediaDevices)).isTrue();
-        assertThat(devices.size()).isEqualTo(mMediaDevices.size());
-        verify(mCb).onDeviceListChanged();
-    }
-
-    @Test
     public void routeProcessSupport_onDeviceListUpdate_preferenceExist_NotUpdatesRangeInformation()
             throws RemoteException {
         when(mLocalMediaManager.isPreferenceRouteListingExist()).thenReturn(true);
-        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ROUTES_PROCESSING)).thenReturn(true);
-        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
         mMediaOutputController.start(mCb);
         reset(mCb);
 
@@ -387,8 +413,7 @@
     }
 
     @Test
-    public void advanced_onDeviceListUpdate_verifyDeviceListCallback() {
-        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
+    public void onDeviceListUpdate_verifyDeviceListCallback() {
         mMediaOutputController.start(mCb);
         reset(mCb);
 
@@ -409,7 +434,6 @@
 
     @Test
     public void advanced_onDeviceListUpdateWithConnectedDeviceRemote_verifyItemSize() {
-        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
         when(mMediaDevice1.getFeatures()).thenReturn(
                 ImmutableList.of(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK));
         when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mMediaDevice1);
@@ -433,7 +457,6 @@
 
     @Test
     public void advanced_categorizeMediaItems_withSuggestedDevice_verifyDeviceListSize() {
-        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
         when(mMediaDevice1.isSuggestedDevice()).thenReturn(true);
         when(mMediaDevice2.isSuggestedDevice()).thenReturn(false);
 
@@ -471,7 +494,6 @@
 
     @Test
     public void advanced_onDeviceListUpdate_isRefreshing_updatesNeedRefreshToTrue() {
-        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
         mMediaOutputController.start(mCb);
         reset(mCb);
         mMediaOutputController.mIsRefreshing = true;
@@ -509,7 +531,7 @@
                 mMediaSessionManager, mLocalBluetoothManager, mStarter,
                 mNotifCollection, mDialogLaunchAnimator,
                 Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags);
+                mKeyguardManager, mFlags, mUserTracker);
         testMediaOutputController.start(mCb);
         reset(mCb);
 
@@ -532,7 +554,7 @@
                 mMediaSessionManager, mLocalBluetoothManager, mStarter,
                 mNotifCollection, mDialogLaunchAnimator,
                 Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags);
+                mKeyguardManager, mFlags, mUserTracker);
         testMediaOutputController.start(mCb);
         reset(mCb);
 
@@ -568,7 +590,7 @@
                 mMediaSessionManager, mLocalBluetoothManager, mStarter,
                 mNotifCollection, mDialogLaunchAnimator,
                 Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags);
+                mKeyguardManager, mFlags, mUserTracker);
 
         LocalMediaManager testLocalMediaManager = spy(testMediaOutputController.mLocalMediaManager);
         testMediaOutputController.mLocalMediaManager = testLocalMediaManager;
@@ -585,7 +607,7 @@
                 mMediaSessionManager, mLocalBluetoothManager, mStarter,
                 mNotifCollection, mDialogLaunchAnimator,
                 Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags);
+                mKeyguardManager, mFlags, mUserTracker);
 
         LocalMediaManager testLocalMediaManager = spy(testMediaOutputController.mLocalMediaManager);
         testMediaOutputController.mLocalMediaManager = testLocalMediaManager;
@@ -673,7 +695,6 @@
 
     @Test
     public void isAnyDeviceTransferring_advancedLayoutSupport() {
-        when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
         when(mMediaDevice1.getState()).thenReturn(
                 LocalMediaManager.MediaDeviceState.STATE_CONNECTING);
         mMediaOutputController.start(mCb);
@@ -684,7 +705,7 @@
 
     @Test
     public void isPlaying_stateIsNull() {
-        when(mMediaController.getPlaybackState()).thenReturn(null);
+        when(mSessionMediaController.getPlaybackState()).thenReturn(null);
 
         assertThat(mMediaOutputController.isPlaying()).isFalse();
     }
@@ -726,7 +747,7 @@
 
     @Test
     public void getHeaderTitle_withoutMetadata_returnDefaultString() {
-        when(mMediaController.getMetadata()).thenReturn(null);
+        when(mSessionMediaController.getMetadata()).thenReturn(null);
 
         mMediaOutputController.start(mCb);
 
@@ -736,7 +757,7 @@
 
     @Test
     public void getHeaderTitle_withMetadata_returnSongName() {
-        when(mMediaController.getMetadata()).thenReturn(mMediaMetadata);
+        when(mSessionMediaController.getMetadata()).thenReturn(mMediaMetadata);
 
         mMediaOutputController.start(mCb);
 
@@ -745,7 +766,7 @@
 
     @Test
     public void getHeaderSubTitle_withoutMetadata_returnNull() {
-        when(mMediaController.getMetadata()).thenReturn(null);
+        when(mSessionMediaController.getMetadata()).thenReturn(null);
 
         mMediaOutputController.start(mCb);
 
@@ -754,7 +775,7 @@
 
     @Test
     public void getHeaderSubTitle_withMetadata_returnArtistName() {
-        when(mMediaController.getMetadata()).thenReturn(mMediaMetadata);
+        when(mSessionMediaController.getMetadata()).thenReturn(mMediaMetadata);
 
         mMediaOutputController.start(mCb);
 
@@ -868,7 +889,7 @@
                 mMediaSessionManager, mLocalBluetoothManager, mStarter,
                 mNotifCollection, mDialogLaunchAnimator,
                 Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags);
+                mKeyguardManager, mFlags, mUserTracker);
 
         assertThat(mMediaOutputController.getNotificationIcon()).isNull();
     }
@@ -1060,7 +1081,7 @@
                 mMediaSessionManager, mLocalBluetoothManager, mStarter,
                 mNotifCollection, mDialogLaunchAnimator,
                 Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags);
+                mKeyguardManager, mFlags, mUserTracker);
 
         testMediaOutputController.setTemporaryAllowListExceptionIfNeeded(mMediaDevice2);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
index 425d0bc..f3aee48 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
@@ -34,6 +34,7 @@
 import android.media.session.MediaSessionManager;
 import android.media.session.PlaybackState;
 import android.os.PowerExemptionManager;
+import android.os.UserHandle;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.util.FeatureFlagUtils;
@@ -55,12 +56,14 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -98,6 +101,7 @@
     private PowerExemptionManager mPowerExemptionManager = mock(PowerExemptionManager.class);
     private KeyguardManager mKeyguardManager = mock(KeyguardManager.class);
     private FeatureFlags mFlags = mock(FeatureFlags.class);
+    private UserTracker mUserTracker = mock(UserTracker.class);
 
     private List<MediaController> mMediaControllers = new ArrayList<>();
     private MediaOutputDialog mMediaOutputDialog;
@@ -119,13 +123,17 @@
         when(mMediaController.getMetadata()).thenReturn(mMediaMetadata);
         when(mMediaMetadata.getDescription()).thenReturn(mMediaDescription);
         mMediaControllers.add(mMediaController);
-        when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllers);
+        final UserHandle userHandle = mock(UserHandle.class);
+        when(mUserTracker.getUserHandle()).thenReturn(userHandle);
+        when(mMediaSessionManager.getActiveSessionsForUser(any(),
+                Mockito.eq(userHandle))).thenReturn(
+                mMediaControllers);
 
         mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
                 mMediaSessionManager, mLocalBluetoothManager, mStarter,
                 mNotifCollection, mDialogLaunchAnimator,
                 Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
-                mKeyguardManager, mFlags);
+                mKeyguardManager, mFlags, mUserTracker);
         mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
         mMediaOutputDialog = makeTestDialog(mMediaOutputController);
         mMediaOutputDialog.show();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
index bd042c2..ffbf62a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.media.taptotransfer.MediaTttFlags
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.temporarydisplay.TemporaryViewUiEventLogger
 import com.android.systemui.util.concurrency.DelayableExecutor
 import com.android.systemui.util.time.SystemClock
 import com.android.systemui.util.view.ViewUtil
@@ -48,6 +49,7 @@
     wakeLockBuilder: WakeLock.Builder,
     systemClock: SystemClock,
     rippleController: MediaTttReceiverRippleController,
+    temporaryViewUiEventLogger: TemporaryViewUiEventLogger,
 ) :
     MediaTttChipControllerReceiver(
         commandQueue,
@@ -66,6 +68,7 @@
         wakeLockBuilder,
         systemClock,
         rippleController,
+        temporaryViewUiEventLogger,
     ) {
     override fun animateViewOut(view: ViewGroup, removalReason: String?, onAnimationEnd: Runnable) {
         // Just bypass the animation in tests
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
index 19dd2f0..2b66e7b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
@@ -31,6 +31,7 @@
 import android.view.accessibility.AccessibilityManager
 import android.widget.ImageView
 import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
@@ -38,6 +39,7 @@
 import com.android.systemui.media.taptotransfer.MediaTttFlags
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.temporarydisplay.TemporaryViewUiEventLogger
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
@@ -90,6 +92,7 @@
     private lateinit var fakeAppIconDrawable: Drawable
     private lateinit var uiEventLoggerFake: UiEventLoggerFake
     private lateinit var receiverUiEventLogger: MediaTttReceiverUiEventLogger
+    private lateinit var temporaryViewUiEventLogger: TemporaryViewUiEventLogger
     private lateinit var fakeClock: FakeSystemClock
     private lateinit var fakeExecutor: FakeExecutor
     private lateinit var fakeWakeLockBuilder: WakeLockFake.Builder
@@ -114,6 +117,7 @@
 
         uiEventLoggerFake = UiEventLoggerFake()
         receiverUiEventLogger = MediaTttReceiverUiEventLogger(uiEventLoggerFake)
+        temporaryViewUiEventLogger = TemporaryViewUiEventLogger(uiEventLoggerFake)
 
         fakeWakeLock = WakeLockFake()
         fakeWakeLockBuilder = WakeLockFake.Builder(context)
@@ -136,6 +140,7 @@
             fakeWakeLockBuilder,
             fakeClock,
             rippleController,
+            temporaryViewUiEventLogger,
         )
         controllerReceiver.start()
 
@@ -166,6 +171,7 @@
             fakeWakeLockBuilder,
             fakeClock,
             rippleController,
+            temporaryViewUiEventLogger,
         )
         controllerReceiver.start()
 
@@ -186,6 +192,7 @@
         assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
             MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_CLOSE_TO_SENDER.id
         )
+        assertThat(uiEventLoggerFake.logs[0].instanceId).isNotNull()
     }
 
     @Test
@@ -201,6 +208,7 @@
         assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
             MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_FAR_FROM_SENDER.id
         )
+        assertThat(uiEventLoggerFake.logs[0].instanceId).isNotNull()
     }
 
     @Test
@@ -216,6 +224,7 @@
         assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
                 MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_TRANSFER_TO_RECEIVER_SUCCEEDED.id
         )
+        assertThat(uiEventLoggerFake.logs[0].instanceId).isNotNull()
     }
 
     @Test
@@ -231,6 +240,7 @@
         assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
                 MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_TRANSFER_TO_RECEIVER_FAILED.id
         )
+        assertThat(uiEventLoggerFake.logs[0].instanceId).isNotNull()
     }
 
     @Test
@@ -276,6 +286,25 @@
     }
 
     @Test
+    fun commandQueueCallback_closeThenSucceeded_sameViewInstanceId() {
+        commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
+            StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
+            routeInfo,
+            null,
+            null
+        )
+
+        commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
+            StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
+            routeInfo,
+            null,
+            null
+        )
+
+        assertThat(uiEventLoggerFake[0].instanceId).isEqualTo(uiEventLoggerFake[1].instanceId)
+    }
+
+    @Test
     fun commandQueueCallback_closeThenFailed_chipShownThenHidden() {
         commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
             StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
@@ -349,6 +378,7 @@
                 appIconDrawableOverride = null,
                 appNameOverride = null,
                 id = "id",
+                instanceId = InstanceId.fakeInstanceId(0),
             )
         )
 
@@ -371,6 +401,7 @@
                 drawableOverride,
                 appNameOverride = null,
                 id = "id",
+                instanceId = InstanceId.fakeInstanceId(0),
             )
         )
 
@@ -388,6 +419,7 @@
                 appIconDrawableOverride = null,
                 appNameOverride,
                 id = "id",
+                instanceId = InstanceId.fakeInstanceId(0),
             )
         )
 
@@ -442,7 +474,13 @@
             .addFeature("feature")
             .setClientPackageName(packageName)
             .build()
-        return ChipReceiverInfo(routeInfo, null, null, id = "id")
+        return ChipReceiverInfo(
+            routeInfo,
+            null,
+            null,
+            id = "id",
+            instanceId = InstanceId.fakeInstanceId(0),
+        )
     }
 
     private fun ViewGroup.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt
index ee10ddc..f557713 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt
@@ -1,6 +1,7 @@
 package com.android.systemui.media.taptotransfer.receiver
 
 import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
@@ -21,10 +22,12 @@
     @Test
     fun logReceiverStateChange_eventAssociatedWithStateIsLogged() {
         val state = ChipStateReceiver.CLOSE_TO_SENDER
+        val instanceId = InstanceId.fakeInstanceId(0)
 
-        logger.logReceiverStateChange(state)
+        logger.logReceiverStateChange(state, instanceId)
 
         assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
         assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(state.uiEvent.id)
+        assertThat(uiEventLoggerFake.logs[0].instanceId).isEqualTo(instanceId)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
index ca2b1da..ea25f71 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt
@@ -22,6 +22,7 @@
 import android.graphics.drawable.Drawable
 import android.media.MediaRoute2Info
 import android.os.PowerManager
+import android.os.VibrationAttributes
 import android.os.VibrationEffect
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
@@ -45,6 +46,7 @@
 import com.android.systemui.statusbar.VibratorHelper
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.temporarydisplay.TemporaryViewDisplayController
+import com.android.systemui.temporarydisplay.TemporaryViewUiEventLogger
 import com.android.systemui.temporarydisplay.chipbar.ChipbarAnimator
 import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
 import com.android.systemui.temporarydisplay.chipbar.ChipbarLogger
@@ -107,6 +109,7 @@
     private lateinit var fakeExecutor: FakeExecutor
     private lateinit var uiEventLoggerFake: UiEventLoggerFake
     private lateinit var uiEventLogger: MediaTttSenderUiEventLogger
+    private lateinit var tempViewUiEventLogger: TemporaryViewUiEventLogger
     private val defaultTimeout = context.resources.getInteger(R.integer.heads_up_notification_decay)
 
     @Before
@@ -136,6 +139,7 @@
 
         uiEventLoggerFake = UiEventLoggerFake()
         uiEventLogger = MediaTttSenderUiEventLogger(uiEventLoggerFake)
+        tempViewUiEventLogger = TemporaryViewUiEventLogger(uiEventLoggerFake)
 
         chipbarCoordinator =
             ChipbarCoordinator(
@@ -155,6 +159,7 @@
                 vibratorHelper,
                 fakeWakeLockBuilder,
                 fakeClock,
+                tempViewUiEventLogger,
             )
         chipbarCoordinator.start()
 
@@ -210,7 +215,14 @@
         assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.GONE)
         assertThat(uiEventLoggerFake.eventId(0))
             .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST.id)
-        verify(vibratorHelper).vibrate(any<VibrationEffect>())
+        verify(vibratorHelper)
+            .vibrate(
+                any(),
+                any(),
+                any<VibrationEffect>(),
+                any(),
+                any<VibrationAttributes>(),
+            )
     }
 
     @Test
@@ -246,7 +258,14 @@
         assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.GONE)
         assertThat(uiEventLoggerFake.eventId(0))
             .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST.id)
-        verify(vibratorHelper).vibrate(any<VibrationEffect>())
+        verify(vibratorHelper)
+            .vibrate(
+                any(),
+                any(),
+                any<VibrationEffect>(),
+                any(),
+                any<VibrationAttributes>(),
+            )
     }
 
     @Test
@@ -267,7 +286,14 @@
         assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.GONE)
         assertThat(uiEventLoggerFake.eventId(0))
             .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED.id)
-        verify(vibratorHelper).vibrate(any<VibrationEffect>())
+        verify(vibratorHelper)
+            .vibrate(
+                any(),
+                any(),
+                any<VibrationEffect>(),
+                any(),
+                any<VibrationAttributes>(),
+            )
     }
 
     @Test
@@ -303,7 +329,14 @@
         assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.GONE)
         assertThat(uiEventLoggerFake.eventId(0))
             .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED.id)
-        verify(vibratorHelper).vibrate(any<VibrationEffect>())
+        verify(vibratorHelper)
+            .vibrate(
+                any(),
+                any(),
+                any<VibrationEffect>(),
+                any(),
+                any<VibrationAttributes>(),
+            )
     }
 
     @Test
@@ -323,10 +356,35 @@
             .isEqualTo(ChipStateSender.TRANSFER_TO_RECEIVER_SUCCEEDED.getExpectedStateText())
         assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE)
         assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
-        // Event index 1 since initially displaying the triggered chip would also log an event.
-        assertThat(uiEventLoggerFake.eventId(1))
+        // Event index 2 since initially displaying the triggered chip would also log two events.
+        assertThat(uiEventLoggerFake.eventId(2))
+            .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED.id)
+        verify(vibratorHelper, never())
+            .vibrate(
+                any(),
+                any(),
+                any<VibrationEffect>(),
+                any(),
+                any<VibrationAttributes>(),
+            )
+    }
+
+    @Test
+    fun commandQueueCallback_transferToReceiverSucceeded_sameViewInstanceId() {
+        displayReceiverTriggered()
+        reset(vibratorHelper)
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
+            routeInfo,
+            null
+        )
+
+        // Event index 2 since initially displaying the triggered chip would also log two events.
+        assertThat(uiEventLoggerFake.eventId(2))
             .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED.id)
         verify(vibratorHelper, never()).vibrate(any<VibrationEffect>())
+        assertThat(uiEventLoggerFake.logs[0].instanceId)
+            .isEqualTo(uiEventLoggerFake.logs[2].instanceId)
     }
 
     @Test
@@ -374,9 +432,9 @@
 
         getChipbarView().getUndoButton().performClick()
 
-        // Event index 2 since initially displaying the triggered and succeeded chip would also log
+        // Event index 3 since initially displaying the triggered and succeeded chip would also log
         // events.
-        assertThat(uiEventLoggerFake.eventId(2))
+        assertThat(uiEventLoggerFake.eventId(3))
             .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED.id)
         assertThat(undoCallbackCalled).isTrue()
         assertThat(getChipbarView().getChipText())
@@ -400,10 +458,17 @@
             .isEqualTo(ChipStateSender.TRANSFER_TO_THIS_DEVICE_SUCCEEDED.getExpectedStateText())
         assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE)
         assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
-        // Event index 1 since initially displaying the triggered chip would also log an event.
-        assertThat(uiEventLoggerFake.eventId(1))
+        // Event index 2 since initially displaying the triggered chip would also log two events.
+        assertThat(uiEventLoggerFake.eventId(2))
             .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED.id)
-        verify(vibratorHelper, never()).vibrate(any<VibrationEffect>())
+        verify(vibratorHelper, never())
+            .vibrate(
+                any(),
+                any(),
+                any<VibrationEffect>(),
+                any(),
+                any<VibrationAttributes>(),
+            )
     }
 
     @Test
@@ -451,9 +516,9 @@
 
         getChipbarView().getUndoButton().performClick()
 
-        // Event index 2 since initially displaying the triggered and succeeded chip would also log
+        // Event index 3 since initially displaying the triggered and succeeded chip would also log
         // events.
-        assertThat(uiEventLoggerFake.eventId(2))
+        assertThat(uiEventLoggerFake.eventId(3))
             .isEqualTo(
                 MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED.id
             )
@@ -480,10 +545,17 @@
         assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE)
         assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
         assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.VISIBLE)
-        // Event index 1 since initially displaying the triggered chip would also log an event.
-        assertThat(uiEventLoggerFake.eventId(1))
+        // Event index 2 since initially displaying the triggered chip would also log two events.
+        assertThat(uiEventLoggerFake.eventId(2))
             .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED.id)
-        verify(vibratorHelper).vibrate(any<VibrationEffect>())
+        verify(vibratorHelper)
+            .vibrate(
+                any(),
+                any(),
+                any<VibrationEffect>(),
+                any(),
+                any<VibrationAttributes>(),
+            )
     }
 
     @Test
@@ -509,9 +581,16 @@
         assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE)
         assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.VISIBLE)
         // Event index 1 since initially displaying the triggered chip would also log an event.
-        assertThat(uiEventLoggerFake.eventId(1))
+        assertThat(uiEventLoggerFake.eventId(2))
             .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED.id)
-        verify(vibratorHelper).vibrate(any<VibrationEffect>())
+        verify(vibratorHelper)
+            .vibrate(
+                any(),
+                any(),
+                any<VibrationEffect>(),
+                any(),
+                any<VibrationAttributes>(),
+            )
     }
 
     @Test
@@ -1025,6 +1104,7 @@
     @Test
     fun newState_viewListenerRegistered() {
         val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+        whenever(mockChipbarCoordinator.tempViewUiEventLogger).thenReturn(tempViewUiEventLogger)
         underTest =
             MediaTttSenderCoordinator(
                 mockChipbarCoordinator,
@@ -1052,6 +1132,7 @@
     @Test
     fun onInfoPermanentlyRemoved_viewListenerUnregistered() {
         val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+        whenever(mockChipbarCoordinator.tempViewUiEventLogger).thenReturn(tempViewUiEventLogger)
         underTest =
             MediaTttSenderCoordinator(
                 mockChipbarCoordinator,
@@ -1085,6 +1166,7 @@
     @Test
     fun onInfoPermanentlyRemoved_wrongId_viewListenerNotUnregistered() {
         val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+        whenever(mockChipbarCoordinator.tempViewUiEventLogger).thenReturn(tempViewUiEventLogger)
         underTest =
             MediaTttSenderCoordinator(
                 mockChipbarCoordinator,
@@ -1117,6 +1199,7 @@
     @Test
     fun farFromReceiverState_viewListenerUnregistered() {
         val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+        whenever(mockChipbarCoordinator.tempViewUiEventLogger).thenReturn(tempViewUiEventLogger)
         underTest =
             MediaTttSenderCoordinator(
                 mockChipbarCoordinator,
@@ -1153,6 +1236,7 @@
     @Test
     fun statesWithDifferentIds_onInfoPermanentlyRemovedForOneId_viewListenerNotUnregistered() {
         val mockChipbarCoordinator = mock<ChipbarCoordinator>()
+        whenever(mockChipbarCoordinator.tempViewUiEventLogger).thenReturn(tempViewUiEventLogger)
         underTest =
             MediaTttSenderCoordinator(
                 mockChipbarCoordinator,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLoggerTest.kt
index 2287da5..ee3704c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLoggerTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.media.taptotransfer.sender
 
 import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.log.LogBuffer
@@ -91,8 +92,16 @@
     fun logStateMap_bufferHasInfo() {
         val map =
             mapOf(
-                "123" to ChipStateSender.ALMOST_CLOSE_TO_START_CAST,
-                "456" to ChipStateSender.TRANSFER_TO_THIS_DEVICE_TRIGGERED,
+                "123" to
+                    Pair(
+                        InstanceId.fakeInstanceId(100),
+                        ChipStateSender.ALMOST_CLOSE_TO_START_CAST
+                    ),
+                "456" to
+                    Pair(
+                        InstanceId.fakeInstanceId(200),
+                        ChipStateSender.TRANSFER_TO_THIS_DEVICE_TRIGGERED
+                    ),
             )
 
         logger.logStateMap(map)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
index 263637a..bf26a2f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
@@ -1,6 +1,7 @@
 package com.android.systemui.media.taptotransfer.sender
 
 import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
@@ -21,26 +22,32 @@
     @Test
     fun logSenderStateChange_eventAssociatedWithStateIsLogged() {
         val state = ChipStateSender.ALMOST_CLOSE_TO_END_CAST
-        logger.logSenderStateChange(state)
+        logger.logSenderStateChange(state, instanceId)
 
         assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
         assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(state.uiEvent.id)
+        assertThat(uiEventLoggerFake.get(0).instanceId).isEqualTo(instanceId)
     }
 
     @Test
     fun logUndoClicked_undoEventLogged() {
         val undoEvent = MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED
 
-        logger.logUndoClicked(undoEvent)
+        logger.logUndoClicked(undoEvent, instanceId)
 
         assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
         assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(undoEvent.id)
+        assertThat(uiEventLoggerFake.get(0).instanceId).isEqualTo(instanceId)
     }
 
     @Test
     fun logUndoClicked_notUndoEvent_eventNotLogged() {
-        logger.logUndoClicked(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED)
+        val state = MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED
+
+        logger.logUndoClicked(state, instanceId)
 
         assertThat(uiEventLoggerFake.numLogs()).isEqualTo(0)
     }
 }
+
+private val instanceId = InstanceId.fakeInstanceId(0)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
index bd7898a..e99f8b6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -25,8 +25,11 @@
 import android.content.ComponentName
 import android.content.Context
 import android.content.Intent
+import android.content.Intent.ACTION_CREATE_NOTE
 import android.content.Intent.ACTION_MAIN
+import android.content.Intent.ACTION_MANAGE_DEFAULT_APP
 import android.content.Intent.CATEGORY_HOME
+import android.content.Intent.EXTRA_USE_STYLUS_MODE
 import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK
 import android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT
 import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
@@ -47,8 +50,10 @@
 import com.android.systemui.notetask.NoteTaskController.Companion.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE
 import com.android.systemui.notetask.NoteTaskController.Companion.SHORTCUT_ID
 import com.android.systemui.notetask.NoteTaskEntryPoint.APP_CLIPS
+import com.android.systemui.notetask.NoteTaskEntryPoint.KEYBOARD_SHORTCUT
 import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE
 import com.android.systemui.notetask.NoteTaskEntryPoint.TAIL_BUTTON
+import com.android.systemui.notetask.NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT
 import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
 import com.android.systemui.notetask.shortcut.LaunchNoteTaskActivity
 import com.android.systemui.notetask.shortcut.LaunchNoteTaskManagedProfileProxyActivity
@@ -103,6 +108,8 @@
         whenever(context.packageManager).thenReturn(packageManager)
         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(NOTE_TASK_INFO)
         whenever(userManager.isUserUnlocked).thenReturn(true)
+        whenever(userManager.isUserUnlocked(any<Int>())).thenReturn(true)
+        whenever(userManager.isUserUnlocked(any<UserHandle>())).thenReturn(true)
         whenever(
                 devicePolicyManager.getKeyguardDisabledFeatures(
                     /* admin= */ eq(null),
@@ -221,31 +228,22 @@
     // region showNoteTask
     @Test
     fun showNoteTask_keyguardIsLocked_shouldStartActivityAndLogUiEvent() {
-        val expectedInfo =
-            NOTE_TASK_INFO.copy(
-                entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
-                isKeyguardLocked = true,
-            )
+        val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true)
         whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
 
-        createNoteTaskController()
-            .showNoteTask(
-                entryPoint = expectedInfo.entryPoint!!,
-            )
+        createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
 
         val intentCaptor = argumentCaptor<Intent>()
         val userCaptor = argumentCaptor<UserHandle>()
         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
-        intentCaptor.value.let { intent ->
-            assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
-            assertThat(intent.`package`).isEqualTo(NOTE_TASK_PACKAGE_NAME)
-            assertThat(intent.flags and FLAG_ACTIVITY_NEW_TASK).isEqualTo(FLAG_ACTIVITY_NEW_TASK)
-            assertThat(intent.flags and FLAG_ACTIVITY_MULTIPLE_TASK)
-                .isEqualTo(FLAG_ACTIVITY_MULTIPLE_TASK)
-            assertThat(intent.flags and FLAG_ACTIVITY_NEW_DOCUMENT)
-                .isEqualTo(FLAG_ACTIVITY_NEW_DOCUMENT)
-            assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue()
+        assertThat(intentCaptor.value).run {
+            hasAction(ACTION_CREATE_NOTE)
+            hasPackage(NOTE_TASK_PACKAGE_NAME)
+            hasFlags(FLAG_ACTIVITY_NEW_TASK)
+            hasFlags(FLAG_ACTIVITY_MULTIPLE_TASK)
+            hasFlags(FLAG_ACTIVITY_NEW_DOCUMENT)
+            extras().bool(EXTRA_USE_STYLUS_MODE).isTrue()
         }
         assertThat(userCaptor.value).isEqualTo(userTracker.userHandle)
         verify(eventLogger).logNoteTaskOpened(expectedInfo)
@@ -256,32 +254,23 @@
     fun showNoteTaskWithUser_keyguardIsLocked_shouldStartActivityWithExpectedUserAndLogUiEvent() {
         val user10 = UserHandle.of(/* userId= */ 10)
         val expectedInfo =
-            NOTE_TASK_INFO.copy(
-                entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
-                isKeyguardLocked = true,
-                user = user10,
-            )
+            NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true, user = user10)
         whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
 
         createNoteTaskController()
-            .showNoteTaskAsUser(
-                entryPoint = expectedInfo.entryPoint!!,
-                user = user10,
-            )
+            .showNoteTaskAsUser(entryPoint = expectedInfo.entryPoint!!, user = user10)
 
         val intentCaptor = argumentCaptor<Intent>()
         val userCaptor = argumentCaptor<UserHandle>()
         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
-        intentCaptor.value.let { intent ->
-            assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
-            assertThat(intent.`package`).isEqualTo(NOTE_TASK_PACKAGE_NAME)
-            assertThat(intent.flags and FLAG_ACTIVITY_NEW_TASK).isEqualTo(FLAG_ACTIVITY_NEW_TASK)
-            assertThat(intent.flags and FLAG_ACTIVITY_MULTIPLE_TASK)
-                .isEqualTo(FLAG_ACTIVITY_MULTIPLE_TASK)
-            assertThat(intent.flags and FLAG_ACTIVITY_NEW_DOCUMENT)
-                .isEqualTo(FLAG_ACTIVITY_NEW_DOCUMENT)
-            assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue()
+        assertThat(intentCaptor.value).run {
+            hasAction(ACTION_CREATE_NOTE)
+            hasPackage(NOTE_TASK_PACKAGE_NAME)
+            hasFlags(FLAG_ACTIVITY_NEW_TASK)
+            hasFlags(FLAG_ACTIVITY_MULTIPLE_TASK)
+            hasFlags(FLAG_ACTIVITY_NEW_DOCUMENT)
+            extras().bool(EXTRA_USE_STYLUS_MODE).isTrue()
         }
         assertThat(userCaptor.value).isEqualTo(user10)
         verify(eventLogger).logNoteTaskOpened(expectedInfo)
@@ -290,11 +279,7 @@
 
     @Test
     fun showNoteTask_keyguardIsLocked_noteIsOpen_shouldCloseActivityAndLogUiEvent() {
-        val expectedInfo =
-            NOTE_TASK_INFO.copy(
-                entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
-                isKeyguardLocked = true,
-            )
+        val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true)
         whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
         whenever(activityManager.getRunningTasks(anyInt()))
@@ -305,10 +290,10 @@
         val intentCaptor = argumentCaptor<Intent>()
         val userCaptor = argumentCaptor<UserHandle>()
         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
-        intentCaptor.value.let { intent ->
-            assertThat(intent.action).isEqualTo(ACTION_MAIN)
-            assertThat(intent.categories).contains(CATEGORY_HOME)
-            assertThat(intent.flags and FLAG_ACTIVITY_NEW_TASK).isEqualTo(FLAG_ACTIVITY_NEW_TASK)
+        assertThat(intentCaptor.value).run {
+            hasAction(ACTION_MAIN)
+            categories().contains(CATEGORY_HOME)
+            hasFlags(FLAG_ACTIVITY_NEW_TASK)
         }
         assertThat(userCaptor.value).isEqualTo(userTracker.userHandle)
         verify(eventLogger).logNoteTaskClosed(expectedInfo)
@@ -317,18 +302,11 @@
 
     @Test
     fun showNoteTask_keyguardIsUnlocked_shouldStartBubblesWithoutLoggingUiEvent() {
-        val expectedInfo =
-            NOTE_TASK_INFO.copy(
-                entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
-                isKeyguardLocked = false,
-            )
+        val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = false)
         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
         whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
 
-        createNoteTaskController()
-            .showNoteTask(
-                entryPoint = expectedInfo.entryPoint!!,
-            )
+        createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
 
         // Context package name used to create bubble icon from drawable resource id
         verify(context).packageName
@@ -338,10 +316,7 @@
 
     @Test
     fun showNoteTask_bubblesIsNull_shouldDoNothing() {
-        createNoteTaskController(bubbles = null)
-            .showNoteTask(
-                entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
-            )
+        createNoteTaskController(bubbles = null).showNoteTask(entryPoint = TAIL_BUTTON)
 
         verifyZeroInteractions(context, bubbles, eventLogger)
     }
@@ -352,7 +327,7 @@
         val noteTaskController = spy(createNoteTaskController())
         doNothing().whenever(noteTaskController).showNoDefaultNotesAppToast()
 
-        noteTaskController.showNoteTask(entryPoint = NoteTaskEntryPoint.TAIL_BUTTON)
+        noteTaskController.showNoteTask(entryPoint = TAIL_BUTTON)
 
         verify(noteTaskController).showNoDefaultNotesAppToast()
         verifyZeroInteractions(context, bubbles, eventLogger)
@@ -360,10 +335,7 @@
 
     @Test
     fun showNoteTask_flagDisabled_shouldDoNothing() {
-        createNoteTaskController(isEnabled = false)
-            .showNoteTask(
-                entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
-            )
+        createNoteTaskController(isEnabled = false).showNoteTask(entryPoint = TAIL_BUTTON)
 
         verifyZeroInteractions(context, bubbles, eventLogger)
     }
@@ -372,10 +344,7 @@
     fun showNoteTask_userIsLocked_shouldDoNothing() {
         whenever(userManager.isUserUnlocked).thenReturn(false)
 
-        createNoteTaskController()
-            .showNoteTask(
-                entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
-            )
+        createNoteTaskController().showNoteTask(entryPoint = TAIL_BUTTON)
 
         verifyZeroInteractions(context, bubbles, eventLogger)
     }
@@ -383,30 +352,22 @@
     @Test
     fun showNoteTask_keyboardShortcut_shouldStartActivity() {
         val expectedInfo =
-            NOTE_TASK_INFO.copy(
-                entryPoint = NoteTaskEntryPoint.KEYBOARD_SHORTCUT,
-                isKeyguardLocked = true,
-            )
+            NOTE_TASK_INFO.copy(entryPoint = KEYBOARD_SHORTCUT, isKeyguardLocked = true)
         whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
 
-        createNoteTaskController()
-            .showNoteTask(
-                entryPoint = expectedInfo.entryPoint!!,
-            )
+        createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
 
         val intentCaptor = argumentCaptor<Intent>()
         val userCaptor = argumentCaptor<UserHandle>()
         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
-        intentCaptor.value.let { intent ->
-            assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
-            assertThat(intent.`package`).isEqualTo(NOTE_TASK_PACKAGE_NAME)
-            assertThat(intent.flags and FLAG_ACTIVITY_NEW_TASK).isEqualTo(FLAG_ACTIVITY_NEW_TASK)
-            assertThat(intent.flags and FLAG_ACTIVITY_MULTIPLE_TASK)
-                .isEqualTo(FLAG_ACTIVITY_MULTIPLE_TASK)
-            assertThat(intent.flags and FLAG_ACTIVITY_NEW_DOCUMENT)
-                .isEqualTo(FLAG_ACTIVITY_NEW_DOCUMENT)
-            assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, true)).isFalse()
+        assertThat(intentCaptor.value).run {
+            hasAction(ACTION_CREATE_NOTE)
+            hasPackage(NOTE_TASK_PACKAGE_NAME)
+            hasFlags(FLAG_ACTIVITY_NEW_TASK)
+            hasFlags(FLAG_ACTIVITY_MULTIPLE_TASK)
+            hasFlags(FLAG_ACTIVITY_NEW_DOCUMENT)
+            extras().bool(EXTRA_USE_STYLUS_MODE).isFalse()
         }
         assertThat(userCaptor.value).isEqualTo(userTracker.userHandle)
         verify(eventLogger).logNoteTaskOpened(expectedInfo)
@@ -583,7 +544,7 @@
         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
 
-        createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.TAIL_BUTTON)
+        createNoteTaskController().showNoteTask(entryPoint = TAIL_BUTTON)
 
         verifyNoteTaskOpenInBubbleInUser(workUserInfo.userHandle)
     }
@@ -593,8 +554,7 @@
         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
 
-        createNoteTaskController()
-            .showNoteTask(entryPoint = NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT)
+        createNoteTaskController().showNoteTask(entryPoint = WIDGET_PICKER_SHORTCUT)
 
         verifyNoteTaskOpenInBubbleInUser(mainUserInfo.userHandle)
     }
@@ -604,7 +564,7 @@
         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
 
-        createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.APP_CLIPS)
+        createNoteTaskController().showNoteTask(entryPoint = APP_CLIPS)
 
         verifyNoteTaskOpenInBubbleInUser(mainUserInfo.userHandle)
     }
@@ -615,13 +575,13 @@
         val iconCaptor = argumentCaptor<Icon>()
         verify(bubbles)
             .showOrHideAppBubble(capture(intentCaptor), eq(userHandle), capture(iconCaptor))
-        intentCaptor.value.let { intent ->
-            assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
-            assertThat(intent.`package`).isEqualTo(NOTE_TASK_PACKAGE_NAME)
-            assertThat(intent.flags).isEqualTo(FLAG_ACTIVITY_NEW_TASK)
-            assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue()
+        assertThat(intentCaptor.value).run {
+            hasAction(ACTION_CREATE_NOTE)
+            hasPackage(NOTE_TASK_PACKAGE_NAME)
+            hasFlags(FLAG_ACTIVITY_NEW_TASK)
+            extras().bool(EXTRA_USE_STYLUS_MODE).isTrue()
         }
-        iconCaptor.value.let { icon ->
+        iconCaptor.value?.let { icon ->
             assertThat(icon).isNotNull()
             assertThat(icon.resId).isEqualTo(R.drawable.ic_note_task_shortcut_widget)
         }
@@ -679,9 +639,10 @@
         verify(shortcutManager).updateShortcuts(actualShortcuts.capture())
         val actualShortcut = actualShortcuts.value.first()
         assertThat(actualShortcut.id).isEqualTo(SHORTCUT_ID)
-        assertThat(actualShortcut.intent?.component?.className)
-            .isEqualTo(LaunchNoteTaskActivity::class.java.name)
-        assertThat(actualShortcut.intent?.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
+        assertThat(actualShortcut.intent).run {
+            hasComponentClass(LaunchNoteTaskActivity::class.java)
+            hasAction(ACTION_CREATE_NOTE)
+        }
         assertThat(actualShortcut.shortLabel).isEqualTo(NOTE_TASK_SHORT_LABEL)
         assertThat(actualShortcut.isLongLived).isEqualTo(true)
         assertThat(actualShortcut.icon.resId).isEqualTo(R.drawable.ic_note_task_shortcut_widget)
@@ -737,12 +698,9 @@
 
         val intentCaptor = argumentCaptor<Intent>()
         verify(context).startActivityAsUser(intentCaptor.capture(), eq(user0))
-        intentCaptor.value.let { intent ->
-            assertThat(intent)
-                .hasComponent(
-                    ComponentName(context, LaunchNoteTaskManagedProfileProxyActivity::class.java)
-                )
-            assertThat(intent).hasFlags(FLAG_ACTIVITY_NEW_TASK)
+        assertThat(intentCaptor.value).run {
+            hasComponentClass(LaunchNoteTaskManagedProfileProxyActivity::class.java)
+            hasFlags(FLAG_ACTIVITY_NEW_TASK)
         }
     }
     // endregion
@@ -817,9 +775,7 @@
         val intentCaptor = argumentCaptor<Intent>()
         val userCaptor = argumentCaptor<UserHandle>()
         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
-        intentCaptor.value.let { intent ->
-            assertThat(intent).hasAction(Intent.ACTION_MANAGE_DEFAULT_APP)
-        }
+        assertThat(intentCaptor.value).hasAction(ACTION_MANAGE_DEFAULT_APP)
         assertThat(userCaptor.value).isEqualTo(UserHandle.of(workUserInfo.id))
     }
 
@@ -833,9 +789,7 @@
         val intentCaptor = argumentCaptor<Intent>()
         val userCaptor = argumentCaptor<UserHandle>()
         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
-        intentCaptor.value.let { intent ->
-            assertThat(intent).hasAction(Intent.ACTION_MANAGE_DEFAULT_APP)
-        }
+        assertThat(intentCaptor.value).hasAction(ACTION_MANAGE_DEFAULT_APP)
         assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id))
     }
 
@@ -848,9 +802,7 @@
         val intentCaptor = argumentCaptor<Intent>()
         val userCaptor = argumentCaptor<UserHandle>()
         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
-        intentCaptor.value.let { intent ->
-            assertThat(intent).hasAction(Intent.ACTION_MANAGE_DEFAULT_APP)
-        }
+        assertThat(intentCaptor.value).hasAction(ACTION_MANAGE_DEFAULT_APP)
         assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id))
     }
 
@@ -863,9 +815,7 @@
         val intentCaptor = argumentCaptor<Intent>()
         val userCaptor = argumentCaptor<UserHandle>()
         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
-        intentCaptor.value.let { intent ->
-            assertThat(intent).hasAction(Intent.ACTION_MANAGE_DEFAULT_APP)
-        }
+        assertThat(intentCaptor.value).hasAction(ACTION_MANAGE_DEFAULT_APP)
         assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id))
     }
     // endregion
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt
index 28ed9d2..4e85b6c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt
@@ -16,124 +16,169 @@
 package com.android.systemui.notetask
 
 import android.app.role.RoleManager
-import android.test.suitebuilder.annotation.SmallTest
+import android.app.role.RoleManager.ROLE_NOTES
+import android.os.UserHandle
+import android.os.UserManager
+import android.testing.AndroidTestingRunner
 import android.view.KeyEvent
-import androidx.test.runner.AndroidJUnit4
+import android.view.KeyEvent.ACTION_DOWN
+import android.view.KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.settings.FakeUserTracker
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.android.wm.shell.bubbles.Bubbles
 import java.util.Optional
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
 import org.mockito.Mock
 import org.mockito.Mockito.never
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.MockitoAnnotations
+import org.mockito.MockitoAnnotations.initMocks
 
 /** atest SystemUITests:NoteTaskInitializerTest */
+@OptIn(ExperimentalCoroutinesApi::class, InternalNoteTaskApi::class)
 @SmallTest
-@RunWith(AndroidJUnit4::class)
+@RunWith(AndroidTestingRunner::class)
 internal class NoteTaskInitializerTest : SysuiTestCase() {
 
     @Mock lateinit var commandQueue: CommandQueue
     @Mock lateinit var bubbles: Bubbles
     @Mock lateinit var controller: NoteTaskController
     @Mock lateinit var roleManager: RoleManager
-    private val clock = FakeSystemClock()
-    private val executor = FakeExecutor(clock)
+    @Mock lateinit var userManager: UserManager
+    @Mock lateinit var keyguardMonitor: KeyguardUpdateMonitor
+
+    private val executor = FakeExecutor(FakeSystemClock())
     private val userTracker = FakeUserTracker()
 
     @Before
     fun setUp() {
-        MockitoAnnotations.initMocks(this)
+        initMocks(this)
+        whenever(keyguardMonitor.isUserUnlocked(userTracker.userId)).thenReturn(true)
     }
 
-    private fun createNoteTaskInitializer(
-        isEnabled: Boolean = true,
-        bubbles: Bubbles? = this.bubbles,
-    ): NoteTaskInitializer {
-        return NoteTaskInitializer(
+    private fun createUnderTest(
+        isEnabled: Boolean,
+        bubbles: Bubbles?,
+    ): NoteTaskInitializer =
+        NoteTaskInitializer(
             controller = controller,
             commandQueue = commandQueue,
             optionalBubbles = Optional.ofNullable(bubbles),
             isEnabled = isEnabled,
             roleManager = roleManager,
-            backgroundExecutor = executor,
             userTracker = userTracker,
+            keyguardUpdateMonitor = keyguardMonitor,
+            backgroundExecutor = executor,
         )
-    }
 
-    // region initializer
     @Test
-    fun initialize() {
-        createNoteTaskInitializer().initialize()
+    fun initialize_withUserUnlocked() {
+        whenever(keyguardMonitor.isUserUnlocked(userTracker.userId)).thenReturn(true)
 
-        verify(controller).setNoteTaskShortcutEnabled(eq(true), eq(userTracker.userHandle))
+        createUnderTest(isEnabled = true, bubbles = bubbles).initialize()
+
         verify(commandQueue).addCallback(any())
         verify(roleManager).addOnRoleHoldersChangedListenerAsUser(any(), any(), any())
+        verify(controller).setNoteTaskShortcutEnabled(any(), any())
+        verify(keyguardMonitor, never()).registerCallback(any())
+    }
+
+    @Test
+    fun initialize_withUserLocked() {
+        whenever(keyguardMonitor.isUserUnlocked(userTracker.userId)).thenReturn(false)
+
+        createUnderTest(isEnabled = true, bubbles = bubbles).initialize()
+
+        verify(commandQueue).addCallback(any())
+        verify(roleManager).addOnRoleHoldersChangedListenerAsUser(any(), any(), any())
+        verify(controller, never()).setNoteTaskShortcutEnabled(any(), any())
+        verify(keyguardMonitor).registerCallback(any())
     }
 
     @Test
     fun initialize_flagDisabled() {
-        createNoteTaskInitializer(isEnabled = false).initialize()
+        val underTest = createUnderTest(isEnabled = false, bubbles = bubbles)
 
-        verify(controller, never()).setNoteTaskShortcutEnabled(any(), any())
-        verify(commandQueue, never()).addCallback(any())
-        verify(roleManager, never()).addOnRoleHoldersChangedListenerAsUser(any(), any(), any())
+        underTest.initialize()
+
+        verifyZeroInteractions(
+            commandQueue,
+            bubbles,
+            controller,
+            roleManager,
+            userManager,
+            keyguardMonitor,
+        )
     }
 
     @Test
     fun initialize_bubblesNotPresent() {
-        createNoteTaskInitializer(bubbles = null).initialize()
+        val underTest = createUnderTest(isEnabled = true, bubbles = null)
 
-        verify(controller, never()).setNoteTaskShortcutEnabled(any(), any())
-        verify(commandQueue, never()).addCallback(any())
-        verify(roleManager, never()).addOnRoleHoldersChangedListenerAsUser(any(), any(), any())
-    }
-    // endregion
+        underTest.initialize()
 
-    // region handleSystemKey
-    @Test
-    fun handleSystemKey_receiveValidSystemKey_shouldShowNoteTask() {
-        createNoteTaskInitializer()
-            .callbacks
-            .handleSystemKey(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL))
-
-        verify(controller).showNoteTask(entryPoint = NoteTaskEntryPoint.TAIL_BUTTON)
+        verifyZeroInteractions(
+            commandQueue,
+            bubbles,
+            controller,
+            roleManager,
+            userManager,
+            keyguardMonitor,
+        )
     }
 
     @Test
-    fun handleSystemKey_receiveKeyboardShortcut_shouldShowNoteTask() {
-        createNoteTaskInitializer()
-            .callbacks
-            .handleSystemKey(
-                KeyEvent(
-                    0,
-                    0,
-                    KeyEvent.ACTION_DOWN,
-                    KeyEvent.KEYCODE_N,
-                    0,
-                    KeyEvent.META_META_ON or KeyEvent.META_CTRL_ON
-                )
-            )
+    fun initialize_handleSystemKey() {
+        val expectedKeyEvent = KeyEvent(ACTION_DOWN, KEYCODE_STYLUS_BUTTON_TAIL)
+        val underTest = createUnderTest(isEnabled = true, bubbles = bubbles)
+        underTest.initialize()
+        val callback = captureArgument { verify(commandQueue).addCallback(capture()) }
 
-        verify(controller).showNoteTask(entryPoint = NoteTaskEntryPoint.KEYBOARD_SHORTCUT)
+        callback.handleSystemKey(expectedKeyEvent)
+
+        verify(controller).showNoteTask(any())
     }
 
     @Test
-    fun handleSystemKey_receiveInvalidSystemKey_shouldDoNothing() {
-        createNoteTaskInitializer()
-            .callbacks
-            .handleSystemKey(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_UNKNOWN))
+    fun initialize_userUnlocked() {
+        whenever(keyguardMonitor.isUserUnlocked(userTracker.userId)).thenReturn(false)
+        val underTest = createUnderTest(isEnabled = true, bubbles = bubbles)
+        underTest.initialize()
+        val callback = captureArgument { verify(keyguardMonitor).registerCallback(capture()) }
+        whenever(keyguardMonitor.isUserUnlocked(userTracker.userId)).thenReturn(true)
 
-        verifyZeroInteractions(controller)
+        callback.onUserUnlocked()
+        verify(controller).setNoteTaskShortcutEnabled(any(), any())
     }
-    // endregion
+
+    @Test
+    fun initialize_onRoleHoldersChanged() {
+        val underTest = createUnderTest(isEnabled = true, bubbles = bubbles)
+        underTest.initialize()
+        val callback = captureArgument {
+            verify(roleManager)
+                .addOnRoleHoldersChangedListenerAsUser(any(), capture(), eq(UserHandle.ALL))
+        }
+
+        callback.onRoleHoldersChanged(ROLE_NOTES, userTracker.userHandle)
+
+        verify(controller).onRoleHoldersChanged(ROLE_NOTES, userTracker.userHandle)
+    }
 }
+
+private inline fun <reified T : Any> captureArgument(block: ArgumentCaptor<T>.() -> Unit) =
+    argumentCaptor<T>().apply(block).value
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
index 3d55c51..6720dae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
@@ -321,4 +321,30 @@
         assertThat(mController.shouldUseHorizontalLayout()).isFalse();
         verify(mHorizontalLayoutListener).run();
     }
+
+    @Test
+    public void changeTiles_callbackRemovedOnOldOnes() {
+        // Start with one tile
+        assertThat(mController.mRecords.size()).isEqualTo(1);
+        QSPanelControllerBase.TileRecord record = mController.mRecords.get(0);
+
+        assertThat(record.tile).isEqualTo(mQSTile);
+
+        // Change to a different tile
+        when(mQSHost.getTiles()).thenReturn(List.of(mOtherTile));
+        mController.setTiles();
+
+        verify(mQSTile).removeCallback(record.callback);
+        verify(mOtherTile, never()).removeCallback(any());
+        verify(mOtherTile, never()).removeCallbacks();
+    }
+
+    @Test
+    public void onViewDetached_removesJustTheAssociatedCallback() {
+        QSPanelControllerBase.TileRecord record = mController.mRecords.get(0);
+
+        mController.onViewDetached();
+        verify(mQSTile).removeCallback(record.callback);
+        verify(mQSTile, never()).removeCallbacks();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
index 93cebe2..a60dad4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
@@ -27,6 +27,8 @@
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.qs.QSTileView
+import com.android.systemui.qs.QSPanelControllerBase.TileRecord
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSIconViewImpl
 import com.android.systemui.qs.tileimpl.QSTileViewImpl
@@ -192,6 +194,18 @@
         verify(accessibilityInfo, never()).addAction(actionCollapse)
     }
 
+    @Test
+    fun addTile_callbackAdded() {
+        val tile = mock(QSTile::class.java)
+        val tileView = mock(QSTileView::class.java)
+
+        val record = TileRecord(tile, tileView)
+
+        qsPanel.addTile(record)
+
+        verify(tile).addCallback(record.callback)
+    }
+
     private infix fun View.isLeftOf(other: View): Boolean {
         val rect = Rect()
         getBoundsOnScreen(rect)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
index 35c8cc7..8789253 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
@@ -28,8 +28,11 @@
 import static org.mockito.Mockito.verify;
 
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.TestableLooper;
+import android.view.View;
 import android.view.accessibility.AccessibilityNodeInfo;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -48,6 +51,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class TileLayoutTest extends SysuiTestCase {
     private Resources mResources;
     private int mLayoutSizeForOneTile;
@@ -228,4 +232,53 @@
 
         assertEquals(false, mTileLayout.updateResources());
     }
+
+    @Test
+    public void fontScalingChanged_updateResources_cellHeightEnoughForTileContent() {
+        final float originalFontScale = mContext.getResources().getConfiguration().fontScale;
+        float[] testScales = {0.8f, 1.0f, 1.4f, 1.6f, 2.0f};
+        for (float scale: testScales) {
+            changeFontScaling_updateResources_cellHeightEnoughForTileContent(scale);
+        }
+
+        changeFontScaling(originalFontScale);
+    }
+
+    private void changeFontScaling_updateResources_cellHeightEnoughForTileContent(float scale) {
+        changeFontScaling(scale);
+
+        QSPanelControllerBase.TileRecord tileRecord = createTileRecord();
+        mTileLayout.addTile(tileRecord);
+
+        FakeTileView tileView = new FakeTileView(mContext);
+        QSTile.State state = new QSTile.State();
+        state.label = "TEST LABEL";
+        state.secondaryLabel = "TEST SECONDARY LABEL";
+        tileView.changeState(state);
+
+        mTileLayout.updateResources();
+
+        int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
+        tileView.measure(spec, spec);
+        assertTrue(mTileLayout.getCellHeight() >= tileView.getMeasuredHeight());
+
+        mTileLayout.removeTile(tileRecord);
+    }
+
+    private static class FakeTileView extends QSTileViewImpl {
+        FakeTileView(Context context) {
+            super(context, new QSIconViewImpl(context), /* collapsed= */ false);
+        }
+
+        void changeState(QSTile.State state) {
+            handleStateChanged(state);
+        }
+    }
+
+    private void changeFontScaling(float scale) {
+        Configuration configuration = new Configuration(mContext.getResources().getConfiguration());
+        configuration.fontScale = scale;
+        // updateConfiguration could help update on both resource configuration and displayMetrics
+        mContext.getResources().updateConfiguration(configuration, null, null);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
index 7ecb4dc..426ff67 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
@@ -589,6 +589,26 @@
                 .isTrue()
         }
 
+    @Test
+    fun retainedTiles_callbackNotRemoved() =
+        testScope.runTest(USER_INFO_0) {
+            val tiles by collectLastValue(underTest.currentTiles)
+            tileSpecRepository.setTiles(USER_INFO_0.id, listOf(TileSpec.create("a")))
+
+            val tileA = tiles!![0].tile
+            val callback = mock<QSTile.Callback>()
+            tileA.addCallback(callback)
+
+            tileSpecRepository.setTiles(
+                USER_INFO_0.id,
+                listOf(TileSpec.create("a"), CUSTOM_TILE_SPEC)
+            )
+            val newTileA = tiles!![0].tile
+            assertThat(tileA).isSameInstanceAs(newTileA)
+
+            assertThat((tileA as FakeQSTile).callbacks).containsExactly(callback)
+        }
+
     private fun QSTile.State.fillIn(state: Int, label: CharSequence, secondaryLabel: CharSequence) {
         this.state = state
         this.label = label
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt
index e509696..013c925 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt
@@ -29,6 +29,7 @@
     private var tileSpec: String? = null
     var destroyed = false
     private val state = QSTile.State()
+    val callbacks = mutableListOf<QSTile.Callback>()
 
     override fun getTileSpec(): String? {
         return tileSpec
@@ -45,11 +46,17 @@
 
     override fun refreshState() {}
 
-    override fun addCallback(callback: QSTile.Callback?) {}
+    override fun addCallback(callback: QSTile.Callback) {
+        callbacks.add(callback)
+    }
 
-    override fun removeCallback(callback: QSTile.Callback?) {}
+    override fun removeCallback(callback: QSTile.Callback) {
+        callbacks.remove(callback)
+    }
 
-    override fun removeCallbacks() {}
+    override fun removeCallbacks() {
+        callbacks.clear()
+    }
 
     override fun createTileView(context: Context?): QSIconView? {
         return null
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
index 84cc977..6614392 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
@@ -43,6 +43,7 @@
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
 import android.testing.AndroidTestingRunner;
@@ -961,6 +962,26 @@
         assertThat(dds).contains(mContext.getString(R.string.carrier_network_change_mode));
     }
 
+    @Test
+    public void onStop_cleanUp() {
+        doReturn(SUB_ID).when(mTelephonyManager).getSubscriptionId();
+        assertThat(mInternetDialogController.mSubIdTelephonyManagerMap.get(SUB_ID)).isEqualTo(
+                mTelephonyManager);
+        assertThat(mInternetDialogController.mSubIdTelephonyCallbackMap.get(SUB_ID)).isNotNull();
+
+        mInternetDialogController.onStop();
+
+        verify(mTelephonyManager).unregisterTelephonyCallback(any(TelephonyCallback.class));
+        assertThat(mInternetDialogController.mSubIdTelephonyDisplayInfoMap.isEmpty()).isTrue();
+        assertThat(mInternetDialogController.mSubIdTelephonyManagerMap.isEmpty()).isTrue();
+        assertThat(mInternetDialogController.mSubIdTelephonyCallbackMap.isEmpty()).isTrue();
+        verify(mSubscriptionManager).removeOnSubscriptionsChangedListener(mInternetDialogController
+                .mOnSubscriptionsChangedListener);
+        verify(mAccessPointController).removeAccessPointCallback(mInternetDialogController);
+        verify(mConnectivityManager).unregisterNetworkCallback(
+                any(ConnectivityManager.NetworkCallback.class));
+    }
+
     private String getResourcesString(String name) {
         return mContext.getResources().getString(getResourcesId(name));
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
index e8875be..105387d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
@@ -18,15 +18,11 @@
 
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.authentication.data.repository.AuthenticationRepositoryImpl
-import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
-import com.android.systemui.bouncer.data.repo.BouncerRepository
-import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.domain.interactor.LockScreenSceneInteractor
-import com.android.systemui.scene.data.repository.fakeSceneContainerRepository
-import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
+import com.android.systemui.scene.SceneTestUtils
+import com.android.systemui.scene.SceneTestUtils.Companion.CONTAINER_1
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
 import com.google.common.truth.Truth.assertThat
@@ -44,51 +40,38 @@
 class QuickSettingsSceneViewModelTest : SysuiTestCase() {
 
     private val testScope = TestScope()
-    private val sceneInteractor =
-        SceneInteractor(
-            repository = fakeSceneContainerRepository(),
-        )
-    private val mAuthenticationInteractor =
-        AuthenticationInteractor(
-            applicationScope = testScope.backgroundScope,
-            repository = AuthenticationRepositoryImpl(),
+    private val utils = SceneTestUtils(this, testScope)
+    private val sceneInteractor = utils.sceneInteractor()
+    private val authenticationInteractor =
+        utils.authenticationInteractor(
+            repository = utils.authenticationRepository(),
         )
 
     private val underTest =
         QuickSettingsSceneViewModel(
-            lockScreenSceneInteractorFactory =
-                object : LockScreenSceneInteractor.Factory {
-                    override fun create(containerName: String): LockScreenSceneInteractor {
-                        return LockScreenSceneInteractor(
-                            applicationScope = testScope.backgroundScope,
-                            authenticationInteractor = mAuthenticationInteractor,
-                            bouncerInteractorFactory =
-                                object : BouncerInteractor.Factory {
-                                    override fun create(containerName: String): BouncerInteractor {
-                                        return BouncerInteractor(
-                                            applicationScope = testScope.backgroundScope,
-                                            applicationContext = context,
-                                            repository = BouncerRepository(),
-                                            authenticationInteractor = mAuthenticationInteractor,
-                                            sceneInteractor = sceneInteractor,
-                                            containerName = containerName,
-                                        )
-                                    }
-                                },
+            lockscreenSceneInteractorFactory =
+                object : LockscreenSceneInteractor.Factory {
+                    override fun create(containerName: String): LockscreenSceneInteractor {
+                        return utils.lockScreenSceneInteractor(
+                            authenticationInteractor = authenticationInteractor,
                             sceneInteractor = sceneInteractor,
-                            containerName = CONTAINER_NAME,
+                            bouncerInteractor =
+                                utils.bouncerInteractor(
+                                    authenticationInteractor = authenticationInteractor,
+                                    sceneInteractor = sceneInteractor,
+                                ),
                         )
                     }
                 },
-            containerName = CONTAINER_NAME
+            containerName = CONTAINER_1
         )
 
     @Test
     fun onContentClicked_deviceUnlocked_switchesToGone() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
-            mAuthenticationInteractor.unlockDevice()
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.unlockDevice()
             runCurrent()
 
             underTest.onContentClicked()
@@ -99,17 +82,13 @@
     @Test
     fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
-            mAuthenticationInteractor.lockDevice()
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.lockDevice()
             runCurrent()
 
             underTest.onContentClicked()
 
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
         }
-
-    companion object {
-        private const val CONTAINER_NAME = "container1"
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/Fakes.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/Fakes.kt
deleted file mode 100644
index 1cdaec0..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/Fakes.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.scene.data.repository
-
-import com.android.systemui.scene.data.model.SceneContainerConfig
-import com.android.systemui.scene.shared.model.SceneKey
-
-fun fakeSceneContainerRepository(
-    containerConfigurations: Set<SceneContainerConfig> =
-        setOf(
-            fakeSceneContainerConfig("container1"),
-            fakeSceneContainerConfig("container2"),
-        )
-): SceneContainerRepository {
-    return SceneContainerRepository(containerConfigurations)
-}
-
-fun fakeSceneKeys(): List<SceneKey> {
-    return listOf(
-        SceneKey.QuickSettings,
-        SceneKey.Shade,
-        SceneKey.LockScreen,
-        SceneKey.Bouncer,
-        SceneKey.Gone,
-    )
-}
-
-fun fakeSceneContainerConfig(
-    name: String,
-    sceneKeys: List<SceneKey> = fakeSceneKeys(),
-): SceneContainerConfig {
-    return SceneContainerConfig(
-        name = name,
-        sceneKeys = sceneKeys,
-        initialSceneKey = SceneKey.LockScreen,
-    )
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
index 9e264db8..de15c77 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
@@ -21,6 +21,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.scene.SceneTestUtils
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
 import com.google.common.truth.Truth.assertThat
@@ -34,15 +35,17 @@
 @RunWith(JUnit4::class)
 class SceneContainerRepositoryTest : SysuiTestCase() {
 
+    private val utils = SceneTestUtils(this)
+
     @Test
     fun allSceneKeys() {
-        val underTest = fakeSceneContainerRepository()
+        val underTest = utils.fakeSceneContainerRepository()
         assertThat(underTest.allSceneKeys("container1"))
             .isEqualTo(
                 listOf(
                     SceneKey.QuickSettings,
                     SceneKey.Shade,
-                    SceneKey.LockScreen,
+                    SceneKey.Lockscreen,
                     SceneKey.Bouncer,
                     SceneKey.Gone,
                 )
@@ -51,15 +54,15 @@
 
     @Test(expected = IllegalStateException::class)
     fun allSceneKeys_noSuchContainer_throws() {
-        val underTest = fakeSceneContainerRepository()
+        val underTest = utils.fakeSceneContainerRepository()
         underTest.allSceneKeys("nonExistingContainer")
     }
 
     @Test
     fun currentScene() = runTest {
-        val underTest = fakeSceneContainerRepository()
+        val underTest = utils.fakeSceneContainerRepository()
         val currentScene by collectLastValue(underTest.currentScene("container1"))
-        assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
+        assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
 
         underTest.setCurrentScene("container1", SceneModel(SceneKey.Shade))
         assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade))
@@ -67,25 +70,25 @@
 
     @Test(expected = IllegalStateException::class)
     fun currentScene_noSuchContainer_throws() {
-        val underTest = fakeSceneContainerRepository()
+        val underTest = utils.fakeSceneContainerRepository()
         underTest.currentScene("nonExistingContainer")
     }
 
     @Test(expected = IllegalStateException::class)
     fun setCurrentScene_noSuchContainer_throws() {
-        val underTest = fakeSceneContainerRepository()
+        val underTest = utils.fakeSceneContainerRepository()
         underTest.setCurrentScene("nonExistingContainer", SceneModel(SceneKey.Shade))
     }
 
     @Test(expected = IllegalStateException::class)
     fun setCurrentScene_noSuchSceneInContainer_throws() {
         val underTest =
-            fakeSceneContainerRepository(
+            utils.fakeSceneContainerRepository(
                 setOf(
-                    fakeSceneContainerConfig("container1"),
-                    fakeSceneContainerConfig(
+                    utils.fakeSceneContainerConfig("container1"),
+                    utils.fakeSceneContainerConfig(
                         "container2",
-                        listOf(SceneKey.QuickSettings, SceneKey.LockScreen)
+                        listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)
                     ),
                 )
             )
@@ -94,7 +97,7 @@
 
     @Test
     fun isVisible() = runTest {
-        val underTest = fakeSceneContainerRepository()
+        val underTest = utils.fakeSceneContainerRepository()
         val isVisible by collectLastValue(underTest.isVisible("container1"))
         assertThat(isVisible).isTrue()
 
@@ -107,19 +110,19 @@
 
     @Test(expected = IllegalStateException::class)
     fun isVisible_noSuchContainer_throws() {
-        val underTest = fakeSceneContainerRepository()
+        val underTest = utils.fakeSceneContainerRepository()
         underTest.isVisible("nonExistingContainer")
     }
 
     @Test(expected = IllegalStateException::class)
     fun setVisible_noSuchContainer_throws() {
-        val underTest = fakeSceneContainerRepository()
+        val underTest = utils.fakeSceneContainerRepository()
         underTest.setVisible("nonExistingContainer", false)
     }
 
     @Test
     fun sceneTransitionProgress() = runTest {
-        val underTest = fakeSceneContainerRepository()
+        val underTest = utils.fakeSceneContainerRepository()
         val sceneTransitionProgress by
             collectLastValue(underTest.sceneTransitionProgress("container1"))
         assertThat(sceneTransitionProgress).isEqualTo(1f)
@@ -133,7 +136,7 @@
 
     @Test(expected = IllegalStateException::class)
     fun sceneTransitionProgress_noSuchContainer_throws() {
-        val underTest = fakeSceneContainerRepository()
+        val underTest = utils.fakeSceneContainerRepository()
         underTest.sceneTransitionProgress("nonExistingContainer")
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index c5ce092..ee4f6c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -21,8 +21,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.scene.data.repository.fakeSceneContainerRepository
-import com.android.systemui.scene.data.repository.fakeSceneKeys
+import com.android.systemui.scene.SceneTestUtils
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
 import com.google.common.truth.Truth.assertThat
@@ -36,20 +35,18 @@
 @RunWith(JUnit4::class)
 class SceneInteractorTest : SysuiTestCase() {
 
-    private val underTest =
-        SceneInteractor(
-            repository = fakeSceneContainerRepository(),
-        )
+    private val utils = SceneTestUtils(this)
+    private val underTest = utils.sceneInteractor()
 
     @Test
     fun allSceneKeys() {
-        assertThat(underTest.allSceneKeys("container1")).isEqualTo(fakeSceneKeys())
+        assertThat(underTest.allSceneKeys("container1")).isEqualTo(utils.fakeSceneKeys())
     }
 
     @Test
     fun sceneTransitions() = runTest {
         val currentScene by collectLastValue(underTest.currentScene("container1"))
-        assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
+        assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
 
         underTest.setCurrentScene("container1", SceneModel(SceneKey.Shade))
         assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
index ab61ddd..cd2f5af 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
@@ -21,9 +21,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.scene.data.repository.fakeSceneContainerRepository
-import com.android.systemui.scene.data.repository.fakeSceneKeys
-import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.SceneTestUtils
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
 import com.google.common.truth.Truth.assertThat
@@ -36,10 +34,9 @@
 @SmallTest
 @RunWith(JUnit4::class)
 class SceneContainerViewModelTest : SysuiTestCase() {
-    private val interactor =
-        SceneInteractor(
-            repository = fakeSceneContainerRepository(),
-        )
+
+    private val utils = SceneTestUtils(this)
+    private val interactor = utils.sceneInteractor()
     private val underTest =
         SceneContainerViewModel(
             interactor = interactor,
@@ -60,13 +57,13 @@
 
     @Test
     fun allSceneKeys() {
-        assertThat(underTest.allSceneKeys).isEqualTo(fakeSceneKeys())
+        assertThat(underTest.allSceneKeys).isEqualTo(utils.fakeSceneKeys())
     }
 
     @Test
     fun sceneTransition() = runTest {
         val currentScene by collectLastValue(underTest.currentScene)
-        assertThat(currentScene).isEqualTo(SceneModel(SceneKey.LockScreen))
+        assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
 
         underTest.setCurrentScene(SceneModel(SceneKey.Shade))
         assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
index 7c30843b..3def6ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
@@ -46,6 +46,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
@@ -73,6 +75,8 @@
     private Handler mHandler;
     @Mock
     private UserContextProvider mUserContextTracker;
+    @Captor
+    private ArgumentCaptor<Runnable> mRunnableCaptor;
     private KeyguardDismissUtil mKeyguardDismissUtil = new KeyguardDismissUtil() {
         public void executeWhenUnlocked(ActivityStarter.OnDismissAction action,
                 boolean requiresShadeOpen) {
@@ -209,4 +213,19 @@
 
         verify(mScreenMediaRecorder).release();
     }
+
+    @Test
+    public void testOnErrorSaving() throws IOException {
+        // When the screen recording does not save properly
+        doThrow(new IllegalStateException("fail")).when(mScreenMediaRecorder).save();
+
+        Intent startIntent = RecordingService.getStopIntent(mContext);
+        mRecordingService.onStartCommand(startIntent, 0, 0);
+        verify(mExecutor).execute(mRunnableCaptor.capture());
+        mRunnableCaptor.getValue().run();
+
+        // Then the state is set to not recording and we cancel the notification
+        verify(mController).updateState(false);
+        verify(mNotificationManager).cancelAsUser(any(), anyInt(), any());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java
index 3c08d58..27eec80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java
@@ -37,8 +37,8 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Parcel;
+import android.os.Process;
 import android.os.ResultReceiver;
-import android.os.UserHandle;
 import android.testing.AndroidTestingRunner;
 import android.widget.ImageView;
 
@@ -120,7 +120,8 @@
         ImageExporter.Result result = new ImageExporter.Result();
         result.uri = TEST_URI;
         when(mImageExporter.export(any(Executor.class), any(UUID.class), any(Bitmap.class),
-                any(UserHandle.class))).thenReturn(Futures.immediateFuture(result));
+                eq(Process.myUserHandle())))
+                .thenReturn(Futures.immediateFuture(result));
     }
 
     @After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java
index cbd9dba..e9007ff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java
@@ -27,6 +27,7 @@
 import static com.android.systemui.flags.Flags.SCREENSHOT_APP_CLIPS;
 import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_TRIGGERED;
 import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_SCREENSHOT_URI;
+import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_USE_WP_USER;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -74,6 +75,7 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.List;
 import java.util.Optional;
 
 @RunWith(AndroidTestingRunner.class)
@@ -82,7 +84,6 @@
     private static final String TEST_URI_STRING = "www.test-uri.com";
     private static final Uri TEST_URI = Uri.parse(TEST_URI_STRING);
     private static final int TEST_UID = 42;
-    private static final int TEST_USER_ID = 43;
     private static final String TEST_CALLING_PACKAGE = "test-calling-package";
 
     @Mock
@@ -287,6 +288,7 @@
         assertThat(actualIntent.getComponent()).isEqualTo(
                 new ComponentName(mContext, AppClipsTrampolineActivity.class));
         assertThat(actualIntent.getFlags()).isEqualTo(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+        assertThat(actualIntent.getBooleanExtra(EXTRA_USE_WP_USER, false)).isTrue();
         assertThat(activity.mStartingUser).isEqualTo(UserHandle.SYSTEM);
     }
 
@@ -313,13 +315,13 @@
         when(mOptionalBubbles.get()).thenReturn(mBubbles);
         when(mBubbles.isAppBubbleTaskId(anyInt())).thenReturn(true);
         when(mDevicePolicyManager.getScreenCaptureDisabled(eq(null))).thenReturn(false);
-        when(mUserTracker.getUserId()).thenReturn(TEST_USER_ID);
+        when(mUserTracker.getUserProfiles()).thenReturn(List.of());
 
         ApplicationInfo testApplicationInfo = new ApplicationInfo();
         testApplicationInfo.uid = TEST_UID;
         when(mPackageManager.getApplicationInfoAsUser(eq(TEST_CALLING_PACKAGE),
                 any(ApplicationInfoFlags.class),
-                eq(TEST_USER_ID))).thenReturn(testApplicationInfo);
+                eq(mContext.getUser().getIdentifier()))).thenReturn(testApplicationInfo);
     }
 
     public static final class AppClipsTrampolineActivityTestable extends
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java
index e7c3c05..b7b8b11 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java
@@ -31,6 +31,7 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.ShapeDrawable;
 import android.net.Uri;
+import android.os.Process;
 import android.os.UserHandle;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -57,10 +58,10 @@
     private static final Drawable FAKE_DRAWABLE = new ShapeDrawable();
     private static final Rect FAKE_RECT = new Rect();
     private static final Uri FAKE_URI = Uri.parse("www.test-uri.com");
+    private static final UserHandle USER_HANDLE = Process.myUserHandle();
 
     @Mock private AppClipsCrossProcessHelper mAppClipsCrossProcessHelper;
     @Mock private ImageExporter mImageExporter;
-
     private AppClipsViewModel mViewModel;
 
     @Before
@@ -99,10 +100,10 @@
     @Test
     public void saveScreenshot_throwsError_shouldUpdateErrorWithFailed() {
         when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null),
-                any(UserHandle.class))).thenReturn(
+                eq(USER_HANDLE))).thenReturn(
                 Futures.immediateFailedFuture(new ExecutionException(new Throwable())));
 
-        mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT);
+        mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT, USER_HANDLE);
         waitForIdleSync();
 
         assertThat(mViewModel.getErrorLiveData().getValue())
@@ -113,10 +114,9 @@
     @Test
     public void saveScreenshot_failsSilently_shouldUpdateErrorWithFailed() {
         when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null),
-                any(UserHandle.class))).thenReturn(
-                        Futures.immediateFuture(new ImageExporter.Result()));
+                eq(USER_HANDLE))).thenReturn(Futures.immediateFuture(new ImageExporter.Result()));
 
-        mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT);
+        mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT, USER_HANDLE);
         waitForIdleSync();
 
         assertThat(mViewModel.getErrorLiveData().getValue())
@@ -129,9 +129,9 @@
         ImageExporter.Result result = new ImageExporter.Result();
         result.uri = FAKE_URI;
         when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null),
-                any(UserHandle.class))).thenReturn(Futures.immediateFuture(result));
+                eq(USER_HANDLE))).thenReturn(Futures.immediateFuture(result));
 
-        mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT);
+        mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT, USER_HANDLE);
         waitForIdleSync();
 
         assertThat(mViewModel.getErrorLiveData().getValue()).isNull();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 9a8ec88..fe89a14 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -679,6 +679,7 @@
                 mFeatureFlags,
                 mInteractionJankMonitor,
                 mShadeLog,
+                mDumpManager,
                 mKeyguardFaceAuthInteractor,
                 mShadeRepository,
                 mCastController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 48e0b53..a5a9de5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -902,6 +902,13 @@
     }
 
     @Test
+    public void isExpandingOrCollapsing_returnsTrue_whenQsLockscreenDragInProgress() {
+        when(mQsController.getLockscreenShadeDragProgress()).thenReturn(0.5f);
+        assertThat(mNotificationPanelViewController.isExpandingOrCollapsing()).isTrue();
+    }
+
+
+    @Test
     public void getMaxPanelTransitionDistance_inSplitShade_withHeadsUp_returnsBiggerValue() {
         enableSplitShade(true);
         mNotificationPanelViewController.expandToQs();
@@ -1099,7 +1106,7 @@
     }
 
     @Test
-    public void shadeExpanded_inShadeState() {
+    public void shadeFullyExpanded_inShadeState() {
         mStatusBarStateController.setState(SHADE);
 
         mNotificationPanelViewController.setExpandedHeight(0);
@@ -1111,7 +1118,7 @@
     }
 
     @Test
-    public void shadeExpanded_onKeyguard() {
+    public void shadeFullyExpanded_onKeyguard() {
         mStatusBarStateController.setState(KEYGUARD);
 
         int transitionDistance = mNotificationPanelViewController.getMaxPanelTransitionDistance();
@@ -1120,8 +1127,39 @@
     }
 
     @Test
-    public void shadeExpanded_onShadeLocked() {
+    public void shadeFullyExpanded_onShadeLocked() {
         mStatusBarStateController.setState(SHADE_LOCKED);
         assertThat(mNotificationPanelViewController.isShadeFullyExpanded()).isTrue();
     }
+
+    @Test
+    public void shadeExpanded_whenHasHeight() {
+        int transitionDistance = mNotificationPanelViewController.getMaxPanelTransitionDistance();
+        mNotificationPanelViewController.setExpandedHeight(transitionDistance);
+        assertThat(mNotificationPanelViewController.isExpanded()).isTrue();
+    }
+
+    @Test
+    public void shadeExpanded_whenInstantExpanding() {
+        mNotificationPanelViewController.expand(true);
+        assertThat(mNotificationPanelViewController.isExpanded()).isTrue();
+    }
+
+    @Test
+    public void shadeExpanded_whenHunIsPresent() {
+        when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
+        assertThat(mNotificationPanelViewController.isExpanded()).isTrue();
+    }
+
+    @Test
+    public void shadeExpanded_whenWaitingForExpandGesture() {
+        mNotificationPanelViewController.startWaitingForExpandGesture();
+        assertThat(mNotificationPanelViewController.isExpanded()).isTrue();
+    }
+
+    @Test
+    public void shadeExpanded_whenUnlockedOffscreenAnimationRunning() {
+        when(mUnlockedScreenOffAnimationController.isAnimationPlaying()).thenReturn(true);
+        assertThat(mNotificationPanelViewController.isExpanded()).isTrue();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt
index dfb1bce..168cbb7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt
@@ -229,25 +229,6 @@
     }
 
     @Test
-    fun testCustomizingInSinglePaneShade() {
-        disableSplitShade()
-        controller.setCustomizerShowing(true)
-
-        // always sets spacings to 0
-        given(taskbarVisible = false,
-                navigationMode = GESTURES_NAVIGATION,
-                insets = windowInsets().withStableBottom())
-        then(expectedContainerPadding = 0,
-                expectedNotificationsMargin = 0)
-
-        given(taskbarVisible = false,
-                navigationMode = BUTTONS_NAVIGATION,
-                insets = emptyInsets())
-        then(expectedContainerPadding = 0,
-                expectedNotificationsMargin = 0)
-    }
-
-    @Test
     fun testDetailShowingInSinglePaneShade() {
         disableSplitShade()
         controller.setDetailShowing(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
index 1cf3873..34d09a9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
@@ -247,6 +247,7 @@
                 mFeatureFlags,
                 mInteractionJankMonitor,
                 mShadeLogger,
+                mDumpManager,
                 mock(KeyguardFaceAuthInteractor.class),
                 mock(ShadeRepository.class),
                 mCastController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeExpansionStateManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeExpansionStateManagerTest.kt
index a601b67..15c04eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeExpansionStateManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeExpansionStateManagerTest.kt
@@ -35,7 +35,8 @@
     @Test
     fun onPanelExpansionChanged_listenerNotified() {
         val listener = TestShadeExpansionListener()
-        shadeExpansionStateManager.addExpansionListener(listener)
+        val currentState = shadeExpansionStateManager.addExpansionListener(listener)
+        listener.onPanelExpansionChanged(currentState)
         val fraction = 0.6f
         val expanded = true
         val tracking = true
@@ -68,7 +69,8 @@
         )
         val listener = TestShadeExpansionListener()
 
-        shadeExpansionStateManager.addExpansionListener(listener)
+        val currentState = shadeExpansionStateManager.addExpansionListener(listener)
+        listener.onPanelExpansionChanged(currentState)
 
         assertThat(listener.fraction).isEqualTo(fraction)
         assertThat(listener.expanded).isEqualTo(expanded)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java
index 2ef3d60..57ae621 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
@@ -109,6 +110,8 @@
                 .thenReturn(mCarrierTextControllerBuilder);
         when(mCarrierTextControllerBuilder.setShowMissingSim(anyBoolean()))
                 .thenReturn(mCarrierTextControllerBuilder);
+        when(mCarrierTextControllerBuilder.setDebugLocationString(anyString()))
+                .thenReturn(mCarrierTextControllerBuilder);
         when(mCarrierTextControllerBuilder.build()).thenReturn(mCarrierTextManager);
 
         doAnswer(invocation -> mCallback = invocation.getArgument(0))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
index 8f2c93b..e26a8bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.shade.ShadeExpansionChangeEvent
 import com.android.systemui.shade.ShadeExpansionStateManager
 import com.android.systemui.shade.domain.model.ShadeModel
+import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -37,6 +38,7 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
 @OptIn(ExperimentalCoroutinesApi::class)
@@ -56,6 +58,9 @@
         MockitoAnnotations.initMocks(this)
 
         underTest = ShadeRepositoryImpl(shadeExpansionStateManager)
+        `when`(shadeExpansionStateManager.addExpansionListener(any())).thenReturn(
+            ShadeExpansionChangeEvent(0f, false, false, 0f)
+        )
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index 688cce8..69d03d9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -18,15 +18,11 @@
 
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.authentication.data.repository.AuthenticationRepositoryImpl
-import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
-import com.android.systemui.bouncer.data.repo.BouncerRepository
-import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.domain.interactor.LockScreenSceneInteractor
-import com.android.systemui.scene.data.repository.fakeSceneContainerRepository
-import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
+import com.android.systemui.scene.SceneTestUtils
+import com.android.systemui.scene.SceneTestUtils.Companion.CONTAINER_1
 import com.android.systemui.scene.shared.model.SceneKey
 import com.android.systemui.scene.shared.model.SceneModel
 import com.google.common.truth.Truth.assertThat
@@ -44,62 +40,49 @@
 class ShadeSceneViewModelTest : SysuiTestCase() {
 
     private val testScope = TestScope()
-    private val sceneInteractor =
-        SceneInteractor(
-            repository = fakeSceneContainerRepository(),
-        )
-    private val mAuthenticationInteractor =
-        AuthenticationInteractor(
-            applicationScope = testScope.backgroundScope,
-            repository = AuthenticationRepositoryImpl(),
+    private val utils = SceneTestUtils(this, testScope)
+    private val sceneInteractor = utils.sceneInteractor()
+    private val authenticationInteractor =
+        utils.authenticationInteractor(
+            repository = utils.authenticationRepository(),
         )
 
     private val underTest =
         ShadeSceneViewModel(
             applicationScope = testScope.backgroundScope,
-            lockScreenSceneInteractorFactory =
-                object : LockScreenSceneInteractor.Factory {
-                    override fun create(containerName: String): LockScreenSceneInteractor {
-                        return LockScreenSceneInteractor(
-                            applicationScope = testScope.backgroundScope,
-                            authenticationInteractor = mAuthenticationInteractor,
-                            bouncerInteractorFactory =
-                                object : BouncerInteractor.Factory {
-                                    override fun create(containerName: String): BouncerInteractor {
-                                        return BouncerInteractor(
-                                            applicationScope = testScope.backgroundScope,
-                                            applicationContext = context,
-                                            repository = BouncerRepository(),
-                                            authenticationInteractor = mAuthenticationInteractor,
-                                            sceneInteractor = sceneInteractor,
-                                            containerName = containerName,
-                                        )
-                                    }
-                                },
+            lockscreenSceneInteractorFactory =
+                object : LockscreenSceneInteractor.Factory {
+                    override fun create(containerName: String): LockscreenSceneInteractor {
+                        return utils.lockScreenSceneInteractor(
+                            authenticationInteractor = authenticationInteractor,
                             sceneInteractor = sceneInteractor,
-                            containerName = CONTAINER_NAME,
+                            bouncerInteractor =
+                                utils.bouncerInteractor(
+                                    authenticationInteractor = authenticationInteractor,
+                                    sceneInteractor = sceneInteractor,
+                                ),
                         )
                     }
                 },
-            containerName = CONTAINER_NAME
+            containerName = SceneTestUtils.CONTAINER_1
         )
 
     @Test
     fun upTransitionSceneKey_deviceLocked_lockScreen() =
         testScope.runTest {
             val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
-            mAuthenticationInteractor.lockDevice()
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.lockDevice()
 
-            assertThat(upTransitionSceneKey).isEqualTo(SceneKey.LockScreen)
+            assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Lockscreen)
         }
 
     @Test
     fun upTransitionSceneKey_deviceUnlocked_gone() =
         testScope.runTest {
             val upTransitionSceneKey by collectLastValue(underTest.upDestinationSceneKey)
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
-            mAuthenticationInteractor.unlockDevice()
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.unlockDevice()
 
             assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Gone)
         }
@@ -107,9 +90,9 @@
     @Test
     fun onContentClicked_deviceUnlocked_switchesToGone() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
-            mAuthenticationInteractor.unlockDevice()
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.unlockDevice()
             runCurrent()
 
             underTest.onContentClicked()
@@ -120,17 +103,13 @@
     @Test
     fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
         testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
-            mAuthenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
-            mAuthenticationInteractor.lockDevice()
+            val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+            authenticationInteractor.setAuthenticationMethod(AuthenticationMethodModel.PIN(1234))
+            authenticationInteractor.lockDevice()
             runCurrent()
 
             underTest.onContentClicked()
 
             assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
         }
-
-    companion object {
-        private const val CONTAINER_NAME = "container1"
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
index 2eca78a..e92368d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
@@ -19,6 +19,7 @@
 import android.testing.AndroidTestingRunner
 import android.view.LayoutInflater
 import androidx.test.filters.SmallTest
+import com.android.app.animation.Interpolators
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.TextAnimator
@@ -64,8 +65,8 @@
                 color = 200,
                 strokeWidth = -1F,
                 animate = false,
-                duration = 350L,
-                interpolator = null,
+                duration = 833L,
+                interpolator = Interpolators.EMPHASIZED_DECELERATE,
                 delay = 0L,
                 onAnimationEnd = null
             )
@@ -98,8 +99,8 @@
                 color = 200,
                 strokeWidth = -1F,
                 animate = true,
-                duration = 350L,
-                interpolator = null,
+                duration = 833L,
+                interpolator = Interpolators.EMPHASIZED_DECELERATE,
                 delay = 0L,
                 onAnimationEnd = null
             )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java
index de5824d..b724175 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java
@@ -32,6 +32,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.log.TableLogBufferBase;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
 
@@ -44,6 +45,7 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 
 import kotlinx.coroutines.CoroutineScope;
@@ -59,6 +61,8 @@
 
     @Mock
     private CoroutineScope mScope;
+    @Mock
+    private TableLogBufferBase mLogBuffer;
 
     private Monitor mConditionMonitor;
 
@@ -630,4 +634,42 @@
         verify(callback).onActiveChanged(eq(true));
         verify(callback).onConditionsChanged(eq(true));
     }
+
+    @Test
+    public void testLoggingCallback() {
+        final Monitor monitor = new Monitor(mExecutor, Collections.emptySet(), mLogBuffer);
+
+        final FakeCondition condition = new FakeCondition(mScope);
+        final FakeCondition overridingCondition = new FakeCondition(
+                mScope,
+                /* initialValue= */ false,
+                /* overriding= */ true);
+
+        final Monitor.Callback callback = mock(Monitor.Callback.class);
+        monitor.addSubscription(getDefaultBuilder(callback)
+                .addCondition(condition)
+                .addCondition(overridingCondition)
+                .build());
+        mExecutor.runAllReady();
+
+        // condition set to true
+        condition.fakeUpdateCondition(true);
+        mExecutor.runAllReady();
+        verify(mLogBuffer).logChange("", "FakeCondition", "True");
+
+        // condition set to false
+        condition.fakeUpdateCondition(false);
+        mExecutor.runAllReady();
+        verify(mLogBuffer).logChange("", "FakeCondition", "False");
+
+        // condition unset
+        condition.fakeClearCondition();
+        mExecutor.runAllReady();
+        verify(mLogBuffer).logChange("", "FakeCondition", "Invalid");
+
+        // overriding condition set to true
+        overridingCondition.fakeUpdateCondition(true);
+        mExecutor.runAllReady();
+        verify(mLogBuffer).logChange("", "FakeCondition[OVRD]", "True");
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/FakeCondition.java b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/FakeCondition.java
index a325cbf..5416536 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/FakeCondition.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/FakeCondition.java
@@ -47,4 +47,8 @@
     public void fakeUpdateCondition(boolean isConditionMet) {
         updateCondition(isConditionMet);
     }
+
+    public void fakeClearCondition() {
+        clearCondition();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplerTest.kt
index ae1c8cb..1031621 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplerTest.kt
@@ -1,17 +1,30 @@
 package com.android.systemui.shared.regionsampling
 
+import android.app.WallpaperColors
 import android.app.WallpaperManager
+import android.graphics.Color
+import android.graphics.RectF
 import android.testing.AndroidTestingRunner
 import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.capture
+import com.google.common.truth.Truth.assertThat
 import java.io.PrintWriter
 import java.util.concurrent.Executor
+import org.junit.Assert.assertTrue
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Captor
 import org.mockito.Mock
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.junit.MockitoJUnit
 
@@ -26,25 +39,188 @@
     @Mock private lateinit var bgExecutor: Executor
     @Mock private lateinit var pw: PrintWriter
     @Mock private lateinit var wallpaperManager: WallpaperManager
+    @Mock private lateinit var updateForegroundColor: UpdateColorCallback
 
-    private lateinit var mRegionSampler: RegionSampler
-    private var updateFun: UpdateColorCallback = {}
+    private lateinit var regionSampler: RegionSampler // lockscreen
+    private lateinit var homescreenRegionSampler: RegionSampler
+
+    @Captor
+    private lateinit var colorsChangedListener:
+        ArgumentCaptor<WallpaperManager.LocalWallpaperColorConsumer>
+
+    @Captor private lateinit var layoutChangedListener: ArgumentCaptor<View.OnLayoutChangeListener>
 
     @Before
     fun setUp() {
         whenever(sampledView.isAttachedToWindow).thenReturn(true)
+        whenever(sampledView.width).thenReturn(100)
+        whenever(sampledView.height).thenReturn(100)
+        whenever(sampledView.isLaidOut).thenReturn(true)
+        whenever(sampledView.locationOnScreen).thenReturn(intArrayOf(0, 0))
 
-        mRegionSampler =
-            RegionSampler(sampledView, mainExecutor, bgExecutor, true, updateFun, wallpaperManager)
+        regionSampler =
+            RegionSampler(
+                sampledView,
+                mainExecutor,
+                bgExecutor,
+                regionSamplingEnabled = true,
+                isLockscreen = true,
+                wallpaperManager,
+                updateForegroundColor
+            )
+        regionSampler.displaySize.set(1080, 2050)
+
+        // TODO(b/265969235): test sampling on home screen via WallpaperManager.FLAG_SYSTEM
+        homescreenRegionSampler =
+            RegionSampler(
+                sampledView,
+                mainExecutor,
+                bgExecutor,
+                regionSamplingEnabled = true,
+                isLockscreen = false,
+                wallpaperManager,
+                updateForegroundColor
+            )
     }
 
     @Test
-    fun testStartRegionSampler() {
-        mRegionSampler.startRegionSampler()
+    fun testCalculatedBounds_inRange() {
+        // test calculations return region within [0,1]
+        sampledView.setLeftTopRightBottom(100, 100, 200, 200)
+        var fractionalBounds =
+            regionSampler.calculateScreenLocation(sampledView)?.let {
+                regionSampler.convertBounds(it)
+            }
+
+        assertTrue(fractionalBounds?.left!! >= 0.0f)
+        assertTrue(fractionalBounds.right <= 1.0f)
+        assertTrue(fractionalBounds.top >= 0.0f)
+        assertTrue(fractionalBounds.bottom <= 1.0f)
+    }
+
+    @Test
+    fun testEmptyView_returnsEarly() {
+        sampledView.setLeftTopRightBottom(0, 0, 0, 0)
+        whenever(sampledView.width).thenReturn(0)
+        whenever(sampledView.height).thenReturn(0)
+        regionSampler.startRegionSampler()
+        // returns early so should never call this function
+        verify(wallpaperManager, never())
+            .addOnColorsChangedListener(
+                any(WallpaperManager.LocalWallpaperColorConsumer::class.java),
+                any(),
+                any()
+            )
+    }
+
+    @Test
+    fun testLayoutChange_notifiesListener() {
+        regionSampler.startRegionSampler()
+        // don't count addOnColorsChangedListener() call made in startRegionSampler()
+        clearInvocations(wallpaperManager)
+
+        verify(sampledView).addOnLayoutChangeListener(capture(layoutChangedListener))
+        layoutChangedListener.value.onLayoutChange(
+            sampledView,
+            300,
+            300,
+            400,
+            400,
+            100,
+            100,
+            200,
+            200
+        )
+        verify(sampledView).removeOnLayoutChangeListener(layoutChangedListener.value)
+        verify(wallpaperManager)
+            .removeOnColorsChangedListener(
+                any(WallpaperManager.LocalWallpaperColorConsumer::class.java)
+            )
+        verify(wallpaperManager)
+            .addOnColorsChangedListener(
+                any(WallpaperManager.LocalWallpaperColorConsumer::class.java),
+                any(),
+                any()
+            )
+    }
+
+    @Test
+    fun testColorsChanged_triggersCallback() {
+        regionSampler.startRegionSampler()
+        verify(wallpaperManager)
+            .addOnColorsChangedListener(
+                capture(colorsChangedListener),
+                any(),
+                eq(WallpaperManager.FLAG_LOCK)
+            )
+        setWhiteWallpaper()
+        verify(updateForegroundColor).invoke()
+    }
+
+    @Test
+    fun testRegionDarkness() {
+        regionSampler.startRegionSampler()
+        verify(wallpaperManager)
+            .addOnColorsChangedListener(
+                capture(colorsChangedListener),
+                any(),
+                eq(WallpaperManager.FLAG_LOCK)
+            )
+
+        // should detect dark region
+        setBlackWallpaper()
+        assertThat(regionSampler.currentRegionDarkness()).isEqualTo(RegionDarkness.DARK)
+
+        // should detect light region
+        setWhiteWallpaper()
+        assertThat(regionSampler.currentRegionDarkness()).isEqualTo(RegionDarkness.LIGHT)
+    }
+
+    @Test
+    fun testForegroundColor() {
+        regionSampler.setForegroundColors(Color.WHITE, Color.BLACK)
+        regionSampler.startRegionSampler()
+        verify(wallpaperManager)
+            .addOnColorsChangedListener(
+                capture(colorsChangedListener),
+                any(),
+                eq(WallpaperManager.FLAG_LOCK)
+            )
+
+        // dark background, light text
+        setBlackWallpaper()
+        assertThat(regionSampler.currentForegroundColor()).isEqualTo(Color.WHITE)
+
+        // light background, dark text
+        setWhiteWallpaper()
+        assertThat(regionSampler.currentForegroundColor()).isEqualTo(Color.BLACK)
+    }
+
+    private fun setBlackWallpaper() {
+        val wallpaperColors =
+            WallpaperColors(Color.valueOf(Color.BLACK), Color.valueOf(Color.BLACK), null)
+        colorsChangedListener.value.onColorsChanged(
+            RectF(100.0f, 100.0f, 200.0f, 200.0f),
+            wallpaperColors
+        )
+    }
+    private fun setWhiteWallpaper() {
+        val wallpaperColors =
+            WallpaperColors(
+                Color.valueOf(Color.WHITE),
+                Color.valueOf(Color.WHITE),
+                null,
+                WallpaperColors.HINT_SUPPORTS_DARK_TEXT
+            )
+        colorsChangedListener.value.onColorsChanged(
+            RectF(100.0f, 100.0f, 200.0f, 200.0f),
+            wallpaperColors
+        )
     }
 
     @Test
     fun testDump() {
-        mRegionSampler.dump(pw)
+        regionSampler.dump(pw)
+        homescreenRegionSampler.dump(pw)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index f4cd383..1643e17 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -28,7 +28,6 @@
 
 import android.content.ComponentName;
 import android.graphics.Rect;
-import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.IBiometricSysuiReceiver;
 import android.hardware.biometrics.PromptInfo;
 import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback;
@@ -443,15 +442,13 @@
         final long operationId = 1;
         final String packageName = "test";
         final long requestId = 10;
-        final int multiSensorConfig = BiometricManager.BIOMETRIC_MULTI_SENSOR_DEFAULT;
 
         mCommandQueue.showAuthenticationDialog(promptInfo, receiver, sensorIds,
-                credentialAllowed, requireConfirmation, userId, operationId, packageName, requestId,
-                multiSensorConfig);
+                credentialAllowed, requireConfirmation, userId, operationId, packageName, requestId);
         waitForIdleSync();
         verify(mCallbacks).showAuthenticationDialog(eq(promptInfo), eq(receiver), eq(sensorIds),
                 eq(credentialAllowed), eq(requireConfirmation), eq(userId), eq(operationId),
-                eq(packageName), eq(requestId), eq(multiSensorConfig));
+                eq(packageName), eq(requestId));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index f7fcab1..542e0cb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -1066,11 +1066,11 @@
     }
 
     @Test
-    public void onRefreshBatteryInfo_chargingWithOverheat_presentChargingLimited() {
+    public void onRefreshBatteryInfo_chargingWithLongLife_presentChargingLimited() {
         createController();
         BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_CHARGING,
                 80 /* level */, BatteryManager.BATTERY_PLUGGED_AC,
-                BatteryManager.BATTERY_HEALTH_OVERHEAT, 0 /* maxChargingWattage */,
+                BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE, 0 /* maxChargingWattage */,
                 true /* present */);
 
         mController.getKeyguardCallback().onRefreshBatteryInfo(status);
@@ -1084,11 +1084,11 @@
     }
 
     @Test
-    public void onRefreshBatteryInfo_fullChargedWithOverheat_presentChargingLimited() {
+    public void onRefreshBatteryInfo_fullChargedWithLongLife_presentChargingLimited() {
         createController();
         BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_CHARGING,
                 100 /* level */, BatteryManager.BATTERY_PLUGGED_AC,
-                BatteryManager.BATTERY_HEALTH_OVERHEAT, 0 /* maxChargingWattage */,
+                BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE, 0 /* maxChargingWattage */,
                 true /* present */);
 
         mController.getKeyguardCallback().onRefreshBatteryInfo(status);
@@ -1102,11 +1102,11 @@
     }
 
     @Test
-    public void onRefreshBatteryInfo_fullChargedWithoutOverheat_presentCharged() {
+    public void onRefreshBatteryInfo_fullChargedWithoutLongLife_presentCharged() {
         createController();
         BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_CHARGING,
                 100 /* level */, BatteryManager.BATTERY_PLUGGED_AC,
-                BatteryManager.BATTERY_HEALTH_GOOD, 0 /* maxChargingWattage */,
+                BatteryManager.CHARGING_POLICY_DEFAULT, 0 /* maxChargingWattage */,
                 true /* present */);
 
         mController.getKeyguardCallback().onRefreshBatteryInfo(status);
@@ -1118,11 +1118,11 @@
     }
 
     @Test
-    public void onRefreshBatteryInfo_dozing_dischargingWithOverheat_presentBatteryPercentage() {
+    public void onRefreshBatteryInfo_dozing_dischargingWithLongLife_presentBatteryPercentage() {
         createController();
         mController.setVisible(true);
         BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_DISCHARGING,
-                90 /* level */, 0 /* plugged */, BatteryManager.BATTERY_HEALTH_OVERHEAT,
+                90 /* level */, 0 /* plugged */, BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE,
                 0 /* maxChargingWattage */, true /* present */);
 
         mController.getKeyguardCallback().onRefreshBatteryInfo(status);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt
index cd06465..8397702 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt
@@ -27,3 +27,9 @@
     override val showAnimation: Boolean = true,
     override var contentDescription: String? = "",
 ) : StatusEvent
+
+class FakePrivacyStatusEvent(
+    override val viewCreator: ViewCreator,
+    override val showAnimation: Boolean = true,
+    override var contentDescription: String? = "",
+) : PrivacyEvent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt
index 08a9f31..39ed553 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt
@@ -380,6 +380,53 @@
     }
 
     @Test
+    fun testPrivacyEvent_forceVisibleIsUpdated_whenRescheduledDuringQueuedState() = runTest {
+        // Instantiate class under test with TestScope from runTest
+        initializeSystemStatusAnimationScheduler(testScope = this)
+
+        // create and schedule privacy event
+        createAndScheduleFakePrivacyEvent()
+        // request removal of persistent dot (sets forceVisible to false)
+        systemStatusAnimationScheduler.removePersistentDot()
+        // create and schedule a privacy event again (resets forceVisible to true)
+        createAndScheduleFakePrivacyEvent()
+
+        // skip chip animation lifecycle and fast forward to SHOWING_PERSISTENT_DOT state
+        fastForwardAnimationToState(SHOWING_PERSISTENT_DOT)
+
+        // verify that we reach SHOWING_PERSISTENT_DOT and that listener callback is invoked
+        assertEquals(SHOWING_PERSISTENT_DOT, systemStatusAnimationScheduler.getAnimationState())
+        verify(listener, times(1)).onSystemStatusAnimationTransitionToPersistentDot(any())
+    }
+
+    @Test
+    fun testPrivacyEvent_forceVisibleIsUpdated_whenRescheduledDuringAnimatingState() = runTest {
+        // Instantiate class under test with TestScope from runTest
+        initializeSystemStatusAnimationScheduler(testScope = this)
+
+        // create and schedule privacy event
+        createAndScheduleFakePrivacyEvent()
+        // request removal of persistent dot (sets forceVisible to false)
+        systemStatusAnimationScheduler.removePersistentDot()
+        fastForwardAnimationToState(RUNNING_CHIP_ANIM)
+
+        // create and schedule a privacy event again (resets forceVisible to true)
+        createAndScheduleFakePrivacyEvent()
+
+        // skip status chip display time
+        advanceTimeBy(DISPLAY_LENGTH + 1)
+        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        verify(listener, times(1)).onSystemEventAnimationFinish(anyBoolean())
+
+        // skip disappear animation
+        animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
+
+        // verify that we reach SHOWING_PERSISTENT_DOT and that listener callback is invoked
+        assertEquals(SHOWING_PERSISTENT_DOT, systemStatusAnimationScheduler.getAnimationState())
+        verify(listener, times(1)).onSystemStatusAnimationTransitionToPersistentDot(any())
+    }
+
+    @Test
     fun testNewEvent_isScheduled_whenPostedDuringRemovalAnimation() = runTest {
         // Instantiate class under test with TestScope from runTest
         initializeSystemStatusAnimationScheduler(testScope = this)
@@ -440,8 +487,7 @@
 
     private fun createAndScheduleFakePrivacyEvent(): OngoingPrivacyChip {
         val privacyChip = OngoingPrivacyChip(mContext)
-        val fakePrivacyStatusEvent =
-            FakeStatusEvent(viewCreator = { privacyChip }, priority = 100, forceVisible = true)
+        val fakePrivacyStatusEvent = FakePrivacyStatusEvent(viewCreator = { privacyChip })
         systemStatusAnimationScheduler.onStatusEvent(fakePrivacyStatusEvent)
         return privacyChip
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index f771606..a4ee349 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -188,13 +188,6 @@
                 .thenReturn(mNotificationRoundnessManager);
         mStackScroller.setController(mStackScrollLayoutController);
 
-        // Stub out functionality that isn't necessary to test.
-        doNothing().when(mCentralSurfaces)
-                .executeRunnableDismissingKeyguard(any(Runnable.class),
-                        any(Runnable.class),
-                        anyBoolean(),
-                        anyBoolean(),
-                        anyBoolean());
         doNothing().when(mGroupExpansionManager).collapseGroups();
         doNothing().when(mExpandHelper).cancelImmediately();
         doNothing().when(mNotificationShelf).setAnimationsEnabled(anyBoolean());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index 551499e..7632d01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -392,23 +392,32 @@
 
     @Test
     public void testSnapchild_targetIsZero() {
-        doNothing().when(mSwipeHelper).superSnapChild(mView, 0, 0);
-        mSwipeHelper.snapChild(mView, 0, 0);
+        doNothing().when(mSwipeHelper).superSnapChild(mNotificationRow, 0, 0);
+        mSwipeHelper.snapChild(mNotificationRow, 0, 0);
 
-        verify(mCallback, times(1)).onDragCancelled(mView);
-        verify(mSwipeHelper, times(1)).superSnapChild(mView, 0, 0);
+        verify(mCallback, times(1)).onDragCancelled(mNotificationRow);
+        verify(mSwipeHelper, times(1)).superSnapChild(mNotificationRow, 0, 0);
         verify(mSwipeHelper, times(1)).handleMenuCoveredOrDismissed();
     }
 
 
     @Test
     public void testSnapchild_targetNotZero() {
+        doNothing().when(mSwipeHelper).superSnapChild(mNotificationRow, 10, 0);
+        mSwipeHelper.snapChild(mNotificationRow, 10, 0);
+
+        verify(mCallback, times(1)).onDragCancelled(mNotificationRow);
+        verify(mSwipeHelper, times(1)).superSnapChild(mNotificationRow, 10, 0);
+        verify(mSwipeHelper, times(0)).handleMenuCoveredOrDismissed();
+    }
+
+    @Test
+    public void testSnapchild_targetNotSwipeable() {
         doNothing().when(mSwipeHelper).superSnapChild(mView, 10, 0);
         mSwipeHelper.snapChild(mView, 10, 0);
 
-        verify(mCallback, times(1)).onDragCancelled(mView);
-        verify(mSwipeHelper, times(1)).superSnapChild(mView, 10, 0);
-        verify(mSwipeHelper, times(0)).handleMenuCoveredOrDismissed();
+        verify(mCallback).onDragCancelled(mView);
+        verify(mSwipeHelper, never()).superSnapChild(mView, 10, 0);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index 7f20f1e..e12d179 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -716,6 +716,94 @@
                 .isLessThan(px(R.dimen.heads_up_pinned_elevation))
     }
 
+    @Test
+    fun aodToLockScreen_hasPulsingNotification_pulsingNotificationRowDoesNotChange() {
+        // Given: Before AOD to LockScreen, there was a pulsing notification
+        val pulsingNotificationView = createPulsingViewMock()
+        val algorithmState = StackScrollAlgorithm.StackScrollAlgorithmState()
+        algorithmState.visibleChildren.add(pulsingNotificationView)
+        ambientState.setPulsingRow(pulsingNotificationView)
+
+        // When: during AOD to LockScreen, any dozeAmount between (0, 1.0) is equivalent as a middle
+        // stage; here we use 0.5 for testing.
+        // stackScrollAlgorithm.updatePulsingStates is called
+        ambientState.dozeAmount = 0.5f
+        stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState)
+
+        // Then: ambientState.pulsingRow should still be pulsingNotificationView
+        assertTrue(ambientState.isPulsingRow(pulsingNotificationView))
+    }
+
+    @Test
+    fun deviceOnAod_hasPulsingNotification_recordPulsingNotificationRow() {
+        // Given: Device is on AOD, there is a pulsing notification
+        // ambientState.pulsingRow is null before stackScrollAlgorithm.updatePulsingStates
+        ambientState.dozeAmount = 1.0f
+        val pulsingNotificationView = createPulsingViewMock()
+        val algorithmState = StackScrollAlgorithm.StackScrollAlgorithmState()
+        algorithmState.visibleChildren.add(pulsingNotificationView)
+        ambientState.setPulsingRow(null)
+
+        // When: stackScrollAlgorithm.updatePulsingStates is called
+        stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState)
+
+        // Then: ambientState.pulsingRow should record the pulsingNotificationView
+        assertTrue(ambientState.isPulsingRow(pulsingNotificationView))
+    }
+
+    @Test
+    fun deviceOnLockScreen_hasPulsingNotificationBefore_clearPulsingNotificationRowRecord() {
+        // Given: Device finished AOD to LockScreen, there was a pulsing notification, and
+        // ambientState.pulsingRow was not null before AOD to LockScreen
+        // pulsingNotificationView.showingPulsing() returns false since the device is on LockScreen
+        ambientState.dozeAmount = 0.0f
+        val pulsingNotificationView = createPulsingViewMock()
+        whenever(pulsingNotificationView.showingPulsing()).thenReturn(false)
+        val algorithmState = StackScrollAlgorithm.StackScrollAlgorithmState()
+        algorithmState.visibleChildren.add(pulsingNotificationView)
+        ambientState.setPulsingRow(pulsingNotificationView)
+
+        // When: stackScrollAlgorithm.updatePulsingStates is called
+        stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState)
+
+        // Then: ambientState.pulsingRow should be null
+        assertTrue(ambientState.isPulsingRow(null))
+    }
+
+    @Test
+    fun aodToLockScreen_hasPulsingNotification_pulsingNotificationRowShowAtFullHeight() {
+        // Given: Before AOD to LockScreen, there was a pulsing notification
+        val pulsingNotificationView = createPulsingViewMock()
+        val algorithmState = StackScrollAlgorithm.StackScrollAlgorithmState()
+        algorithmState.visibleChildren.add(pulsingNotificationView)
+        ambientState.setPulsingRow(pulsingNotificationView)
+
+        // When: during AOD to LockScreen, any dozeAmount between (0, 1.0) is equivalent as a middle
+        // stage; here we use 0.5 for testing. The expansionFraction is also 0.5.
+        // stackScrollAlgorithm.resetViewStates is called.
+        ambientState.dozeAmount = 0.5f
+        setExpansionFractionWithoutShelfDuringAodToLockScreen(
+                ambientState,
+                algorithmState,
+                fraction = 0.5f
+        )
+        stackScrollAlgorithm.resetViewStates(ambientState, 0)
+
+        // Then: pulsingNotificationView should show at full height
+        assertEquals(
+                stackScrollAlgorithm.getMaxAllowedChildHeight(pulsingNotificationView),
+                pulsingNotificationView.viewState.height
+        )
+
+        // After: reset dozeAmount and expansionFraction
+        ambientState.dozeAmount = 0f
+        setExpansionFractionWithoutShelfDuringAodToLockScreen(
+                ambientState,
+                algorithmState,
+                fraction = 1f
+        )
+    }
+
     private fun createHunViewMock(
             isShadeOpen: Boolean,
             fullyVisible: Boolean,
@@ -744,6 +832,29 @@
                 headsUpIsVisible = fullyVisible
             }
 
+    private fun createPulsingViewMock(
+    ) =
+            mock<ExpandableNotificationRow>().apply {
+                whenever(this.viewState).thenReturn(ExpandableViewState())
+                whenever(this.showingPulsing()).thenReturn(true)
+            }
+
+    private fun setExpansionFractionWithoutShelfDuringAodToLockScreen(
+            ambientState: AmbientState,
+            algorithmState: StackScrollAlgorithm.StackScrollAlgorithmState,
+            fraction: Float
+    ) {
+        // showingShelf: false
+        algorithmState.firstViewInShelf = null
+        // scrimPadding: 0, because device is on lock screen
+        ambientState.setStatusBarState(StatusBarState.KEYGUARD)
+        ambientState.dozeAmount = 0.0f
+        // set stackEndHeight and stackHeight
+        // ExpansionFractionWithoutShelf == stackHeight / stackEndHeight
+        ambientState.stackEndHeight = 100f
+        ambientState.stackHeight = ambientState.stackEndHeight * fraction
+    }
+
     private fun resetViewStates_expansionChanging_notificationAlphaUpdated(
             expansionFraction: Float,
             expectedAlpha: Float,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index c83769d..fd9f6a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -22,8 +22,6 @@
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
 import static com.android.systemui.statusbar.StatusBarState.SHADE;
 
-import static com.google.common.truth.Truth.assertThat;
-
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.TestCase.fail;
@@ -54,7 +52,6 @@
 import android.app.trust.TrustManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
-import android.content.Intent;
 import android.content.IntentFilter;
 import android.hardware.devicestate.DeviceStateManager;
 import android.hardware.display.AmbientDisplayConfiguration;
@@ -120,6 +117,7 @@
 import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel;
 import com.android.systemui.navigationbar.NavigationBarController;
 import com.android.systemui.notetask.NoteTaskController;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.plugins.PluginDependencyProvider;
 import com.android.systemui.plugins.PluginManager;
@@ -327,6 +325,7 @@
     @Mock private FingerprintManager mFingerprintManager;
     @Captor private ArgumentCaptor<OnBackInvokedCallback> mOnBackInvokedCallback;
     @Mock IPowerManager mPowerManagerService;
+    @Mock ActivityStarter mActivityStarter;
 
     private ShadeController mShadeController;
     private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
@@ -335,6 +334,7 @@
     private final FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
     private final InitController mInitController = new InitController();
     private final DumpManager mDumpManager = new DumpManager();
+    private final ScreenLifecycle mScreenLifecycle = new ScreenLifecycle(mDumpManager);
 
     @Before
     public void setup() throws Exception {
@@ -487,7 +487,7 @@
                 mUserSwitcherController,
                 mBatteryController,
                 mColorExtractor,
-                new ScreenLifecycle(mDumpManager),
+                mScreenLifecycle,
                 mWakefulnessLifecycle,
                 mStatusBarStateController,
                 Optional.of(mBubbles),
@@ -547,13 +547,15 @@
                 mLightRevealScrim,
                 mAlternateBouncerInteractor,
                 mUserTracker,
-                () -> mFingerprintManager
+                () -> mFingerprintManager,
+                mActivityStarter
         ) {
             @Override
             protected ViewRootImpl getViewRootImpl() {
                 return mViewRootImpl;
             }
         };
+        mScreenLifecycle.addObserver(mCentralSurfaces.mScreenObserver);
         mCentralSurfaces.initShadeVisibilityListener();
         when(mViewRootImpl.getOnBackInvokedDispatcher())
                 .thenReturn(mOnBackInvokedDispatcher);
@@ -593,60 +595,6 @@
     }
 
     @Test
-    public void executeRunnableDismissingKeyguard_nullRunnable_showingAndOccluded() {
-        when(mKeyguardStateController.isShowing()).thenReturn(true);
-        when(mKeyguardStateController.isOccluded()).thenReturn(true);
-
-        mCentralSurfaces.executeRunnableDismissingKeyguard(null, null, false, false, false);
-    }
-
-    @Test
-    public void executeRunnableDismissingKeyguard_nullRunnable_showing() {
-        when(mKeyguardStateController.isShowing()).thenReturn(true);
-        when(mKeyguardStateController.isOccluded()).thenReturn(false);
-
-        mCentralSurfaces.executeRunnableDismissingKeyguard(null, null, false, false, false);
-    }
-
-    @Test
-    public void executeRunnableDismissingKeyguard_nullRunnable_notShowing() {
-        when(mKeyguardStateController.isShowing()).thenReturn(false);
-        when(mKeyguardStateController.isOccluded()).thenReturn(false);
-
-        mCentralSurfaces.executeRunnableDismissingKeyguard(null, null, false, false, false);
-    }
-
-    @Test
-    public void executeRunnableDismissingKeyguard_dreaming_notShowing() throws RemoteException {
-        when(mKeyguardStateController.isShowing()).thenReturn(false);
-        when(mKeyguardStateController.isOccluded()).thenReturn(false);
-        when(mKeyguardUpdateMonitor.isDreaming()).thenReturn(true);
-
-        mCentralSurfaces.executeRunnableDismissingKeyguard(() ->  {},
-                /* cancelAction= */ null,
-                /* dismissShade= */ false,
-                /* afterKeyguardGone= */ false,
-                /* deferred= */ false);
-        mUiBgExecutor.runAllReady();
-        verify(mDreamManager, times(1)).awaken();
-    }
-
-    @Test
-    public void executeRunnableDismissingKeyguard_notDreaming_notShowing() throws RemoteException {
-        when(mKeyguardStateController.isShowing()).thenReturn(false);
-        when(mKeyguardStateController.isOccluded()).thenReturn(false);
-        when(mKeyguardUpdateMonitor.isDreaming()).thenReturn(false);
-
-        mCentralSurfaces.executeRunnableDismissingKeyguard(() ->  {},
-                /* cancelAction= */ null,
-                /* dismissShade= */ false,
-                /* afterKeyguardGone= */ false,
-                /* deferred= */ false);
-        mUiBgExecutor.runAllReady();
-        verify(mDreamManager, never()).awaken();
-    }
-
-    @Test
     public void lockscreenStateMetrics_notShowing() {
         // uninteresting state, except that fingerprint must be non-zero
         when(mKeyguardStateController.isOccluded()).thenReturn(false);
@@ -1253,20 +1201,29 @@
     }
 
     @Test
-    public void startActivityDismissingKeyguard_isShowingAndIsOccluded() {
-        when(mKeyguardStateController.isShowing()).thenReturn(true);
-        when(mKeyguardStateController.isOccluded()).thenReturn(true);
-        mCentralSurfaces.startActivityDismissingKeyguard(
-                new Intent(),
-                /* onlyProvisioned = */false,
-                /* dismissShade = */false);
-        ArgumentCaptor<OnDismissAction> onDismissActionCaptor =
-                ArgumentCaptor.forClass(OnDismissAction.class);
-        verify(mStatusBarKeyguardViewManager)
-                .dismissWithAction(onDismissActionCaptor.capture(), any(Runnable.class), eq(true),
-                        eq(null));
-        assertThat(onDismissActionCaptor.getValue().onDismiss()).isFalse();
-        verify(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any(Runnable.class));
+    public void deviceStateChange_unfolded_shadeExpanding_onKeyguard_closesQS() {
+        setFoldedStates(FOLD_STATE_FOLDED);
+        setGoToSleepStates(FOLD_STATE_FOLDED);
+        mCentralSurfaces.setBarStateForTest(KEYGUARD);
+        when(mNotificationPanelViewController.isExpandingOrCollapsing()).thenReturn(true);
+
+        setDeviceState(FOLD_STATE_UNFOLDED);
+        mScreenLifecycle.dispatchScreenTurnedOff();
+
+        verify(mQuickSettingsController).closeQs();
+    }
+
+    @Test
+    public void deviceStateChange_unfolded_shadeExpanded_onKeyguard_closesQS() {
+        setFoldedStates(FOLD_STATE_FOLDED);
+        setGoToSleepStates(FOLD_STATE_FOLDED);
+        mCentralSurfaces.setBarStateForTest(KEYGUARD);
+        when(mNotificationPanelViewController.isShadeFullyExpanded()).thenReturn(true);
+
+        setDeviceState(FOLD_STATE_UNFOLDED);
+        mScreenLifecycle.dispatchScreenTurnedOff();
+
+        verify(mQuickSettingsController).closeQs();
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
index 91c88ce..c886f9b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
@@ -226,31 +226,33 @@
     }
 
     @Test
-    public void batteryStateChanged_healthNotOverheated_outputsFalse() {
+    public void batteryStateChanged_chargingStatusNotLongLife_outputsFalse() {
         Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
-        intent.putExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_GOOD);
+        intent.putExtra(BatteryManager.EXTRA_CHARGING_STATUS,
+                BatteryManager.CHARGING_POLICY_DEFAULT);
 
         mBatteryController.onReceive(getContext(), intent);
 
-        Assert.assertFalse(mBatteryController.isOverheated());
+        Assert.assertFalse(mBatteryController.isBatteryDefender());
     }
 
     @Test
-    public void batteryStateChanged_healthOverheated_outputsTrue() {
+    public void batteryStateChanged_chargingStatusLongLife_outputsTrue() {
         Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
-        intent.putExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_OVERHEAT);
+        intent.putExtra(BatteryManager.EXTRA_CHARGING_STATUS,
+                BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE);
 
         mBatteryController.onReceive(getContext(), intent);
 
-        Assert.assertTrue(mBatteryController.isOverheated());
+        Assert.assertTrue(mBatteryController.isBatteryDefender());
     }
 
     @Test
-    public void batteryStateChanged_noHealthGiven_outputsFalse() {
+    public void batteryStateChanged_noChargingStatusGiven_outputsFalse() {
         Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
 
         mBatteryController.onReceive(getContext(), intent);
 
-        Assert.assertFalse(mBatteryController.isOverheated());
+        Assert.assertFalse(mBatteryController.isBatteryDefender());
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
index 7402b4d..243f881 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
@@ -284,16 +284,8 @@
         assertFalse(mBluetoothControllerImpl.isBluetoothAudioActive());
         assertFalse(mBluetoothControllerImpl.isBluetoothAudioProfileOnly());
 
-        CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
-        mDevices.add(device);
-        when(device.isActiveDevice(BluetoothProfile.HEADSET)).thenReturn(true);
-
-        List<LocalBluetoothProfile> profiles = new ArrayList<>();
-        LocalBluetoothProfile profile = mock(LocalBluetoothProfile.class);
-        profiles.add(profile);
-        when(profile.getProfileId()).thenReturn(BluetoothProfile.HEADSET);
-        when(device.getProfiles()).thenReturn(profiles);
-        when(device.isConnectedProfile(profile)).thenReturn(true);
+        CachedBluetoothDevice device = createBluetoothDevice(
+                BluetoothProfile.HEADSET, /* isConnected= */ true, /* isActive= */ true);
 
         mBluetoothControllerImpl.onAclConnectionStateChanged(device,
                 BluetoothProfile.STATE_CONNECTED);
@@ -304,6 +296,149 @@
     }
 
     @Test
+    public void isBluetoothAudioActive_headsetIsActive_true() {
+        CachedBluetoothDevice device = createBluetoothDevice(
+                BluetoothProfile.HEADSET, /* isConnected= */ true, /* isActive= */ true);
+
+        mBluetoothControllerImpl.onActiveDeviceChanged(device, BluetoothProfile.HEADSET);
+
+        assertThat(mBluetoothControllerImpl.isBluetoothAudioActive()).isTrue();
+    }
+
+    @Test
+    public void isBluetoothAudioActive_a2dpIsActive_true() {
+        CachedBluetoothDevice device = createBluetoothDevice(
+                BluetoothProfile.A2DP, /* isConnected= */ true, /* isActive= */ true);
+
+        mBluetoothControllerImpl.onActiveDeviceChanged(device, BluetoothProfile.A2DP);
+
+        assertThat(mBluetoothControllerImpl.isBluetoothAudioActive()).isTrue();
+    }
+
+    @Test
+    public void isBluetoothAudioActive_hearingAidIsActive_true() {
+        CachedBluetoothDevice device = createBluetoothDevice(
+                BluetoothProfile.HEARING_AID, /* isConnected= */ true, /* isActive= */ true);
+
+        mBluetoothControllerImpl.onActiveDeviceChanged(device, BluetoothProfile.HEARING_AID);
+
+        assertThat(mBluetoothControllerImpl.isBluetoothAudioActive()).isTrue();
+    }
+
+    @Test
+    public void isBluetoothAudioActive_leAudioIsActive_true() {
+        CachedBluetoothDevice device = createBluetoothDevice(
+                BluetoothProfile.LE_AUDIO, /* isConnected= */ true, /* isActive= */ true);
+
+        mBluetoothControllerImpl.onActiveDeviceChanged(device, BluetoothProfile.LE_AUDIO);
+
+        assertThat(mBluetoothControllerImpl.isBluetoothAudioActive()).isTrue();
+    }
+
+    @Test
+    public void isBluetoothAudioActive_otherProfile_false() {
+        CachedBluetoothDevice device = createBluetoothDevice(
+                BluetoothProfile.PAN, /* isConnected= */ true, /* isActive= */ true);
+
+        mBluetoothControllerImpl.onActiveDeviceChanged(device, BluetoothProfile.PAN);
+
+        assertThat(mBluetoothControllerImpl.isBluetoothAudioActive()).isFalse();
+    }
+
+    @Test
+    public void isBluetoothAudioActive_leAudio_butNotActive_false() {
+        CachedBluetoothDevice device = createBluetoothDevice(
+                BluetoothProfile.LE_AUDIO, /* isConnected= */ true, /* isActive= */ false);
+
+        mBluetoothControllerImpl.onActiveDeviceChanged(device, BluetoothProfile.LE_AUDIO);
+
+        assertThat(mBluetoothControllerImpl.isBluetoothAudioActive()).isFalse();
+    }
+
+    @Test
+    public void isBluetoothAudioProfileOnly_noneConnected_false() {
+        CachedBluetoothDevice device1 = createBluetoothDevice(
+                BluetoothProfile.LE_AUDIO, /* isConnected= */ false, /* isActive= */ false);
+        CachedBluetoothDevice device2 = createBluetoothDevice(
+                BluetoothProfile.HEADSET, /* isConnected= */ false, /* isActive= */ false);
+
+        mBluetoothControllerImpl.onDeviceAdded(device1);
+        mBluetoothControllerImpl.onDeviceAdded(device2);
+
+        assertThat(mBluetoothControllerImpl.isBluetoothAudioProfileOnly()).isFalse();
+    }
+
+    /** Regression test for b/278982782. */
+    @Test
+    public void isBluetoothAudioProfileOnly_onlyLeAudioConnected_true() {
+        CachedBluetoothDevice device = createBluetoothDevice(
+                BluetoothProfile.LE_AUDIO, /* isConnected= */ true, /* isActive= */ false);
+
+        mBluetoothControllerImpl.onDeviceAdded(device);
+
+        assertThat(mBluetoothControllerImpl.isBluetoothAudioProfileOnly()).isTrue();
+    }
+
+    @Test
+    public void isBluetoothAudioProfileOnly_onlyHeadsetConnected_true() {
+        CachedBluetoothDevice device = createBluetoothDevice(
+                BluetoothProfile.HEADSET, /* isConnected= */ true, /* isActive= */ false);
+
+        mBluetoothControllerImpl.onDeviceAdded(device);
+
+        assertThat(mBluetoothControllerImpl.isBluetoothAudioProfileOnly()).isTrue();
+    }
+
+    @Test
+    public void isBluetoothAudioProfileOnly_onlyA2dpConnected_true() {
+        CachedBluetoothDevice device = createBluetoothDevice(
+                BluetoothProfile.A2DP, /* isConnected= */ true, /* isActive= */ false);
+
+        mBluetoothControllerImpl.onDeviceAdded(device);
+
+        assertThat(mBluetoothControllerImpl.isBluetoothAudioProfileOnly()).isTrue();
+    }
+
+    @Test
+    public void isBluetoothAudioProfileOnly_onlyHearingAidConnected_true() {
+        CachedBluetoothDevice device = createBluetoothDevice(
+                BluetoothProfile.HEARING_AID, /* isConnected= */ true, /* isActive= */ false);
+
+        mBluetoothControllerImpl.onDeviceAdded(device);
+
+        assertThat(mBluetoothControllerImpl.isBluetoothAudioProfileOnly()).isTrue();
+    }
+
+    @Test
+    public void isBluetoothAudioProfileOnly_multipleAudioOnlyProfilesConnected_true() {
+        CachedBluetoothDevice device1 = createBluetoothDevice(
+                BluetoothProfile.LE_AUDIO, /* isConnected= */ true, /* isActive= */ false);
+        CachedBluetoothDevice device2 = createBluetoothDevice(
+                BluetoothProfile.A2DP, /* isConnected= */ true, /* isActive= */ false);
+        CachedBluetoothDevice device3 = createBluetoothDevice(
+                BluetoothProfile.HEADSET, /* isConnected= */ true, /* isActive= */ false);
+
+        mBluetoothControllerImpl.onDeviceAdded(device1);
+        mBluetoothControllerImpl.onDeviceAdded(device2);
+        mBluetoothControllerImpl.onDeviceAdded(device3);
+
+        assertThat(mBluetoothControllerImpl.isBluetoothAudioProfileOnly()).isTrue();
+    }
+
+    @Test
+    public void isBluetoothAudioProfileOnly_leAudioAndOtherProfileConnected_false() {
+        CachedBluetoothDevice device1 = createBluetoothDevice(
+                BluetoothProfile.LE_AUDIO, /* isConnected= */ true, /* isActive= */ false);
+        CachedBluetoothDevice device2 = createBluetoothDevice(
+                BluetoothProfile.PAN, /* isConnected= */ true, /* isActive= */ false);
+
+        mBluetoothControllerImpl.onDeviceAdded(device1);
+        mBluetoothControllerImpl.onDeviceAdded(device2);
+
+        assertThat(mBluetoothControllerImpl.isBluetoothAudioProfileOnly()).isFalse();
+    }
+
+    @Test
     public void testAddOnMetadataChangedListener_registersListenerOnAdapter() {
         CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
         BluetoothDevice device = mock(BluetoothDevice.class);
@@ -336,4 +471,21 @@
         mBluetoothControllerImpl.onActiveDeviceChanged(null, BluetoothProfile.HEADSET);
         // No assert, just need no crash.
     }
+
+    private CachedBluetoothDevice createBluetoothDevice(
+            int profile, boolean isConnected, boolean isActive) {
+        CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
+        mDevices.add(device);
+        when(device.isActiveDevice(profile)).thenReturn(isActive);
+
+        List<LocalBluetoothProfile> localBluetoothProfiles = new ArrayList<>();
+        LocalBluetoothProfile localBluetoothProfile = mock(LocalBluetoothProfile.class);
+        localBluetoothProfiles.add(localBluetoothProfile);
+        when(device.getProfiles()).thenReturn(localBluetoothProfiles);
+
+        when(localBluetoothProfile.getProfileId()).thenReturn(profile);
+        when(device.isConnectedProfile(localBluetoothProfile)).thenReturn(isConnected);
+
+        return device;
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
index 13a2baa..487d26d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
@@ -114,6 +114,54 @@
     }
 
     @Test
+    public void testShouldHeadsUpBecomePinned_hasFSI_notUnpinned_true() {
+        // Set up NotifEntry with FSI
+        NotificationEntry notifEntry = new NotificationEntryBuilder()
+                .setSbn(createNewNotification(/* id= */ 0))
+                .build();
+        notifEntry.getSbn().getNotification().fullScreenIntent = PendingIntent.getActivity(
+                getContext(), 0, new Intent(getContext(), this.getClass()),
+                PendingIntent.FLAG_MUTABLE_UNAUDITED);
+
+        // Add notifEntry to ANM mAlertEntries map and make it NOT unpinned
+        mHeadsUpManager.showNotification(notifEntry);
+        HeadsUpManager.HeadsUpEntry headsUpEntry =
+                mHeadsUpManager.getHeadsUpEntry(notifEntry.getKey());
+        headsUpEntry.wasUnpinned = false;
+
+        assertTrue(mHeadsUpManager.shouldHeadsUpBecomePinned(notifEntry));
+    }
+
+    @Test
+    public void testShouldHeadsUpBecomePinned_wasUnpinned_false() {
+        // Set up NotifEntry with FSI
+        NotificationEntry notifEntry = new NotificationEntryBuilder()
+                .setSbn(createNewNotification(/* id= */ 0))
+                .build();
+        notifEntry.getSbn().getNotification().fullScreenIntent = PendingIntent.getActivity(
+                getContext(), 0, new Intent(getContext(), this.getClass()),
+                PendingIntent.FLAG_MUTABLE_UNAUDITED);
+
+        // Add notifEntry to ANM mAlertEntries map and make it unpinned
+        mHeadsUpManager.showNotification(notifEntry);
+        HeadsUpManager.HeadsUpEntry headsUpEntry =
+                mHeadsUpManager.getHeadsUpEntry(notifEntry.getKey());
+        headsUpEntry.wasUnpinned = true;
+
+        assertFalse(mHeadsUpManager.shouldHeadsUpBecomePinned(notifEntry));
+    }
+
+    @Test
+    public void testShouldHeadsUpBecomePinned_noFSI_false() {
+        // Set up NotifEntry with no FSI
+        NotificationEntry notifEntry = new NotificationEntryBuilder()
+                .setSbn(createNewNotification(/* id= */ 0))
+                .build();
+
+        assertFalse(mHeadsUpManager.shouldHeadsUpBecomePinned(notifEntry));
+    }
+
+    @Test
     public void testShowNotification_autoDismissesWithAccessibilityTimeout() {
         doReturn(TEST_A11Y_AUTO_DISMISS_TIME).when(mAccessibilityMgr)
                 .getRecommendedTimeoutMillis(anyInt(), anyInt());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/MultiRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/MultiRippleControllerTest.kt
index 056e386..0d19ab1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/MultiRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/MultiRippleControllerTest.kt
@@ -101,52 +101,4 @@
             assertThat(multiRippleView.ripples.size).isEqualTo(0)
         }
     }
-
-    @Test
-    fun play_onFinishesAllRipples_triggersRipplesFinished() {
-        var isTriggered = false
-        val listener =
-            object : MultiRippleController.Companion.RipplesFinishedListener {
-                override fun onRipplesFinish() {
-                    isTriggered = true
-                }
-            }
-        multiRippleController.addRipplesFinishedListener(listener)
-
-        fakeExecutor.execute {
-            multiRippleController.play(RippleAnimation(RippleAnimationConfig(duration = 1000)))
-            multiRippleController.play(RippleAnimation(RippleAnimationConfig(duration = 2000)))
-
-            assertThat(multiRippleView.ripples.size).isEqualTo(2)
-
-            fakeSystemClock.advanceTime(2000L)
-
-            assertThat(multiRippleView.ripples.size).isEqualTo(0)
-            assertThat(isTriggered).isTrue()
-        }
-    }
-
-    @Test
-    fun play_notAllRipplesFinished_doesNotTriggerRipplesFinished() {
-        var isTriggered = false
-        val listener =
-            object : MultiRippleController.Companion.RipplesFinishedListener {
-                override fun onRipplesFinish() {
-                    isTriggered = true
-                }
-            }
-        multiRippleController.addRipplesFinishedListener(listener)
-
-        fakeExecutor.execute {
-            multiRippleController.play(RippleAnimation(RippleAnimationConfig(duration = 1000)))
-            multiRippleController.play(RippleAnimation(RippleAnimationConfig(duration = 2000)))
-
-            assertThat(multiRippleView.ripples.size).isEqualTo(2)
-
-            fakeSystemClock.advanceTime(1000L)
-
-            assertThat(multiRippleView.ripples.size).isEqualTo(1)
-            assertThat(isTriggered).isFalse()
-        }
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
index c7c6b94..98bbb26 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
@@ -24,6 +24,8 @@
 import android.view.WindowManager
 import android.view.accessibility.AccessibilityManager
 import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
+import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dagger.qualifiers.Main
@@ -60,6 +62,9 @@
     private lateinit var fakeWakeLockBuilder: WakeLockFake.Builder
     private lateinit var fakeWakeLock: WakeLockFake
 
+    private lateinit var fakeUiEventLogger: UiEventLoggerFake
+    private lateinit var uiEventLogger: TemporaryViewUiEventLogger
+
     @Mock
     private lateinit var logger: TemporaryViewLogger<ViewInfo>
     @Mock
@@ -87,6 +92,9 @@
         fakeWakeLockBuilder = WakeLockFake.Builder(context)
         fakeWakeLockBuilder.setWakeLock(fakeWakeLock)
 
+        fakeUiEventLogger = UiEventLoggerFake()
+        uiEventLogger = TemporaryViewUiEventLogger(fakeUiEventLogger)
+
         underTest = TestController(
             context,
             logger,
@@ -98,6 +106,7 @@
             powerManager,
             fakeWakeLockBuilder,
             fakeClock,
+            uiEventLogger,
         )
         underTest.start()
     }
@@ -126,6 +135,8 @@
         underTest.displayView(info)
 
         verify(logger).logViewAddition(info)
+        assertThat(fakeUiEventLogger.eventId(0))
+                .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_ADDED.id)
     }
 
     @Test
@@ -1029,6 +1040,9 @@
         verify(logger).logViewRemoval(DEFAULT_ID, reason)
         verify(configurationController).removeCallback(any())
         assertThat(listener.permanentlyRemovedIds).containsExactly(DEFAULT_ID)
+        assertThat(fakeUiEventLogger.logs.size).isEqualTo(1)
+        assertThat(fakeUiEventLogger.eventId(0))
+                .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_ADDED.id)
     }
 
     @Test
@@ -1133,6 +1147,7 @@
         powerManager: PowerManager,
         wakeLockBuilder: WakeLock.Builder,
         systemClock: SystemClock,
+        uiEventLogger: TemporaryViewUiEventLogger,
     ) : TemporaryViewDisplayController<ViewInfo, TemporaryViewLogger<ViewInfo>>(
         context,
         logger,
@@ -1145,6 +1160,7 @@
         R.layout.chipbar,
         wakeLockBuilder,
         systemClock,
+        uiEventLogger,
     ) {
         var mostRecentViewInfo: ViewInfo? = null
 
@@ -1168,6 +1184,7 @@
         override val timeoutMs: Int = TIMEOUT_MS.toInt(),
         override val id: String = DEFAULT_ID,
         override val priority: ViewPriority = ViewPriority.NORMAL,
+        override val instanceId: InstanceId = InstanceId.fakeInstanceId(0),
     ) : TemporaryViewInfo()
 
     inner class Listener : TemporaryViewDisplayController.Listener {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt
index 4514249..38c1a78 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.temporarydisplay
 
 import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.log.LogBuffer
@@ -50,6 +51,7 @@
                 override val priority: ViewPriority = ViewPriority.CRITICAL
                 override val windowTitle: String = "Test Window Title"
                 override val wakeReason: String = "wake reason"
+                override val instanceId: InstanceId = InstanceId.fakeInstanceId(0)
             }
 
         logger.logViewAddition(info)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLoggerTest.kt
new file mode 100644
index 0000000..f707a8da
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLoggerTest.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.temporarydisplay
+
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+
+@SmallTest
+class TemporaryViewUiEventLoggerTest : SysuiTestCase() {
+    private lateinit var uiEventLoggerFake: UiEventLoggerFake
+    private lateinit var logger: TemporaryViewUiEventLogger
+
+    @Before
+    fun setup() {
+        uiEventLoggerFake = UiEventLoggerFake()
+        logger = TemporaryViewUiEventLogger(uiEventLoggerFake)
+    }
+
+    @Test
+    fun testViewAdded() {
+        logger.logViewAdded(InstanceId.fakeInstanceId(123))
+
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+        assertThat(uiEventLoggerFake.eventId(0))
+            .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_ADDED.id)
+    }
+
+    @Test
+    fun testMultipleViewsAdded_differentInstanceIds() {
+        logger.logViewAdded(logger.getNewInstanceId())
+        logger.logViewAdded(logger.getNewInstanceId())
+
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2)
+        assertThat(uiEventLoggerFake.eventId(0))
+            .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_ADDED.id)
+        assertThat(uiEventLoggerFake.eventId(1))
+            .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_ADDED.id)
+        assertThat(uiEventLoggerFake.logs[0].instanceId.id)
+            .isNotEqualTo(uiEventLoggerFake.logs[1].instanceId.id)
+    }
+
+    @Test
+    fun testViewManuallyDismissed() {
+        logger.logViewManuallyDismissed(InstanceId.fakeInstanceId(123))
+
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+        assertThat(uiEventLoggerFake.eventId(0))
+            .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_MANUALLY_DISMISSED.id)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
index 6e24941..03834e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.temporarydisplay.chipbar
 
 import android.os.PowerManager
+import android.os.VibrationAttributes
 import android.os.VibrationEffect
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
@@ -29,6 +30,7 @@
 import android.widget.TextView
 import androidx.core.animation.doOnCancel
 import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
@@ -42,6 +44,8 @@
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.statusbar.VibratorHelper
 import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.temporarydisplay.TemporaryViewUiEvent
+import com.android.systemui.temporarydisplay.TemporaryViewUiEventLogger
 import com.android.systemui.temporarydisplay.ViewPriority
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
@@ -86,6 +90,7 @@
     private lateinit var fakeClock: FakeSystemClock
     private lateinit var fakeExecutor: FakeExecutor
     private lateinit var uiEventLoggerFake: UiEventLoggerFake
+    private lateinit var uiEventLogger: TemporaryViewUiEventLogger
 
     @Before
     fun setUp() {
@@ -100,6 +105,7 @@
         fakeWakeLockBuilder.setWakeLock(fakeWakeLock)
 
         uiEventLoggerFake = UiEventLoggerFake()
+        uiEventLogger = TemporaryViewUiEventLogger(uiEventLoggerFake)
         chipbarAnimator = TestChipbarAnimator()
 
         underTest =
@@ -120,6 +126,7 @@
                 vibratorHelper,
                 fakeWakeLockBuilder,
                 fakeClock,
+                uiEventLogger,
             )
         underTest.start()
     }
@@ -461,7 +468,7 @@
     }
 
     @Test
-    fun displayView_vibrationEffect_doubleClickEffect() {
+    fun displayView_vibrationEffect_doubleClickEffectWithHardwareFeedback() {
         underTest.displayView(
             createChipbarInfo(
                 Icon.Resource(R.id.check_box, null),
@@ -471,7 +478,14 @@
             )
         )
 
-        verify(vibratorHelper).vibrate(VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK))
+        verify(vibratorHelper)
+            .vibrate(
+                any(),
+                any(),
+                eq(VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK)),
+                any(),
+                eq(VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK)),
+            )
     }
 
     /** Regression test for b/266119467. */
@@ -624,7 +638,7 @@
     }
 
     @Test
-    fun swipeToDismiss_swipeOccurs_viewDismissed() {
+    fun swipeToDismiss_swipeOccurs_viewDismissed_manuallyDismissedLogged() {
         underTest.displayView(
             createChipbarInfo(
                 Icon.Resource(R.drawable.ic_cake, contentDescription = null),
@@ -641,6 +655,9 @@
         callbackCaptor.value.invoke(MotionEvent.obtain(0L, 0L, 0, 0f, 0f, 0))
 
         verify(windowManager).removeView(view)
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2)
+        assertThat(uiEventLoggerFake.eventId(1))
+            .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_MANUALLY_DISMISSED.id)
     }
 
     @Test
@@ -657,6 +674,11 @@
         val callbackCaptor = argumentCaptor<(MotionEvent) -> Unit>()
         verify(swipeGestureHandler).addOnGestureDetectedCallback(any(), capture(callbackCaptor))
 
+        // only one log for view addition
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+        assertThat(uiEventLoggerFake.eventId(0))
+            .isEqualTo(TemporaryViewUiEvent.TEMPORARY_VIEW_ADDED.id)
+
         // WHEN the view is updated to not allow swipe-to-dismiss
         underTest.displayView(
             createChipbarInfo(
@@ -675,6 +697,7 @@
 
         // THEN it is ignored and view isn't removed
         verify(windowManager, never()).removeView(view)
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
     }
 
     private fun createChipbarInfo(
@@ -695,6 +718,7 @@
             timeoutMs = TIMEOUT,
             id = DEVICE_ID,
             priority = ViewPriority.NORMAL,
+            instanceId = InstanceId.fakeInstanceId(0),
         )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/CreateUserActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/CreateUserActivityTest.kt
index 2b86cfd..6db35ae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/CreateUserActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/CreateUserActivityTest.kt
@@ -6,6 +6,7 @@
 import androidx.test.ext.junit.rules.ActivityScenarioRule
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.nullable
 import com.android.systemui.util.mockito.whenever
@@ -27,9 +28,7 @@
                         createDialog(
                             /* activity = */ nullable(),
                             /* activityStarter = */ nullable(),
-                            /* oldUserIcon = */ nullable(),
-                            /* defaultUserName = */ nullable(),
-                            /* title = */ nullable(),
+                            /* isMultipleAdminsEnabled = */ any(),
                             /* successCallback = */ nullable(),
                             /* cancelCallback = */ nullable()
                         )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
index d252d53..ca83d49 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
@@ -482,30 +482,17 @@
         }
 
     @Test
-    fun executeAction_addUser_dialogShown() =
+    fun executeAction_addUser_dismissesDialogAndStartsActivity() =
         testScope.runTest {
             val userInfos = createUserInfos(count = 2, includeGuest = false)
             userRepository.setUserInfos(userInfos)
             userRepository.setSelectedUserInfo(userInfos[0])
             keyguardRepository.setKeyguardShowing(false)
-            val dialogRequest = collectLastValue(underTest.dialogShowRequests)
-            val dialogShower: UserSwitchDialogController.DialogShower = mock()
 
-            underTest.executeAction(UserActionModel.ADD_USER, dialogShower)
+            underTest.executeAction(UserActionModel.ADD_USER)
             verify(uiEventLogger, times(1))
                 .log(MultiUserActionsEvent.CREATE_USER_FROM_USER_SWITCHER)
-            assertThat(dialogRequest())
-                .isEqualTo(
-                    ShowDialogRequestModel.ShowAddUserDialog(
-                        userHandle = userInfos[0].userHandle,
-                        isKeyguardShowing = false,
-                        showEphemeralMessage = false,
-                        dialogShower = dialogShower,
-                    )
-                )
-
             underTest.onDialogShown()
-            assertThat(dialogRequest()).isNull()
         }
 
     @Test
@@ -862,7 +849,7 @@
 
             // Dialog is shown.
             assertThat(dialogRequest())
-                    .isEqualTo(ShowDialogRequestModel.ShowUserSwitcherFullscreenDialog(expandable))
+                .isEqualTo(ShowDialogRequestModel.ShowUserSwitcherFullscreenDialog(expandable))
 
             underTest.onDialogShown()
             assertThat(dialogRequest()).isNull()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/TraceUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/TraceUtilsTest.kt
new file mode 100644
index 0000000..6aad0ad
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/TraceUtilsTest.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.util
+
+import android.os.Handler
+import android.os.Looper
+import android.os.Trace.TRACE_TAG_APP
+import android.testing.AndroidTestingRunner
+import android.util.Log
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import org.junit.After
+import org.junit.Assert.assertThrows
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class TraceUtilsTest : SysuiTestCase() {
+
+    companion object {
+        private const val TAG = "TraceUtilsTest"
+        private const val TEST_FAIL_TIMEOUT = 5000L
+
+        // A string that is 128 characters long
+        private const val SECTION_NAME_THATS_TOO_LONG =
+            "123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_" +
+                "123456789_123456789_123456789_123456789_12345678"
+    }
+
+    @Before
+    fun setUp() {
+        // Enable tracing via atrace in order to see the expected IllegalArgumentException. Trace
+        // sections won't run if tracing is disabled.
+        uiDevice.executeShellCommand("atrace --async_start -a com.android.*")
+    }
+
+    @After
+    fun tearDown() {
+        uiDevice.executeShellCommand("atrace --async_stop")
+    }
+
+    @Test
+    fun testLongTraceSection_throws_whenUsingPublicAPI() {
+        // Expects: "java.lang.IllegalArgumentException: sectionName is too long"
+        assertThrows(IllegalArgumentException::class.java) {
+            android.os.Trace.beginSection(SECTION_NAME_THATS_TOO_LONG)
+        }
+    }
+
+    @Test
+    fun testLongTraceSection_doesNotThrow_whenUsingPrivateAPI() {
+        android.os.Trace.traceBegin(TRACE_TAG_APP, SECTION_NAME_THATS_TOO_LONG)
+    }
+
+    @Test
+    @Ignore("b/267482189 - Enable once androidx.tracing >= 1.2.0-beta04")
+    fun testLongTraceSection_doesNotThrow_whenUsingAndroidX() {
+        androidx.tracing.Trace.beginSection(SECTION_NAME_THATS_TOO_LONG)
+    }
+
+    @Test
+    fun testLongTraceSection_doesNotThrow_whenUsingHelper() {
+        traceSection(SECTION_NAME_THATS_TOO_LONG) {
+            Log.v(TAG, "com.android.systemui.util.traceSection() block.")
+        }
+    }
+
+    @Test
+    fun testLongTraceSection_doesNotThrow_whenUsedAsTraceNameSupplier() {
+        Handler(Looper.getMainLooper())
+            .runWithScissors(
+                TraceUtils.namedRunnable(SECTION_NAME_THATS_TOO_LONG) {
+                    Log.v(TAG, "TraceUtils.namedRunnable() block.")
+                },
+                TEST_FAIL_TIMEOUT
+            )
+    }
+
+    @Test
+    fun testLongTraceSection_doesNotThrow_whenUsingTraceRunnable() {
+        TraceUtils.traceRunnable(SECTION_NAME_THATS_TOO_LONG) {
+            Log.v(TAG, "TraceUtils.traceRunnable() block.")
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 45a37cf..8f725be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -35,7 +35,6 @@
 import android.content.res.Configuration;
 import android.media.AudioManager;
 import android.os.SystemClock;
-import android.provider.DeviceConfig;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.Gravity;
@@ -47,7 +46,6 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
@@ -62,9 +60,6 @@
 import com.android.systemui.statusbar.policy.DevicePostureController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.FakeConfigurationController;
-import com.android.systemui.util.DeviceConfigProxyFake;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
 
 import org.junit.After;
 import org.junit.Before;
@@ -88,8 +83,6 @@
     View mDrawerVibrate;
     View mDrawerMute;
     View mDrawerNormal;
-    private DeviceConfigProxyFake mDeviceConfigProxy;
-    private FakeExecutor mExecutor;
     private TestableLooper mTestableLooper;
     private ConfigurationController mConfigurationController;
     private int mOriginalOrientation;
@@ -131,8 +124,6 @@
         getContext().addMockSystemService(KeyguardManager.class, mKeyguard);
 
         mTestableLooper = TestableLooper.get(this);
-        mDeviceConfigProxy = new DeviceConfigProxyFake();
-        mExecutor = new FakeExecutor(new FakeSystemClock());
 
         when(mPostureController.getDevicePosture())
                 .thenReturn(DevicePostureController.DEVICE_POSTURE_CLOSED);
@@ -151,8 +142,6 @@
                 mVolumePanelFactory,
                 mActivityStarter,
                 mInteractionJankMonitor,
-                mDeviceConfigProxy,
-                mExecutor,
                 mCsdWarningDialogFactory,
                 mPostureController,
                 mTestableLooper.getLooper(),
@@ -173,9 +162,6 @@
                 VolumePrefs.SHOW_RINGER_TOAST_COUNT + 1);
 
         Prefs.putBoolean(mContext, Prefs.Key.HAS_SEEN_ODI_CAPTIONS_TOOLTIP, false);
-
-        mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false);
     }
 
     private State createShellState() {
@@ -351,13 +337,8 @@
      * API does not exist. So we do the next best thing; we check the cached icon id.
      */
     @Test
-    public void notificationVolumeSeparated_theRingerIconChanges() {
-        mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false);
-
-        mExecutor.runAllReady(); // for the config change to take effect
-
-        // assert icon is new based on res id
+    public void notificationVolumeSeparated_theRingerIconChangesToSpeakerIcon() {
+        // already separated. assert icon is new based on res id
         assertEquals(mDialog.mVolumeRingerIconDrawableId,
                 R.drawable.ic_speaker_on);
         assertEquals(mDialog.mVolumeRingerMuteIconDrawableId,
@@ -365,17 +346,6 @@
     }
 
     @Test
-    public void notificationVolumeNotSeparated_theRingerIconRemainsTheSame() {
-        mDeviceConfigProxy.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false);
-
-        mExecutor.runAllReady();
-
-        assertEquals(mDialog.mVolumeRingerIconDrawableId, R.drawable.ic_volume_ringer);
-        assertEquals(mDialog.mVolumeRingerMuteIconDrawableId, R.drawable.ic_volume_ringer_mute);
-    }
-
-    @Test
     public void testDialogDismissAnimation_notifyVisibleIsNotCalledBeforeAnimation() {
         mDialog.dismissH(DISMISS_REASON_UNKNOWN);
         // notifyVisible(false) should not be called immediately but only after the dismiss
@@ -408,8 +378,6 @@
                 mVolumePanelFactory,
                 mActivityStarter,
                 mInteractionJankMonitor,
-                mDeviceConfigProxy,
-                mExecutor,
                 mCsdWarningDialogFactory,
                 devicePostureController,
                 mTestableLooper.getLooper(),
@@ -447,8 +415,6 @@
                 mVolumePanelFactory,
                 mActivityStarter,
                 mInteractionJankMonitor,
-                mDeviceConfigProxy,
-                mExecutor,
                 mCsdWarningDialogFactory,
                 devicePostureController,
                 mTestableLooper.getLooper(),
@@ -485,8 +451,6 @@
                 mVolumePanelFactory,
                 mActivityStarter,
                 mInteractionJankMonitor,
-                mDeviceConfigProxy,
-                mExecutor,
                 mCsdWarningDialogFactory,
                 devicePostureController,
                 mTestableLooper.getLooper(),
@@ -525,8 +489,6 @@
                 mVolumePanelFactory,
                 mActivityStarter,
                 mInteractionJankMonitor,
-                mDeviceConfigProxy,
-                mExecutor,
                 mCsdWarningDialogFactory,
                 mPostureController,
                 mTestableLooper.getLooper(),
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt
index 96658c6..d270700 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt
@@ -1,7 +1,7 @@
 package com.android.systemui.biometrics.data.repository
 
 import android.hardware.biometrics.PromptInfo
-import com.android.systemui.biometrics.data.model.PromptKind
+import com.android.systemui.biometrics.shared.model.PromptKind
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.asStateFlow
 
@@ -20,26 +20,32 @@
     private var _challenge = MutableStateFlow<Long?>(null)
     override val challenge = _challenge.asStateFlow()
 
-    private val _kind = MutableStateFlow(PromptKind.ANY_BIOMETRIC)
+    private val _kind = MutableStateFlow<PromptKind>(PromptKind.Biometric())
     override val kind = _kind.asStateFlow()
 
+    private val _isConfirmationRequired = MutableStateFlow(false)
+    override val isConfirmationRequired = _isConfirmationRequired.asStateFlow()
+
     override fun setPrompt(
         promptInfo: PromptInfo,
         userId: Int,
         gatekeeperChallenge: Long?,
-        kind: PromptKind
+        kind: PromptKind,
+        requireConfirmation: Boolean,
     ) {
         _promptInfo.value = promptInfo
         _userId.value = userId
         _challenge.value = gatekeeperChallenge
         _kind.value = kind
+        _isConfirmationRequired.value = requireConfirmation
     }
 
     override fun unsetPrompt() {
         _promptInfo.value = null
         _userId.value = null
         _challenge.value = null
-        _kind.value = PromptKind.ANY_BIOMETRIC
+        _kind.value = PromptKind.Biometric()
+        _isConfirmationRequired.value = false
     }
 
     fun setIsShowing(showing: Boolean) {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricSettingsRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricSettingsRepository.kt
index 65735f0..4aaf347 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricSettingsRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricSettingsRepository.kt
@@ -17,10 +17,13 @@
 
 package com.android.systemui.keyguard.data.repository
 
+import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.keyguard.shared.model.AuthenticationFlags
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.map
 
 class FakeBiometricSettingsRepository : BiometricSettingsRepository {
 
@@ -50,9 +53,12 @@
     override val isFaceAuthSupportedInCurrentPosture: Flow<Boolean>
         get() = _isFaceAuthSupportedInCurrentPosture
 
-    private val _isCurrentUserInLockdown = MutableStateFlow(false)
     override val isCurrentUserInLockdown: Flow<Boolean>
-        get() = _isCurrentUserInLockdown
+        get() = _authFlags.map { it.isInUserLockdown }
+
+    private val _authFlags = MutableStateFlow(AuthenticationFlags(0, 0))
+    override val authenticationFlags: Flow<AuthenticationFlags>
+        get() = _authFlags
 
     fun setFingerprintEnrolled(isFingerprintEnrolled: Boolean) {
         _isFingerprintEnrolled.value = isFingerprintEnrolled
@@ -66,6 +72,10 @@
         _isFingerprintEnabledByDevicePolicy.value = isFingerprintEnabledByDevicePolicy
     }
 
+    fun setAuthenticationFlags(value: AuthenticationFlags) {
+        _authFlags.value = value
+    }
+
     fun setFaceEnrolled(isFaceEnrolled: Boolean) {
         _isFaceEnrolled.value = isFaceEnrolled
     }
@@ -79,7 +89,22 @@
     }
 
     fun setIsUserInLockdown(value: Boolean) {
-        _isCurrentUserInLockdown.value = value
+        if (value) {
+            setAuthenticationFlags(
+                AuthenticationFlags(
+                    _authFlags.value.userId,
+                    _authFlags.value.flag or
+                        LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN
+                )
+            )
+        } else {
+            setAuthenticationFlags(
+                AuthenticationFlags(
+                    _authFlags.value.userId,
+                    LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED
+                )
+            )
+        }
     }
 
     fun setIsNonStrongBiometricAllowed(value: Boolean) {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBouncerMessageRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBouncerMessageRepository.kt
new file mode 100644
index 0000000..b03b4ba
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBouncerMessageRepository.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.data.repository
+
+import com.android.systemui.keyguard.bouncer.data.repository.BouncerMessageRepository
+import com.android.systemui.keyguard.bouncer.shared.model.BouncerMessageModel
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+
+class FakeBouncerMessageRepository : BouncerMessageRepository {
+    private val _primaryAuthMessage = MutableStateFlow<BouncerMessageModel?>(null)
+    override val primaryAuthMessage: StateFlow<BouncerMessageModel?>
+        get() = _primaryAuthMessage
+
+    private val _faceAcquisitionMessage = MutableStateFlow<BouncerMessageModel?>(null)
+    override val faceAcquisitionMessage: StateFlow<BouncerMessageModel?>
+        get() = _faceAcquisitionMessage
+    private val _fingerprintAcquisitionMessage = MutableStateFlow<BouncerMessageModel?>(null)
+    override val fingerprintAcquisitionMessage: StateFlow<BouncerMessageModel?>
+        get() = _fingerprintAcquisitionMessage
+    private val _customMessage = MutableStateFlow<BouncerMessageModel?>(null)
+    override val customMessage: StateFlow<BouncerMessageModel?>
+        get() = _customMessage
+    private val _biometricAuthMessage = MutableStateFlow<BouncerMessageModel?>(null)
+    override val biometricAuthMessage: StateFlow<BouncerMessageModel?>
+        get() = _biometricAuthMessage
+    private val _authFlagsMessage = MutableStateFlow<BouncerMessageModel?>(null)
+    override val authFlagsMessage: StateFlow<BouncerMessageModel?>
+        get() = _authFlagsMessage
+
+    private val _biometricLockedOutMessage = MutableStateFlow<BouncerMessageModel?>(null)
+    override val biometricLockedOutMessage: Flow<BouncerMessageModel?>
+        get() = _biometricLockedOutMessage
+
+    override fun setPrimaryAuthMessage(value: BouncerMessageModel?) {
+        _primaryAuthMessage.value = value
+    }
+
+    override fun setFaceAcquisitionMessage(value: BouncerMessageModel?) {
+        _faceAcquisitionMessage.value = value
+    }
+
+    override fun setFingerprintAcquisitionMessage(value: BouncerMessageModel?) {
+        _fingerprintAcquisitionMessage.value = value
+    }
+
+    override fun setCustomMessage(value: BouncerMessageModel?) {
+        _customMessage.value = value
+    }
+
+    fun setBiometricAuthMessage(value: BouncerMessageModel?) {
+        _biometricAuthMessage.value = value
+    }
+
+    fun setAuthFlagsMessage(value: BouncerMessageModel?) {
+        _authFlagsMessage.value = value
+    }
+
+    fun setBiometricLockedOutMessage(value: BouncerMessageModel?) {
+        _biometricLockedOutMessage.value = value
+    }
+
+    override fun clearMessage() {
+        _primaryAuthMessage.value = null
+        _faceAcquisitionMessage.value = null
+        _fingerprintAcquisitionMessage.value = null
+        _customMessage.value = null
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index fd8c4b8..b52a768 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -147,6 +147,10 @@
         _isAodAvailable.value = isAodAvailable
     }
 
+    fun setDreaming(isDreaming: Boolean) {
+        _isDreaming.value = isDreaming
+    }
+
     fun setDreamingWithOverlay(isDreaming: Boolean) {
         _isDreamingWithOverlay.value = isDreaming
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt
index 1340a47..817e1db 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt
@@ -28,7 +28,7 @@
         get() = _isCurrentUserTrusted
 
     private val _isCurrentUserActiveUnlockAvailable = MutableStateFlow(false)
-    override val isCurrentUserActiveUnlockAvailable: StateFlow<Boolean> =
+    override val isCurrentUserActiveUnlockRunning: StateFlow<Boolean> =
         _isCurrentUserActiveUnlockAvailable.asStateFlow()
 
     private val _isCurrentUserTrustManaged = MutableStateFlow(false)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
new file mode 100644
index 0000000..be3d54a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene
+
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.repository.AuthenticationRepository
+import com.android.systemui.authentication.data.repository.AuthenticationRepositoryImpl
+import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
+import com.android.systemui.bouncer.data.repo.BouncerRepository
+import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
+import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
+import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
+import com.android.systemui.scene.data.model.SceneContainerConfig
+import com.android.systemui.scene.data.repository.SceneContainerRepository
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.SceneKey
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+
+/**
+ * Utilities for creating scene container framework related repositories, interactors, and
+ * view-models for tests.
+ */
+@OptIn(ExperimentalCoroutinesApi::class)
+class SceneTestUtils(
+    test: SysuiTestCase,
+    private val testScope: TestScope? = null,
+) {
+
+    private val context = test.context
+
+    fun fakeSceneContainerRepository(
+        containerConfigurations: Set<SceneContainerConfig> =
+            setOf(
+                fakeSceneContainerConfig(CONTAINER_1),
+                fakeSceneContainerConfig(CONTAINER_2),
+            )
+    ): SceneContainerRepository {
+        return SceneContainerRepository(containerConfigurations)
+    }
+
+    fun fakeSceneKeys(): List<SceneKey> {
+        return listOf(
+            SceneKey.QuickSettings,
+            SceneKey.Shade,
+            SceneKey.Lockscreen,
+            SceneKey.Bouncer,
+            SceneKey.Gone,
+        )
+    }
+
+    fun fakeSceneContainerConfig(
+        name: String,
+        sceneKeys: List<SceneKey> = fakeSceneKeys(),
+    ): SceneContainerConfig {
+        return SceneContainerConfig(
+            name = name,
+            sceneKeys = sceneKeys,
+            initialSceneKey = SceneKey.Lockscreen,
+        )
+    }
+
+    fun sceneInteractor(): SceneInteractor {
+        return SceneInteractor(
+            repository = fakeSceneContainerRepository(),
+        )
+    }
+
+    fun authenticationRepository(): AuthenticationRepository {
+        return AuthenticationRepositoryImpl()
+    }
+
+    fun authenticationInteractor(
+        repository: AuthenticationRepository,
+    ): AuthenticationInteractor {
+        return AuthenticationInteractor(
+            applicationScope = applicationScope(),
+            repository = repository,
+        )
+    }
+
+    private fun applicationScope(): CoroutineScope {
+        return checkNotNull(testScope) {
+                """
+                TestScope not initialized, please create a TestScope and inject it into
+                SceneTestUtils.
+            """
+                    .trimIndent()
+            }
+            .backgroundScope
+    }
+
+    fun bouncerInteractor(
+        authenticationInteractor: AuthenticationInteractor,
+        sceneInteractor: SceneInteractor,
+    ): BouncerInteractor {
+        return BouncerInteractor(
+            applicationScope = applicationScope(),
+            applicationContext = context,
+            repository = BouncerRepository(),
+            authenticationInteractor = authenticationInteractor,
+            sceneInteractor = sceneInteractor,
+            containerName = CONTAINER_1,
+        )
+    }
+
+    fun bouncerViewModel(
+        bouncerInteractor: BouncerInteractor,
+    ): BouncerViewModel {
+        return BouncerViewModel(
+            applicationContext = context,
+            applicationScope = applicationScope(),
+            interactorFactory =
+                object : BouncerInteractor.Factory {
+                    override fun create(containerName: String): BouncerInteractor {
+                        return bouncerInteractor
+                    }
+                },
+            containerName = CONTAINER_1,
+        )
+    }
+
+    fun lockScreenSceneInteractor(
+        authenticationInteractor: AuthenticationInteractor,
+        sceneInteractor: SceneInteractor,
+        bouncerInteractor: BouncerInteractor,
+    ): LockscreenSceneInteractor {
+        return LockscreenSceneInteractor(
+            applicationScope = applicationScope(),
+            authenticationInteractor = authenticationInteractor,
+            bouncerInteractorFactory =
+                object : BouncerInteractor.Factory {
+                    override fun create(containerName: String): BouncerInteractor {
+                        return bouncerInteractor
+                    }
+                },
+            sceneInteractor = sceneInteractor,
+            containerName = CONTAINER_1,
+        )
+    }
+
+    companion object {
+        const val CONTAINER_1 = "container1"
+        const val CONTAINER_2 = "container2"
+    }
+}
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index a324b2f..e89e33f 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -81,7 +81,6 @@
 import android.view.MotionEvent;
 import android.view.SurfaceControl;
 import android.view.View;
-import android.view.WindowInfo;
 import android.view.accessibility.AccessibilityCache;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -103,7 +102,6 @@
 import com.android.server.accessibility.AccessibilityWindowManager.RemoteAccessibilityConnection;
 import com.android.server.accessibility.magnification.MagnificationProcessor;
 import com.android.server.inputmethod.InputMethodManagerInternal;
-import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
 
 import java.io.FileDescriptor;
@@ -2081,7 +2079,7 @@
             IAccessibilityInteractionConnectionCallback callback, int fetchFlags,
             long interrogatingTid) {
         RemoteAccessibilityConnection connection;
-        IBinder activityToken = null;
+        IBinder windowToken = null;
         synchronized (mLock) {
             connection = mA11yWindowManager.getConnectionLocked(userId, resolvedWindowId);
             if (connection == null)  {
@@ -2090,9 +2088,8 @@
             final boolean isA11yFocusAction = (action == ACTION_ACCESSIBILITY_FOCUS)
                     || (action == ACTION_CLEAR_ACCESSIBILITY_FOCUS);
             if (!isA11yFocusAction) {
-                final WindowInfo windowInfo =
-                        mA11yWindowManager.findWindowInfoByIdLocked(resolvedWindowId);
-                if (windowInfo != null) activityToken = windowInfo.activityToken;
+                windowToken = mA11yWindowManager.getWindowTokenForUserAndWindowIdLocked(
+                        userId, resolvedWindowId);
             }
             final AccessibilityWindowInfo a11yWindowInfo =
                     mA11yWindowManager.findA11yWindowInfoByIdLocked(resolvedWindowId);
@@ -2113,9 +2110,8 @@
             if (action == ACTION_CLICK || action == ACTION_LONG_CLICK) {
                 mA11yWindowManager.notifyOutsideTouch(userId, resolvedWindowId);
             }
-            if (activityToken != null) {
-                LocalServices.getService(ActivityTaskManagerInternal.class)
-                        .setFocusedActivity(activityToken);
+            if (windowToken != null) {
+                mWindowManagerService.requestWindowFocus(windowToken);
             }
             if (intConnTracingEnabled()) {
                 logTraceIntConn("performAccessibilityAction",
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/AlwaysOnMagnificationFeatureFlag.java b/services/accessibility/java/com/android/server/accessibility/magnification/AlwaysOnMagnificationFeatureFlag.java
index 93531dd..92fd419 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/AlwaysOnMagnificationFeatureFlag.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/AlwaysOnMagnificationFeatureFlag.java
@@ -16,6 +16,8 @@
 
 package com.android.server.accessibility.magnification;
 
+import android.annotation.NonNull;
+import android.content.Context;
 import android.provider.DeviceConfig;
 
 /**
@@ -29,6 +31,13 @@
     private static final String FEATURE_NAME_ENABLE_ALWAYS_ON_MAGNIFICATION =
             "AlwaysOnMagnifier__enable_always_on_magnifier";
 
+    private @NonNull Context mContext;
+
+    AlwaysOnMagnificationFeatureFlag(@NonNull Context context) {
+        super();
+        mContext = context;
+    }
+
     @Override
     String getNamespace() {
         return NAMESPACE;
@@ -41,6 +50,7 @@
 
     @Override
     boolean getDefaultValue() {
-        return false;
+        return mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_magnification_always_on_enabled);
     }
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
index 9b1c204..87fbee7 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -156,7 +156,7 @@
         mSupportWindowMagnification = context.getPackageManager().hasSystemFeature(
                 FEATURE_WINDOW_MAGNIFICATION);
 
-        mAlwaysOnMagnificationFeatureFlag = new AlwaysOnMagnificationFeatureFlag();
+        mAlwaysOnMagnificationFeatureFlag = new AlwaysOnMagnificationFeatureFlag(context);
         mAlwaysOnMagnificationFeatureFlag.addOnChangedListener(
                 mBackgroundExecutor, mAms::updateAlwaysOnMagnification);
     }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index af5b196..fc758cb 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -761,6 +761,12 @@
     }
 
     // Called by Shell command
+    String getFieldDetectionServiceName(@UserIdInt int userId) {
+        enforceCallingPermissionForManagement();
+        return mFieldClassificationResolver.readServiceName(userId);
+    }
+
+    // Called by Shell command
     boolean setTemporaryDetectionService(@UserIdInt int userId, @NonNull String serviceName,
             int durationMs) {
         Slog.i(mTag, "setTemporaryDetectionService(" + userId + ") to " + serviceName
@@ -903,9 +909,9 @@
     }
 
     /**
-     * Whether the Autofill PCC Classification feature is enabled.
+     * Whether the Autofill PCC Classification feature flag is enabled.
      */
-    public boolean isPccClassificationEnabled() {
+    public boolean isPccClassificationFlagEnabled() {
         synchronized (mFlagLock) {
             return mPccClassificationEnabled;
         }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index d5dcdaf..63a607c 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -1730,6 +1730,23 @@
         return mRemoteFieldClassificationService;
     }
 
+
+    public boolean isPccClassificationEnabled() {
+        boolean result = isPccClassificationEnabledInternal();
+        if (sVerbose) {
+            Slog.v(TAG, "pccEnabled: " + result);
+        }
+        return result;
+    }
+
+    public boolean isPccClassificationEnabledInternal() {
+        boolean flagEnabled = mMaster.isPccClassificationFlagEnabled();
+        if (!flagEnabled) return false;
+        synchronized (mLock) {
+            return getRemoteFieldClassificationServiceLocked() != null;
+        }
+    }
+
     /**
      * Called when the {@link AutofillManagerService#mFieldClassificationResolver}
      * changed (among other places).
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
index 62a2970..cd6de87 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
@@ -26,6 +26,7 @@
 import android.os.ShellCommand;
 import android.os.UserHandle;
 import android.service.autofill.AutofillFieldClassificationService.Scores;
+import android.text.TextUtils;
 import android.view.autofill.AutofillManager;
 
 import com.android.internal.os.IResultReceiver;
@@ -154,6 +155,8 @@
                 return getBindInstantService(pw);
             case "default-augmented-service-enabled":
                 return getDefaultAugmentedServiceEnabled(pw);
+            case "field-detection-service-enabled":
+                return isFieldDetectionServiceEnabled(pw);
             case "saved-password-count":
                 return getSavedPasswordCount(pw);
             default:
@@ -343,6 +346,15 @@
         return 0;
     }
 
+    private int isFieldDetectionServiceEnabled(PrintWriter pw) {
+        final int userId = getNextIntArgRequired();
+        String name = mService.getFieldDetectionServiceName(userId);
+        boolean pccFlagEnabled = mService.isPccClassificationFlagEnabled();
+        boolean enabled = (!TextUtils.isEmpty(name)) && pccFlagEnabled;
+        pw.println(enabled);
+        return 0;
+    }
+
     private int setTemporaryAugmentedService(PrintWriter pw) {
         final int userId = getNextIntArgRequired();
         final String serviceName = getNextArg();
diff --git a/services/autofill/java/com/android/server/autofill/FillRequestEventLogger.java b/services/autofill/java/com/android/server/autofill/FillRequestEventLogger.java
index 06a616c..994802d 100644
--- a/services/autofill/java/com/android/server/autofill/FillRequestEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/FillRequestEventLogger.java
@@ -74,9 +74,6 @@
     public static final int TRIGGER_REASON_SERVED_FROM_CACHED_RESPONSE =
             AUTOFILL_FILL_REQUEST_REPORTED__REQUEST_TRIGGER_REASON__TRIGGER_REASON_SERVED_FROM_CACHED_RESPONSE;
 
-    // Augmented autofill currently doesn't have an assigned request_id, use -2 as the magic number.
-    public static final int AUGMENTED_AUTOFILL_REQUEST_ID = -2;
-
     private final int mSessionId;
     private Optional<FillRequestEventInternal> mEventInternal;
 
diff --git a/services/autofill/java/com/android/server/autofill/FillResponseEventLogger.java b/services/autofill/java/com/android/server/autofill/FillResponseEventLogger.java
index 8f2ab71..a69e33a 100644
--- a/services/autofill/java/com/android/server/autofill/FillResponseEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/FillResponseEventLogger.java
@@ -16,17 +16,23 @@
 
 package com.android.server.autofill;
 
+import static android.service.autofill.Dataset.PICK_REASON_PCC_DETECTION_ONLY;
+import static android.service.autofill.Dataset.PICK_REASON_PCC_DETECTION_PREFERRED_WITH_PROVIDER;
+
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED;
-import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__DIALOG;
-import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__INLINE;
-import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__MENU;
-import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__UNKNOWN_AUTOFILL_DISPLAY_PRESENTATION_TYPE;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_FAILURE;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_RESULT_UNKNOWN;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_SUCCESS;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_TYPE__AUTHENTICATION_TYPE_UNKNOWN;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_TYPE__DATASET_AUTHENTICATION;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__AUTHENTICATION_TYPE__FULL_AUTHENTICATION;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_AUTOFILL_PROVIDER;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_PCC;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_UNKONWN;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__DIALOG;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__INLINE;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__MENU;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__UNKNOWN_AUTOFILL_DISPLAY_PRESENTATION_TYPE;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__RESPONSE_STATUS__RESPONSE_STATUS_CANCELLED;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__RESPONSE_STATUS__RESPONSE_STATUS_FAILURE;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__RESPONSE_STATUS__RESPONSE_STATUS_SESSION_DESTROYED;
@@ -37,6 +43,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.Nullable;
+import android.os.SystemClock;
 import android.service.autofill.Dataset;
 import android.util.Slog;
 import android.view.autofill.AutofillId;
@@ -54,6 +61,9 @@
 public final class FillResponseEventLogger {
   private static final String TAG = "FillResponseEventLogger";
 
+  private static final long UNINITIALIZED_TIMESTAMP = -1;
+  private long startResponseProcessingTimestamp = UNINITIALIZED_TIMESTAMP;
+
   /**
    * Reasons why presentation was not shown. These are wrappers around
    * {@link com.android.os.AtomsProto.AutofillFillRequestReported.RequestTriggerReason}.
@@ -111,6 +121,20 @@
   public @interface AuthenticationResult {
   }
 
+
+  /**
+   * Reasons why presentation was not shown. These are wrappers around
+   * {@link com.android.os.AtomsProto.AutofillFillResponseReported.DetectionPreference}.
+   */
+  @IntDef(prefix = {"DETECTION_PREFER"}, value = {
+      DETECTION_PREFER_UNKNOWN,
+      DETECTION_PREFER_AUTOFILL_PROVIDER,
+      DETECTION_PREFER_PCC
+  })
+  @Retention(RetentionPolicy.SOURCE)
+  public @interface DetectionPreference {
+  }
+
   public static final int DISPLAY_PRESENTATION_TYPE_UNKNOWN =
       AUTOFILL_FILL_RESPONSE_REPORTED__DISPLAY_PRESENTATION_TYPE__UNKNOWN_AUTOFILL_DISPLAY_PRESENTATION_TYPE;
   public static final int DISPLAY_PRESENTATION_TYPE_MENU =
@@ -145,6 +169,15 @@
   public static final int RESPONSE_STATUS_UNKNOWN =
       AUTOFILL_FILL_RESPONSE_REPORTED__RESPONSE_STATUS__RESPONSE_STATUS_UNKNOWN;
 
+  // Values for AutofillFillResponseReported.detection_preference
+  public static final int DETECTION_PREFER_UNKNOWN =
+          AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_UNKONWN;
+  public static final int DETECTION_PREFER_AUTOFILL_PROVIDER =
+          AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_AUTOFILL_PROVIDER;
+  public static final int DETECTION_PREFER_PCC =
+          AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_PCC;
+
+
   // Log a magic number when FillRequest failed or timeout to differentiate with FillRequest
   // succeeded.
   public static final int AVAILABLE_COUNT_WHEN_FILL_REQUEST_FAILED_OR_TIMEOUT = -1;
@@ -222,6 +255,21 @@
     });
   }
 
+  public void maybeSetTotalDatasetsProvided(int val) {
+    mEventInternal.ifPresent(event -> {
+      // Don't reset if it's already populated.
+      // This is just a technical limitation of not having complicated logic.
+      // Autofill Provider may return some datasets which are applicable to data types.
+      // In such a case, we set available count to the number of datasets provided.
+      // However, it's possible that those data types aren't detected by PCC, so in effect, there
+      // are 0 datasets. In the codebase, we treat it as null response, which may call this again
+      // to set 0. But we don't want to overwrite already set value.
+      if (event.mTotalDatasetsProvided == -1) {
+        event.mTotalDatasetsProvided = val;
+      }
+    });
+  }
+
   private static int getDatasetCountForAutofillId(@Nullable List<Dataset> datasetList,
       AutofillId currentViewId) {
     int availableCount = 0;
@@ -309,15 +357,78 @@
     });
   }
 
+  public void startResponseProcessingTime() {
+    startResponseProcessingTimestamp = SystemClock.elapsedRealtime();
+  }
+
   /**
    * Set latency_response_processing_millis as long as mEventInternal presents.
    */
-  public void maybeSetLatencyResponseProcessingMillis(int val) {
+  public void maybeSetLatencyResponseProcessingMillis() {
     mEventInternal.ifPresent(event -> {
-      event.mLatencyResponseProcessingMillis = val;
+      if (startResponseProcessingTimestamp == UNINITIALIZED_TIMESTAMP && sVerbose) {
+        Slog.v(TAG, "uninitialized startResponseProcessingTimestamp");
+      }
+      event.mLatencyResponseProcessingMillis
+              = SystemClock.elapsedRealtime() - startResponseProcessingTimestamp;
     });
   }
 
+  /**
+   * Set available_pcc_count.
+   */
+  public void maybeSetAvailablePccCount(int val) {
+    mEventInternal.ifPresent(event -> {
+      event.mAvailablePccCount = val;
+    });
+  }
+
+  /**
+   * Set available_pcc_only_count.
+   */
+  public void maybeSetAvailablePccOnlyCount(int val) {
+    mEventInternal.ifPresent(event -> {
+      event.mAvailablePccOnlyCount = val;
+    });
+  }
+
+  /**
+   * Set available_pcc_count.
+   */
+  public void maybeSetDatasetsCountAfterPotentialPccFiltering(@Nullable List<Dataset> datasetList) {
+    mEventInternal.ifPresent(event -> {
+      int pccOnlyCount = 0;
+      int pccCount = 0;
+      int totalCount = 0;
+      if (datasetList != null) {
+        totalCount = datasetList.size();
+        for (int i = 0; i < datasetList.size(); i++) {
+          Dataset dataset = datasetList.get(i);
+          if (dataset != null) {
+            if (dataset.getEligibleReason() == PICK_REASON_PCC_DETECTION_ONLY) {
+              pccOnlyCount++;
+              pccCount++;
+            } else if (dataset.getEligibleReason()
+                    == PICK_REASON_PCC_DETECTION_PREFERRED_WITH_PROVIDER) {
+              pccCount++;
+            }
+          }
+        }
+      }
+      event.mAvailablePccOnlyCount = pccOnlyCount;
+      event.mAvailablePccCount = pccCount;
+      event.mAvailableCount = totalCount;
+    });
+  }
+
+  /**
+   * Set detection_pref
+   */
+  public void maybeSetDetectionPreference(@DetectionPreference int detectionPreference) {
+    mEventInternal.ifPresent(event -> {
+      event.mDetectionPref = detectionPreference;
+    });
+  }
 
   /**
    * Log an AUTOFILL_FILL_RESPONSE_REPORTED event.
@@ -344,7 +455,11 @@
           + " mLatencyAuthenticationUiDisplayMillis=" + event.mLatencyAuthenticationUiDisplayMillis
           + " mLatencyDatasetDisplayMillis=" + event.mLatencyDatasetDisplayMillis
           + " mResponseStatus=" + event.mResponseStatus
-          + " mLatencyResponseProcessingMillis=" + event.mLatencyResponseProcessingMillis);
+          + " mLatencyResponseProcessingMillis=" + event.mLatencyResponseProcessingMillis
+          + " mAvailablePccCount=" + event.mAvailablePccCount
+          + " mAvailablePccOnlyCount=" + event.mAvailablePccOnlyCount
+          + " mTotalDatasetsProvided=" + event.mTotalDatasetsProvided
+          + " mDetectionPref=" + event.mDetectionPref);
     }
     FrameworkStatsLog.write(
         AUTOFILL_FILL_RESPONSE_REPORTED,
@@ -361,7 +476,11 @@
         event.mLatencyAuthenticationUiDisplayMillis,
         event.mLatencyDatasetDisplayMillis,
         event.mResponseStatus,
-        event.mLatencyResponseProcessingMillis);
+        event.mLatencyResponseProcessingMillis,
+        event.mAvailablePccCount,
+        event.mAvailablePccOnlyCount,
+        event.mTotalDatasetsProvided,
+        event.mDetectionPref);
     mEventInternal = Optional.empty();
   }
 
@@ -371,14 +490,19 @@
     int mDisplayPresentationType = DISPLAY_PRESENTATION_TYPE_UNKNOWN;
     int mAvailableCount = 0;
     int mSaveUiTriggerIds = -1;
-    int mLatencyFillResponseReceivedMillis = 0;
+    int mLatencyFillResponseReceivedMillis = (int) UNINITIALIZED_TIMESTAMP;
     int mAuthenticationType = AUTHENTICATION_TYPE_UNKNOWN;
     int mAuthenticationResult = AUTHENTICATION_RESULT_UNKNOWN;
     int mAuthenticationFailureReason = -1;
-    int mLatencyAuthenticationUiDisplayMillis = 0;
-    int mLatencyDatasetDisplayMillis = 0;
+    int mLatencyAuthenticationUiDisplayMillis = (int) UNINITIALIZED_TIMESTAMP;
+    int mLatencyDatasetDisplayMillis = (int) UNINITIALIZED_TIMESTAMP;
     int mResponseStatus = RESPONSE_STATUS_UNKNOWN;
-    int mLatencyResponseProcessingMillis = 0;
+    long mLatencyResponseProcessingMillis = UNINITIALIZED_TIMESTAMP;
+    int mAvailablePccCount = -1;
+    int mAvailablePccOnlyCount = -1;
+    int mTotalDatasetsProvided = -1;
+    @DetectionPreference
+    int mDetectionPref = DETECTION_PREFER_UNKNOWN;
 
     FillResponseEventInternal() {
     }
diff --git a/services/autofill/java/com/android/server/autofill/InlineSuggestionRendorInfoCallbackOnResultListener.java b/services/autofill/java/com/android/server/autofill/InlineSuggestionRendorInfoCallbackOnResultListener.java
new file mode 100644
index 0000000..7351ef5
--- /dev/null
+++ b/services/autofill/java/com/android/server/autofill/InlineSuggestionRendorInfoCallbackOnResultListener.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.autofill;
+
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+import android.util.Slog;
+import android.view.autofill.AutofillId;
+import android.view.inputmethod.InlineSuggestionsRequest;
+
+import java.lang.ref.WeakReference;
+import java.util.function.Consumer;
+
+final class InlineSuggestionRendorInfoCallbackOnResultListener implements
+        RemoteCallback.OnResultListener{
+    private static final String TAG = "InlineSuggestionRendorInfoCallbackOnResultListener";
+
+    private final int mRequestIdCopy;
+    private final AutofillId mFocusedId;
+    private final WeakReference<Session> mSessionWeakReference;
+    private final Consumer<InlineSuggestionsRequest> mInlineSuggestionsRequestConsumer;
+
+    InlineSuggestionRendorInfoCallbackOnResultListener(WeakReference<Session> sessionWeakReference,
+            int requestIdCopy,
+            Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestConsumer,
+            AutofillId focusedId) {
+        this.mRequestIdCopy = requestIdCopy;
+        this.mInlineSuggestionsRequestConsumer = inlineSuggestionsRequestConsumer;
+        this.mSessionWeakReference = sessionWeakReference;
+        this.mFocusedId = focusedId;
+    }
+    public void onResult(@Nullable Bundle result) {
+        Session session = this.mSessionWeakReference.get();
+        if (session == null) {
+            Slog.wtf(TAG, "Session is null before trying to call onResult");
+            return;
+        }
+        synchronized (session.mLock) {
+            if (session.mDestroyed) {
+                Slog.wtf(TAG, "Session is destroyed before trying to call onResult");
+                return;
+            }
+            session.mInlineSessionController.onCreateInlineSuggestionsRequestLocked(
+                    this.mFocusedId,
+                    session.inlineSuggestionsRequestCacheDecorator(
+                        this.mInlineSuggestionsRequestConsumer, this.mRequestIdCopy),
+                    result);
+        }
+    }
+}
diff --git a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
index ca743cb..11b45db 100644
--- a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
@@ -25,6 +25,9 @@
 import static android.view.autofill.AutofillManager.COMMIT_REASON_VIEW_CLICKED;
 import static android.view.autofill.AutofillManager.COMMIT_REASON_VIEW_COMMITTED;
 
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_AUTOFILL_PROVIDER;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_PCC;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_UNKONWN;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_FAILURE;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_RESULT_UNKNOWN;
@@ -46,6 +49,12 @@
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_CHANGED;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_FOCUSED_BEFORE_FILL_DIALOG_RESPONSE;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_FOCUS_CHANGED;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__SELECTED_DATASET_PICKED_REASON__PICK_REASON_NO_PCC;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__SELECTED_DATASET_PICKED_REASON__PICK_REASON_PCC_DETECTION_ONLY;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__SELECTED_DATASET_PICKED_REASON__PICK_REASON_PCC_DETECTION_PREFERRED_WITH_PROVIDER;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__SELECTED_DATASET_PICKED_REASON__PICK_REASON_PROVIDER_DETECTION_ONLY;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__SELECTED_DATASET_PICKED_REASON__PICK_REASON_PROVIDER_DETECTION_PREFERRED_WITH_PCC;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__SELECTED_DATASET_PICKED_REASON__PICK_REASON_UNKNOWN;
 import static com.android.server.autofill.Helper.sVerbose;
 
 import android.annotation.IntDef;
@@ -116,6 +125,35 @@
     public @interface AuthenticationResult {
     }
 
+    /**
+     * Reasons why the picked dataset was present. These are wrappers around
+     * {@link com.android.os.AtomsProto.AutofillPresentationEventReported.DatasetPickedReason}.
+     * This enum is similar to {@link android.service.autofill.Dataset.DatasetEligibleReason}
+     */
+    @IntDef(prefix = {"PICK_REASON"}, value = {
+            PICK_REASON_UNKNOWN,
+            PICK_REASON_NO_PCC,
+            PICK_REASON_PROVIDER_DETECTION_ONLY,
+            PICK_REASON_PROVIDER_DETECTION_PREFERRED_WITH_PCC,
+            PICK_REASON_PCC_DETECTION_ONLY,
+            PICK_REASON_PCC_DETECTION_PREFERRED_WITH_PROVIDER,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DatasetPickedReason {}
+
+    /**
+     * The type of detection that was preferred. These are wrappers around
+     * {@link com.android.os.AtomsProto.AutofillPresentationEventReported.DetectionPreference}.
+     */
+    @IntDef(prefix = {"DETECTION_PREFER"}, value = {
+            DETECTION_PREFER_UNKNOWN,
+            DETECTION_PREFER_AUTOFILL_PROVIDER,
+            DETECTION_PREFER_PCC
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DetectionPreference {
+    }
+
     public static final int NOT_SHOWN_REASON_ANY_SHOWN =
             AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__ANY_SHOWN;
     public static final int NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED =
@@ -151,6 +189,27 @@
     public static final int AUTHENTICATION_RESULT_FAILURE =
             AUTOFILL_PRESENTATION_EVENT_REPORTED__AUTHENTICATION_RESULT__AUTHENTICATION_FAILURE;
 
+    public static final int PICK_REASON_UNKNOWN =
+            AUTOFILL_PRESENTATION_EVENT_REPORTED__SELECTED_DATASET_PICKED_REASON__PICK_REASON_UNKNOWN;
+    public static final int PICK_REASON_NO_PCC =
+            AUTOFILL_PRESENTATION_EVENT_REPORTED__SELECTED_DATASET_PICKED_REASON__PICK_REASON_NO_PCC;
+     public static final int PICK_REASON_PROVIDER_DETECTION_ONLY =
+             AUTOFILL_PRESENTATION_EVENT_REPORTED__SELECTED_DATASET_PICKED_REASON__PICK_REASON_PROVIDER_DETECTION_ONLY;
+    public static final int PICK_REASON_PROVIDER_DETECTION_PREFERRED_WITH_PCC =
+            AUTOFILL_PRESENTATION_EVENT_REPORTED__SELECTED_DATASET_PICKED_REASON__PICK_REASON_PROVIDER_DETECTION_PREFERRED_WITH_PCC;
+    public static final int PICK_REASON_PCC_DETECTION_ONLY =
+            AUTOFILL_PRESENTATION_EVENT_REPORTED__SELECTED_DATASET_PICKED_REASON__PICK_REASON_PCC_DETECTION_ONLY;
+    public static final int PICK_REASON_PCC_DETECTION_PREFERRED_WITH_PROVIDER =
+            AUTOFILL_PRESENTATION_EVENT_REPORTED__SELECTED_DATASET_PICKED_REASON__PICK_REASON_PCC_DETECTION_PREFERRED_WITH_PROVIDER;
+
+
+    // Values for AutofillFillResponseReported.detection_preference
+    public static final int DETECTION_PREFER_UNKNOWN =
+            AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_UNKONWN;
+    public static final int DETECTION_PREFER_AUTOFILL_PROVIDER =
+            AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_AUTOFILL_PROVIDER;
+    public static final int DETECTION_PREFER_PCC =
+            AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_PCC;
     private final int mSessionId;
     private Optional<PresentationStatsEventInternal> mEventInternal;
 
@@ -194,36 +253,61 @@
     public void maybeSetAvailableCount(@Nullable List<Dataset> datasetList,
             AutofillId currentViewId) {
         mEventInternal.ifPresent(event -> {
-            int availableCount = getDatasetCountForAutofillId(datasetList, currentViewId);
-            event.mAvailableCount = availableCount;
-            event.mIsDatasetAvailable = availableCount > 0;
+            CountContainer container = getDatasetCountForAutofillId(datasetList, currentViewId);
+            event.mAvailableCount = container.mAvailableCount;
+            event.mAvailablePccCount = container.mAvailablePccCount;
+            event.mAvailablePccOnlyCount = container.mAvailablePccOnlyCount;
+            event.mIsDatasetAvailable = container.mAvailableCount > 0;
         });
     }
 
     public void maybeSetCountShown(@Nullable List<Dataset> datasetList,
             AutofillId currentViewId) {
         mEventInternal.ifPresent(event -> {
-            int countShown = getDatasetCountForAutofillId(datasetList, currentViewId);
-            event.mCountShown = countShown;
-            if (countShown > 0) {
+            CountContainer container = getDatasetCountForAutofillId(datasetList, currentViewId);
+            event.mCountShown = container.mAvailableCount;
+            if (container.mAvailableCount > 0) {
                 event.mNoPresentationReason = NOT_SHOWN_REASON_ANY_SHOWN;
             }
         });
     }
 
-    private static int getDatasetCountForAutofillId(@Nullable List<Dataset> datasetList,
+    private static CountContainer getDatasetCountForAutofillId(@Nullable List<Dataset> datasetList,
             AutofillId currentViewId) {
-        int availableCount = 0;
+
+        CountContainer container = new CountContainer();
         if (datasetList != null) {
             for (int i = 0; i < datasetList.size(); i++) {
                 Dataset data = datasetList.get(i);
                 if (data != null && data.getFieldIds() != null
                         && data.getFieldIds().contains(currentViewId)) {
-                    availableCount += 1;
+                    container.mAvailableCount += 1;
+                    if (data.getEligibleReason() == PICK_REASON_PCC_DETECTION_ONLY) {
+                        container.mAvailablePccOnlyCount++;
+                        container.mAvailablePccCount++;
+                    } else if (data.getEligibleReason()
+                            == PICK_REASON_PCC_DETECTION_PREFERRED_WITH_PROVIDER) {
+                        container.mAvailablePccCount++;
+                    }
                 }
             }
         }
-        return availableCount;
+        return container;
+    }
+
+    private static class CountContainer{
+        int mAvailableCount = 0;
+        int mAvailablePccCount = 0;
+        int mAvailablePccOnlyCount = 0;
+
+        CountContainer() {}
+
+        CountContainer(int availableCount, int availablePccCount,
+                int availablePccOnlyCount) {
+            mAvailableCount = availableCount;
+            mAvailablePccCount = availablePccCount;
+            mAvailablePccOnlyCount = availablePccOnlyCount;
+        }
     }
 
     public void maybeSetCountFilteredUserTyping(int countFilteredUserTyping) {
@@ -375,6 +459,55 @@
         });
     }
 
+    /**
+     * Set available_pcc_count.
+     */
+    public void maybeSetAvailablePccCount(int val) {
+        mEventInternal.ifPresent(event -> {
+            event.mAvailablePccCount = val;
+        });
+    }
+
+    /**
+     * Set available_pcc_only_count.
+     */
+    public void maybeSetAvailablePccOnlyCount(int val) {
+        mEventInternal.ifPresent(event -> {
+            event.mAvailablePccOnlyCount = val;
+        });
+    }
+
+    /**
+     * Set selected_dataset_picked_reason.
+     */
+    public void maybeSetSelectedDatasetPickReason(@Dataset.DatasetEligibleReason int val) {
+        mEventInternal.ifPresent(event -> {
+            event.mSelectedDatasetPickedReason = convertDatasetPickReason(val);
+        });
+    }
+
+    /**
+     * Set detection_pref
+     */
+    public void maybeSetDetectionPreference(@DetectionPreference int detectionPreference) {
+        mEventInternal.ifPresent(event -> {
+            event.mDetectionPreference = detectionPreference;
+        });
+    }
+
+    private int convertDatasetPickReason(@Dataset.DatasetEligibleReason int val) {
+        switch (val) {
+            case 0:
+            case 1:
+            case 2:
+            case 3:
+            case 4:
+            case 5:
+                return val;
+        }
+        return PICK_REASON_UNKNOWN;
+    }
+
 
     public void logAndEndEvent() {
         if (!mEventInternal.isPresent()) {
@@ -410,7 +543,11 @@
                     + " mAuthenticationResult=" + event.mAuthenticationResult
                     + " mLatencyAuthenticationUiDisplayMillis="
                     + event.mLatencyAuthenticationUiDisplayMillis
-                    + " mLatencyDatasetDisplayMillis=" + event.mLatencyDatasetDisplayMillis);
+                    + " mLatencyDatasetDisplayMillis=" + event.mLatencyDatasetDisplayMillis
+                    + " mAvailablePccCount=" + event.mAvailablePccCount
+                    + " mAvailablePccOnlyCount=" + event.mAvailablePccOnlyCount
+                    + " mSelectedDatasetPickedReason=" + event.mSelectedDatasetPickedReason
+                    + " mDetectionPreference=" + event.mDetectionPreference);
         }
 
         // TODO(b/234185326): Distinguish empty responses from other no presentation reasons.
@@ -443,7 +580,11 @@
                 event.mAuthenticationType,
                 event.mAuthenticationResult,
                 event.mLatencyAuthenticationUiDisplayMillis,
-                event.mLatencyDatasetDisplayMillis);
+                event.mLatencyDatasetDisplayMillis,
+                event.mAvailablePccCount,
+                event.mAvailablePccOnlyCount,
+                event.mSelectedDatasetPickedReason,
+                event.mDetectionPreference);
         mEventInternal = Optional.empty();
     }
 
@@ -472,6 +613,10 @@
         int mAuthenticationResult = AUTHENTICATION_RESULT_UNKNOWN;
         int mLatencyAuthenticationUiDisplayMillis = -1;
         int mLatencyDatasetDisplayMillis = -1;
+        int mAvailablePccCount = -1;
+        int mAvailablePccOnlyCount = -1;
+        @DatasetPickedReason int mSelectedDatasetPickedReason = PICK_REASON_UNKNOWN;
+        @DetectionPreference int mDetectionPreference = DETECTION_PREFER_UNKNOWN;
 
         PresentationStatsEventInternal() {}
     }
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java b/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java
index b8bac61..ea31074 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java
@@ -28,6 +28,7 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
+import android.os.Build;
 import android.os.ICancellationSignal;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -155,7 +156,19 @@
                                     public void onSuccess(FieldClassificationResponse response) {
                                         logLatency(startTime);
                                         if (sDebug) {
-                                            Log.d(TAG, "onSuccess Response: " + response);
+                                            if (Build.IS_DEBUGGABLE) {
+                                                Slog.d(TAG, "onSuccess Response: " + response);
+                                            } else {
+                                                String msg = "";
+                                                if (response == null
+                                                        || response.getClassifications() == null) {
+                                                    msg = "null response";
+                                                } else {
+                                                    msg = "size: "
+                                                            + response.getClassifications().size();
+                                                }
+                                                Slog.d(TAG, "onSuccess " + msg);
+                                            }
                                         }
                                         fieldClassificationServiceCallbacks
                                                 .onClassificationRequestSuccess(response);
@@ -165,7 +178,7 @@
                                     public void onFailure() {
                                         logLatency(startTime);
                                         if (sDebug) {
-                                            Log.d(TAG, "onFailure");
+                                            Slog.d(TAG, "onFailure");
                                         }
                                         fieldClassificationServiceCallbacks
                                                 .onClassificationRequestFailure(0, null);
diff --git a/services/autofill/java/com/android/server/autofill/SaveEventLogger.java b/services/autofill/java/com/android/server/autofill/SaveEventLogger.java
index e5435c2..28e8e30 100644
--- a/services/autofill/java/com/android/server/autofill/SaveEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/SaveEventLogger.java
@@ -252,6 +252,15 @@
   }
 
   /**
+   * Set is_framework_created_save_info as long as mEventInternal presents.
+   */
+  public void maybeSetIsFrameworkCreatedSaveInfo(boolean val) {
+    mEventInternal.ifPresent(event -> {
+      event.mIsFrameworkCreatedSaveInfo = val;
+    });
+  }
+
+  /**
    * Log an AUTOFILL_SAVE_EVENT_REPORTED event.
    */
   public void logAndEndEvent() {
@@ -277,7 +286,8 @@
           + " mIsSaved=" + event.mIsSaved
           + " mLatencySaveUiDisplayMillis=" + event.mLatencySaveUiDisplayMillis
           + " mLatencySaveRequestMillis=" + event.mLatencySaveRequestMillis
-          + " mLatencySaveFinishMillis=" + event.mLatencySaveFinishMillis);
+          + " mLatencySaveFinishMillis=" + event.mLatencySaveFinishMillis
+          + " mIsFrameworkCreatedSaveInfo=" + event.mIsFrameworkCreatedSaveInfo);
     }
     FrameworkStatsLog.write(
         AUTOFILL_SAVE_EVENT_REPORTED,
@@ -295,7 +305,8 @@
         event.mIsSaved,
         event.mLatencySaveUiDisplayMillis,
         event.mLatencySaveRequestMillis,
-        event.mLatencySaveFinishMillis);
+        event.mLatencySaveFinishMillis,
+        event.mIsFrameworkCreatedSaveInfo);
     mEventInternal = Optional.empty();
   }
 
@@ -314,6 +325,7 @@
     long mLatencySaveUiDisplayMillis = 0;
     long mLatencySaveRequestMillis = 0;
     long mLatencySaveFinishMillis = 0;
+    boolean mIsFrameworkCreatedSaveInfo = false;
 
     SaveEventInternal() {
     }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index c4c1750..44c5033 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -19,6 +19,12 @@
 import static android.Manifest.permission.PROVIDE_OWN_AUTOFILL_SUGGESTIONS;
 import static android.service.autofill.AutofillFieldClassificationService.EXTRA_SCORES;
 import static android.service.autofill.AutofillService.EXTRA_FILL_RESPONSE;
+import static android.service.autofill.Dataset.PICK_REASON_NO_PCC;
+import static android.service.autofill.Dataset.PICK_REASON_PCC_DETECTION_ONLY;
+import static android.service.autofill.Dataset.PICK_REASON_PCC_DETECTION_PREFERRED_WITH_PROVIDER;
+import static android.service.autofill.Dataset.PICK_REASON_PROVIDER_DETECTION_ONLY;
+import static android.service.autofill.Dataset.PICK_REASON_PROVIDER_DETECTION_PREFERRED_WITH_PCC;
+import static android.service.autofill.Dataset.PICK_REASON_UNKNOWN;
 import static android.service.autofill.FillEventHistory.Event.UI_TYPE_DIALOG;
 import static android.service.autofill.FillEventHistory.Event.UI_TYPE_INLINE;
 import static android.service.autofill.FillEventHistory.Event.UI_TYPE_MENU;
@@ -36,6 +42,7 @@
 import static android.view.autofill.AutofillManager.ACTION_VALUE_CHANGED;
 import static android.view.autofill.AutofillManager.ACTION_VIEW_ENTERED;
 import static android.view.autofill.AutofillManager.ACTION_VIEW_EXITED;
+import static android.view.autofill.AutofillManager.COMMIT_REASON_SESSION_DESTROYED;
 import static android.view.autofill.AutofillManager.COMMIT_REASON_UNKNOWN;
 import static android.view.autofill.AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM;
 import static android.view.autofill.AutofillManager.getSmartSuggestionModeToString;
@@ -45,6 +52,9 @@
 import static com.android.server.autofill.FillRequestEventLogger.TRIGGER_REASON_PRE_TRIGGER;
 import static com.android.server.autofill.FillRequestEventLogger.TRIGGER_REASON_SERVED_FROM_CACHED_RESPONSE;
 import static com.android.server.autofill.FillResponseEventLogger.AVAILABLE_COUNT_WHEN_FILL_REQUEST_FAILED_OR_TIMEOUT;
+import static com.android.server.autofill.FillResponseEventLogger.DETECTION_PREFER_AUTOFILL_PROVIDER;
+import static com.android.server.autofill.FillResponseEventLogger.DETECTION_PREFER_UNKNOWN;
+import static com.android.server.autofill.FillResponseEventLogger.DETECTION_PREFER_PCC;
 import static com.android.server.autofill.FillResponseEventLogger.HAVE_SAVE_TRIGGER_ID;
 import static com.android.server.autofill.FillResponseEventLogger.RESPONSE_STATUS_FAILURE;
 import static com.android.server.autofill.FillResponseEventLogger.RESPONSE_STATUS_SESSION_DESTROYED;
@@ -79,7 +89,6 @@
 import static com.android.server.autofill.SaveEventLogger.SAVE_UI_SHOWN_REASON_REQUIRED_ID_CHANGE;
 import static com.android.server.autofill.SaveEventLogger.SAVE_UI_SHOWN_REASON_TRIGGER_ID_SET;
 import static com.android.server.autofill.SaveEventLogger.SAVE_UI_SHOWN_REASON_UNKNOWN;
-import static com.android.server.autofill.SessionCommittedEventLogger.COMMIT_REASON_SESSION_DESTROYED;
 import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
 import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
 
@@ -124,6 +133,7 @@
 import android.service.autofill.AutofillService;
 import android.service.autofill.CompositeUserData;
 import android.service.autofill.Dataset;
+import android.service.autofill.Dataset.DatasetEligibleReason;
 import android.service.autofill.FieldClassification;
 import android.service.autofill.FieldClassification.Match;
 import android.service.autofill.FieldClassificationUserData;
@@ -174,6 +184,7 @@
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -214,6 +225,7 @@
     private static final String EXTRA_REQUEST_ID = "android.service.autofill.extra.REQUEST_ID";
 
     private static final String PCC_HINTS_DELIMITER = ",";
+    public static final String EXTRA_KEY_DETECTIONS = "detections";
 
     final Object mLock;
 
@@ -311,7 +323,7 @@
      * Id of the View currently being displayed.
      */
     @GuardedBy("mLock")
-    @Nullable private AutofillId mCurrentViewId;
+    @Nullable AutofillId mCurrentViewId;
 
     @GuardedBy("mLock")
     private IAutoFillManagerClient mClient;
@@ -359,7 +371,7 @@
     private Bundle mClientState;
 
     @GuardedBy("mLock")
-    private boolean mDestroyed;
+    boolean mDestroyed;
 
     /**
      * Helper used to handle state of Save UI when it must be hiding to show a custom description
@@ -438,7 +450,7 @@
     private ArrayList<AutofillId> mAugmentedAutofillableIds;
 
     @NonNull
-    private final AutofillInlineSessionController mInlineSessionController;
+    final AutofillInlineSessionController mInlineSessionController;
 
     /**
      * Receiver of assist data from the app's {@link Activity}.
@@ -798,7 +810,7 @@
      * Returns empty list if PCC is off or no types available
     */
     private List<String> getTypeHintsForProvider() {
-        if (!mService.getMaster().isPccClassificationEnabled()) {
+        if (!mService.isPccClassificationEnabled()) {
             return Collections.EMPTY_LIST;
         }
         final String typeHints = mService.getMaster().getPccProviderHints();
@@ -1158,7 +1170,7 @@
             }
             mSessionFlags.mAugmentedAutofillOnly = true;
             mFillRequestEventLogger.maybeSetRequestId(AUGMENTED_AUTOFILL_REQUEST_ID);
-            mFillRequestEventLogger.maybeSetIsAugmented(mSessionFlags.mAugmentedAutofillOnly);
+            mFillRequestEventLogger.maybeSetIsAugmented(true);
             mFillRequestEventLogger.logAndEndEvent();
             triggerAugmentedAutofillLocked(flags);
             return;
@@ -1200,7 +1212,7 @@
         // structure is taken. This causes only one fill request per burst of focus changes.
         cancelCurrentRequestLocked();
 
-        if (mService.getMaster().isPccClassificationEnabled()
+        if (mService.isPccClassificationEnabled()
                 && mClassificationState.mHintsToAutofillIdMap == null) {
             if (sVerbose) {
                 Slog.v(TAG, "triggering field classification");
@@ -1214,24 +1226,30 @@
         final RemoteInlineSuggestionRenderService remoteRenderService =
                 mService.getRemoteInlineSuggestionRenderServiceLocked();
         if (mSessionFlags.mInlineSupportedByService
-            && remoteRenderService != null
-            && (isViewFocusedLocked(flags) || isRequestSupportFillDialog(flags))) {
+                && remoteRenderService != null
+                && (isViewFocusedLocked(flags) || isRequestSupportFillDialog(flags))) {
+
             Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestConsumer =
                 mAssistReceiver.newAutofillRequestLocked(viewState,
                     /* isInlineRequest= */ true);
+
             if (inlineSuggestionsRequestConsumer != null) {
-                final AutofillId focusedId = mCurrentViewId;
                 final int requestIdCopy = requestId;
+                final AutofillId focusedId = mCurrentViewId;
+
+                WeakReference sessionWeakReference = new WeakReference<Session>(this);
+                InlineSuggestionRendorInfoCallbackOnResultListener
+                        inlineSuggestionRendorInfoCallbackOnResultListener =
+                                new InlineSuggestionRendorInfoCallbackOnResultListener(
+                                        sessionWeakReference,
+                                        requestIdCopy,
+                                        inlineSuggestionsRequestConsumer,
+                                        focusedId);
+                RemoteCallback inlineSuggestionRendorInfoCallback = new RemoteCallback(
+                        inlineSuggestionRendorInfoCallbackOnResultListener, mHandler);
+
                 remoteRenderService.getInlineSuggestionsRendererInfo(
-                        new RemoteCallback((extras) -> {
-                            synchronized (mLock) {
-                                mInlineSessionController.onCreateInlineSuggestionsRequestLocked(
-                                        focusedId, inlineSuggestionsRequestCacheDecorator(
-                                                inlineSuggestionsRequestConsumer, requestIdCopy),
-                                        extras);
-                            }
-                        }, mHandler)
-                );
+                        inlineSuggestionRendorInfoCallback);
                 viewState.setState(ViewState.STATE_PENDING_CREATE_INLINE_REQUEST);
             }
         } else {
@@ -1453,6 +1471,7 @@
         mFillResponseEventLogger.maybeSetRequestId(requestId);
         mFillResponseEventLogger.maybeSetAppPackageUid(uid);
         mFillResponseEventLogger.maybeSetResponseStatus(RESPONSE_STATUS_SUCCESS);
+        mFillResponseEventLogger.startResponseProcessingTime();
         // Time passed since session was created
         final long fillRequestReceivedRelativeTimestamp =
             SystemClock.elapsedRealtime() - mLatencyBaseTime;
@@ -1460,6 +1479,7 @@
             (int) (fillRequestReceivedRelativeTimestamp));
         mFillResponseEventLogger.maybeSetLatencyFillResponseReceivedMillis(
             (int) (fillRequestReceivedRelativeTimestamp));
+        mFillResponseEventLogger.maybeSetDetectionPreference(getDetectionPreferenceForLogging());
 
         synchronized (mLock) {
             if (mDestroyed) {
@@ -1478,6 +1498,7 @@
                 Slog.w(TAG, "onFillRequestSuccess(): no request log for id " + requestId);
             }
             if (response == null) {
+                mFillResponseEventLogger.maybeSetTotalDatasetsProvided(0);
                 if (requestLog != null) {
                     requestLog.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, -1);
                 }
@@ -1554,9 +1575,8 @@
                 Slog.d(TAG, message.toString());
             }
         }
-
-        if (((response.getDatasets() == null || response.getDatasets().isEmpty())
-                        && response.getAuthentication() == null)
+        List<Dataset> datasetList = response.getDatasets();
+        if (((datasetList == null || datasetList.isEmpty()) && response.getAuthentication() == null)
                 || autofillDisabled) {
             // Response is "empty" from a UI point of view, need to notify client.
             notifyUnavailableToClient(
@@ -1578,10 +1598,16 @@
             }
         }
 
+        int datasetCount = (datasetList == null) ? 0 : datasetList.size();
+        mFillResponseEventLogger.maybeSetTotalDatasetsProvided(datasetCount);
+        // It's possible that this maybe overwritten later on after PCC filtering.
+        mFillResponseEventLogger.maybeSetAvailableCount(datasetCount);
+
         // TODO(b/266379948): Ideally wait for PCC request to finish for a while more
         // (say 100ms) before proceeding further on.
 
         processResponseLockedForPcc(response, response.getClientState(), requestFlags);
+        mFillResponseEventLogger.maybeSetLatencyResponseProcessingMillis();
     }
 
 
@@ -1631,7 +1657,7 @@
             Slog.d(TAG, "DBG: computeDatasetsForProviderAndUpdateContainer: "
                     + autofillProviderContainer);
         }
-        if (!mService.getMaster().isPccClassificationEnabled())  {
+        if (!mService.isPccClassificationEnabled())  {
             if (sVerbose) {
                 Slog.v(TAG, "PCC classification is disabled");
             }
@@ -1728,6 +1754,7 @@
             }
             if (ids.isEmpty()) return saveInfo;
             AutofillId[] autofillIds = new AutofillId[ids.size()];
+            mSaveEventLogger.maybeSetIsFrameworkCreatedSaveInfo(true);
             ids.toArray(autofillIds);
             return SaveInfo.copy(saveInfo, autofillIds);
         }
@@ -1798,6 +1825,13 @@
 
     private void computeDatasetsForProviderAndUpdateContainer(
             FillResponse response, DatasetComputationContainer container) {
+        @DatasetEligibleReason int globalPickReason = PICK_REASON_UNKNOWN;
+        boolean isPccEnabled = mService.isPccClassificationEnabled();
+        if (isPccEnabled) {
+            globalPickReason = PICK_REASON_PROVIDER_DETECTION_ONLY;
+        } else {
+            globalPickReason = PICK_REASON_NO_PCC;
+        }
         List<Dataset> datasets = response.getDatasets();
         if (datasets == null) return;
         ArrayMap<AutofillId, Set<Dataset>> autofillIdToDatasetMap = new ArrayMap<>();
@@ -1805,6 +1839,7 @@
         Set<AutofillId> eligibleAutofillIds = new ArraySet<>();
         for (Dataset dataset : response.getDatasets()) {
             if (dataset.getFieldIds() == null || dataset.getFieldIds().isEmpty()) continue;
+            @DatasetEligibleReason int pickReason = globalPickReason;
             if (dataset.getAutofillDatatypes() != null
                     && !dataset.getAutofillDatatypes().isEmpty()) {
                 // This dataset has information relevant for detection too, so we should filter
@@ -1827,6 +1862,7 @@
                 if (newSize == 0) continue;
 
                 if (conversionRequired) {
+                    pickReason = PICK_REASON_PROVIDER_DETECTION_PREFERRED_WITH_PCC;
                     ArrayList<AutofillId> fieldIds = new ArrayList<>(newSize);
                     ArrayList<AutofillValue> fieldValues = new ArrayList<>(newSize);
                     ArrayList<RemoteViews> fieldPresentations = new ArrayList<>(newSize);
@@ -1870,6 +1906,7 @@
                                     dataset.getAuthentication());
                 }
             }
+            dataset.setEligibleReasonReason(pickReason);
             eligibleDatasets.add(dataset);
             for (AutofillId id : dataset.getFieldIds()) {
                 eligibleAutofillIds.add(id);
@@ -1905,6 +1942,8 @@
             Set<AutofillId> eligibleAutofillIds = new ArraySet<>();
 
             for (int i = 0; i < datasets.size(); i++) {
+
+                @DatasetEligibleReason int pickReason = PICK_REASON_PCC_DETECTION_ONLY;
                 Dataset dataset = datasets.get(i);
                 if (dataset.getAutofillDatatypes() == null
                         || dataset.getAutofillDatatypes().isEmpty()) continue;
@@ -1919,7 +1958,12 @@
                 Set<AutofillId> datasetAutofillIds = new ArraySet<>();
 
                 for (int j = 0; j < dataset.getAutofillDatatypes().size(); j++) {
-                    if (dataset.getAutofillDatatypes().get(j) == null) continue;
+                    if (dataset.getAutofillDatatypes().get(j) == null) {
+                        if (dataset.getFieldIds() != null && dataset.getFieldIds().get(j) != null) {
+                            pickReason = PICK_REASON_PCC_DETECTION_PREFERRED_WITH_PROVIDER;
+                        }
+                        continue;
+                    }
                     String hint = dataset.getAutofillDatatypes().get(j);
 
                     if (hintsToAutofillIdMap.containsKey(hint)) {
@@ -1966,6 +2010,7 @@
                                 null,
                                 dataset.getId(),
                                 dataset.getAuthentication());
+                newDataset.setEligibleReasonReason(pickReason);
                 eligibleDatasets.add(newDataset);
                 Set<Dataset> newDatasets;
                 for (AutofillId autofillId : datasetAutofillIds) {
@@ -2008,7 +2053,10 @@
         mFillResponseEventLogger.maybeSetRequestId(requestId);
         mFillResponseEventLogger.maybeSetAppPackageUid(uid);
         mFillResponseEventLogger.maybeSetAvailableCount(
-            AVAILABLE_COUNT_WHEN_FILL_REQUEST_FAILED_OR_TIMEOUT);
+                AVAILABLE_COUNT_WHEN_FILL_REQUEST_FAILED_OR_TIMEOUT);
+        mFillResponseEventLogger.maybeSetTotalDatasetsProvided(
+                AVAILABLE_COUNT_WHEN_FILL_REQUEST_FAILED_OR_TIMEOUT);
+        mFillResponseEventLogger.maybeSetDetectionPreference(getDetectionPreferenceForLogging());
         final long fillRequestReceivedRelativeTimestamp =
             SystemClock.elapsedRealtime() - mLatencyBaseTime;
         mFillResponseEventLogger.maybeSetLatencyFillResponseReceivedMillis(
@@ -2229,7 +2277,6 @@
     @Override
     public void save() {
         synchronized (mLock) {
-            mSaveEventLogger.maybeSetSaveButtonClicked(true);
             if (mDestroyed) {
                 Slog.w(TAG, "Call to Session#save() rejected - session: "
                         + id + " destroyed");
@@ -2248,7 +2295,6 @@
     public void cancelSave() {
         synchronized (mLock) {
             mSessionFlags.mShowingSaveUi = false;
-            mSaveEventLogger.maybeSetDialogDismissed(true);
             if (mDestroyed) {
                 Slog.w(TAG, "Call to Session#cancelSave() rejected - session: "
                         + id + " destroyed");
@@ -2707,6 +2753,7 @@
         mHandler.sendMessage(obtainMessage(Session::handleLogContextCommitted, this,
                 Event.NO_SAVE_UI_REASON_NONE,
                 COMMIT_REASON_UNKNOWN));
+        logAllEvents(COMMIT_REASON_UNKNOWN);
     }
 
     /**
@@ -2720,6 +2767,7 @@
             @AutofillCommitReason int commitReason) {
         mHandler.sendMessage(obtainMessage(Session::handleLogContextCommitted, this,
                 saveDialogNotShowReason, commitReason));
+        logAllEvents(commitReason);
     }
 
     private void handleLogContextCommitted(@NoSaveReason int saveDialogNotShowReason,
@@ -2951,6 +2999,7 @@
                 changedFieldIds, changedDatasetIds, manuallyFilledFieldIds,
                 manuallyFilledDatasetIds, detectedFieldIds, detectedFieldClassifications,
                 mComponentName, mCompatMode, saveDialogNotShowReason);
+        logAllEvents(commitReason);
     }
 
     /**
@@ -3403,7 +3452,7 @@
                 getUiForShowing().showSaveUi(serviceLabel, serviceIcon,
                         mService.getServicePackageName(), saveInfo, this,
                         mComponentName, this, mContext,  mPendingSaveUi, isUpdate, mCompatMode,
-                        response.getShowSaveDialogIcon());
+                        response.getShowSaveDialogIcon(), mSaveEventLogger);
                 mSaveEventLogger.maybeSetLatencySaveUiDisplayMillis(
                     SystemClock.elapsedRealtime()- saveUiDisplayStartTimestamp);
                 if (client != null) {
@@ -3605,6 +3654,17 @@
 
         final ArrayList<FillContext> contexts = mergePreviousSessionLocked( /* forSave= */ true);
 
+        FieldClassificationResponse fieldClassificationResponse =
+                mClassificationState.mLastFieldClassificationResponse;
+        if (mService.isPccClassificationEnabled()
+                && fieldClassificationResponse != null
+                && !fieldClassificationResponse.getClassifications().isEmpty()) {
+            if (mClientState == null) {
+                mClientState = new Bundle();
+            }
+            mClientState.putParcelableArrayList(EXTRA_KEY_DETECTIONS, new ArrayList<>(
+                    fieldClassificationResponse.getClassifications()));
+        }
         final SaveRequest saveRequest =
                 new SaveRequest(contexts, mClientState, mSelectedDatasetIds);
         mRemoteFillService.onSaveRequest(saveRequest);
@@ -3858,8 +3918,7 @@
                 // View is triggering autofill.
                 mCurrentViewId = viewState.id;
                 viewState.update(value, virtualBounds, flags);
-                mPresentationStatsEventLogger.startNewEvent();
-                mPresentationStatsEventLogger.maybeSetAutofillServiceUid(getAutofillServiceUid());
+                startNewEventForPresentationStatsEventLogger();
                 mPresentationStatsEventLogger.maybeSetIsNewRequest(true);
                 if (!isRequestSupportFillDialog(flags)) {
                     mSessionFlags.mFillDialogDisabled = true;
@@ -3992,9 +4051,7 @@
                 }
                 // If previous request was FillDialog request, a logger event was already started
                 if (!wasPreviouslyFillDialog) {
-                    mPresentationStatsEventLogger.startNewEvent();
-                    mPresentationStatsEventLogger.maybeSetAutofillServiceUid(
-                            getAutofillServiceUid());
+                    startNewEventForPresentationStatsEventLogger();
                 }
                 if (requestNewFillResponseOnViewEnteredIfNecessaryLocked(id, viewState, flags)) {
                     // If a new request was issued even if previously it was fill dialog request,
@@ -4003,9 +4060,7 @@
                     // lock guarded, we should be safe.
                     if (wasPreviouslyFillDialog) {
                         mPresentationStatsEventLogger.logAndEndEvent();
-                        mPresentationStatsEventLogger.startNewEvent();
-                        mPresentationStatsEventLogger.maybeSetAutofillServiceUid(
-                                getAutofillServiceUid());
+                        startNewEventForPresentationStatsEventLogger();
                     }
                     return;
                 }
@@ -4015,8 +4070,6 @@
                     mPresentationStatsEventLogger.maybeSetRequestId(response.getRequestId());
                     mPresentationStatsEventLogger.maybeSetAvailableCount(
                             response.getDatasets(), mCurrentViewId);
-                    mFillResponseEventLogger.maybeSetAvailableCount(
-                        response.getDatasets(), mCurrentViewId);
                 }
 
                 if (isSameViewEntered) {
@@ -4388,7 +4441,7 @@
 
         getUiForShowing().showFillDialog(filledId, response, filterText,
                 mService.getServicePackageName(), mComponentName, serviceIcon, this,
-                id, mCompatMode);
+                id, mCompatMode, mPresentationStatsEventLogger);
         return true;
     }
 
@@ -4707,6 +4760,7 @@
             autofillableIds = null;
         }
         // Log the existing FillResponse event.
+        mFillResponseEventLogger.maybeSetAvailableCount(0);
         mFillResponseEventLogger.logAndEndEvent();
         mService.resetLastResponse();
 
@@ -4818,6 +4872,7 @@
         mFillRequestEventLogger.maybeSetAppPackageUid(uid);
         mFillRequestEventLogger.maybeSetFlags(mFlags);
         mFillRequestEventLogger.maybeSetRequestId(AUGMENTED_AUTOFILL_REQUEST_ID);
+        mFillRequestEventLogger.maybeSetIsAugmented(true);
         mFillRequestEventLogger.logAndEndEvent();
 
         final ViewState viewState = mViewStates.get(mCurrentViewId);
@@ -4934,10 +4989,10 @@
         mResponses.put(requestId, newResponse);
         mClientState = newClientState != null ? newClientState : newResponse.getClientState();
 
-        mPresentationStatsEventLogger.maybeSetAvailableCount(
-                newResponse.getDatasets(), mCurrentViewId);
-        mFillResponseEventLogger.maybeSetAvailableCount(
-            newResponse.getDatasets(), mCurrentViewId);
+        List<Dataset> datasetList = newResponse.getDatasets();
+
+        mPresentationStatsEventLogger.maybeSetAvailableCount(datasetList, mCurrentViewId);
+        mFillResponseEventLogger.maybeSetDatasetsCountAfterPotentialPccFiltering(datasetList);
 
         setViewStatesLocked(newResponse, ViewState.STATE_FILLABLE, false);
         updateFillDialogTriggerIdsLocked();
@@ -5057,11 +5112,14 @@
                         + id + " destroyed");
                 return;
             }
+            // Selected dataset id is logged regardless of authentication result.
+            mPresentationStatsEventLogger.maybeSetSelectedDatasetId(datasetIndex);
+            mPresentationStatsEventLogger.maybeSetSelectedDatasetPickReason(
+                dataset.getEligibleReason());
             // Autofill it directly...
             if (dataset.getAuthentication() == null) {
                 if (generateEvent) {
                     mService.logDatasetSelected(dataset.getId(), id, mClientState, uiType);
-                    mPresentationStatsEventLogger.maybeSetSelectedDatasetId(datasetIndex);
                 }
                 if (mCurrentViewId != null) {
                     mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId);
@@ -5112,7 +5170,7 @@
     }
 
     @NonNull
-    private Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestCacheDecorator(
+    Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestCacheDecorator(
             @NonNull Consumer<InlineSuggestionsRequest> consumer, int requestId) {
         return inlineSuggestionsRequest -> {
             consumer.accept(inlineSuggestionsRequest);
@@ -5122,6 +5180,25 @@
         };
     }
 
+    private int getDetectionPreferenceForLogging() {
+        if (mService.isPccClassificationEnabled()) {
+            if (mService.getMaster().preferProviderOverPcc()) {
+                return DETECTION_PREFER_AUTOFILL_PROVIDER;
+            }
+            return DETECTION_PREFER_PCC;
+        }
+        return DETECTION_PREFER_UNKNOWN;
+    }
+
+    private void startNewEventForPresentationStatsEventLogger() {
+        synchronized (mLock) {
+            mPresentationStatsEventLogger.startNewEvent();
+            mPresentationStatsEventLogger.maybeSetDetectionPreference(
+                    getDetectionPreferenceForLogging());
+            mPresentationStatsEventLogger.maybeSetAutofillServiceUid(getAutofillServiceUid());
+        }
+    }
+
     private void startAuthentication(int authenticationId, IntentSender intent,
             Intent fillInIntent, boolean authenticateInline) {
         try {
@@ -5655,6 +5732,19 @@
         }
     }
 
+    @GuardedBy("mLock")
+    private void logAllEvents(@AutofillCommitReason int val) {
+        mSessionCommittedEventLogger.maybeSetCommitReason(val);
+        mSessionCommittedEventLogger.maybeSetRequestCount(mRequestCount);
+        mSessionCommittedEventLogger.maybeSetSessionDurationMillis(
+            SystemClock.elapsedRealtime() - mStartTime);
+        mFillRequestEventLogger.logAndEndEvent();
+        mFillResponseEventLogger.logAndEndEvent();
+        mPresentationStatsEventLogger.logAndEndEvent();
+        mSaveEventLogger.logAndEndEvent();
+        mSessionCommittedEventLogger.logAndEndEvent();
+    }
+
     /**
      * Destroy this session and perform any clean up work.
      *
@@ -5669,15 +5759,7 @@
     @GuardedBy("mLock")
     RemoteFillService destroyLocked() {
         // Log unlogged events.
-        mSessionCommittedEventLogger.maybeSetCommitReason(COMMIT_REASON_SESSION_DESTROYED);
-        mSessionCommittedEventLogger.maybeSetRequestCount(mRequestCount);
-        mSessionCommittedEventLogger.maybeSetSessionDurationMillis(
-            SystemClock.elapsedRealtime() - mStartTime);
-        mSessionCommittedEventLogger.logAndEndEvent();
-        mPresentationStatsEventLogger.logAndEndEvent();
-        mSaveEventLogger.logAndEndEvent();
-        mFillResponseEventLogger.logAndEndEvent();
-        mFillRequestEventLogger.logAndEndEvent();
+        logAllEvents(COMMIT_REASON_SESSION_DESTROYED);
 
         if (mDestroyed) {
             return null;
diff --git a/services/autofill/java/com/android/server/autofill/SessionCommittedEventLogger.java b/services/autofill/java/com/android/server/autofill/SessionCommittedEventLogger.java
index 541ec80..cd37073 100644
--- a/services/autofill/java/com/android/server/autofill/SessionCommittedEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/SessionCommittedEventLogger.java
@@ -16,13 +16,8 @@
 
 package com.android.server.autofill;
 
+import static android.view.autofill.AutofillManager.COMMIT_REASON_UNKNOWN;
 import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SESSION_COMMITTED;
-import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SESSION_COMMITTED__COMMIT_REASON__COMMIT_REASON_ACTIVITY_FINISHED;
-import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SESSION_COMMITTED__COMMIT_REASON__COMMIT_REASON_SESSION_DESTROYED;
-import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SESSION_COMMITTED__COMMIT_REASON__COMMIT_REASON_UNKNOWN;
-import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SESSION_COMMITTED__COMMIT_REASON__COMMIT_REASON_VIEW_CHANGED;
-import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SESSION_COMMITTED__COMMIT_REASON__COMMIT_REASON_VIEW_CLICKED;
-import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_SESSION_COMMITTED__COMMIT_REASON__COMMIT_REASON_VIEW_COMMITTED;
 import static com.android.server.autofill.Helper.sVerbose;
 
 import android.annotation.IntDef;
@@ -32,7 +27,7 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Slog;
-
+import android.view.autofill.AutofillManager.AutofillCommitReason;
 import com.android.internal.util.FrameworkStatsLog;
 
 import java.lang.annotation.Retention;
@@ -45,35 +40,6 @@
 public final class SessionCommittedEventLogger {
   private static final String TAG = "SessionCommittedEventLogger";
 
-  /**
-   * Reasons why presentation was not shown. These are wrappers around
-   * {@link com.android.os.AtomsProto.AutofillSessionCommitted.AutofillCommitReason}.
-   */
-  @IntDef(prefix = {"COMMIT_REASON"}, value = {
-      COMMIT_REASON_UNKNOWN,
-      COMMIT_REASON_ACTIVITY_FINISHED,
-      COMMIT_REASON_VIEW_COMMITTED,
-      COMMIT_REASON_VIEW_CLICKED,
-      COMMIT_REASON_VIEW_CHANGED,
-      COMMIT_REASON_SESSION_DESTROYED
-  })
-  @Retention(RetentionPolicy.SOURCE)
-  public @interface CommitReason {
-  }
-
-  public static final int COMMIT_REASON_UNKNOWN =
-      AUTOFILL_SESSION_COMMITTED__COMMIT_REASON__COMMIT_REASON_UNKNOWN;
-  public static final int COMMIT_REASON_ACTIVITY_FINISHED =
-      AUTOFILL_SESSION_COMMITTED__COMMIT_REASON__COMMIT_REASON_ACTIVITY_FINISHED;
-  public static final int COMMIT_REASON_VIEW_COMMITTED =
-      AUTOFILL_SESSION_COMMITTED__COMMIT_REASON__COMMIT_REASON_VIEW_COMMITTED;
-  public static final int COMMIT_REASON_VIEW_CLICKED =
-      AUTOFILL_SESSION_COMMITTED__COMMIT_REASON__COMMIT_REASON_VIEW_CLICKED;
-  public static final int COMMIT_REASON_VIEW_CHANGED =
-      AUTOFILL_SESSION_COMMITTED__COMMIT_REASON__COMMIT_REASON_VIEW_CHANGED;
-  public static final int COMMIT_REASON_SESSION_DESTROYED =
-      AUTOFILL_SESSION_COMMITTED__COMMIT_REASON__COMMIT_REASON_SESSION_DESTROYED;
-
   private final int mSessionId;
   private Optional<SessionCommittedEventInternal> mEventInternal;
 
@@ -110,9 +76,9 @@
   /**
    * Set commit_reason as long as mEventInternal presents.
    */
-  public void maybeSetCommitReason(@CommitReason int val) {
+  public void maybeSetCommitReason(@AutofillCommitReason int val) {
     mEventInternal.ifPresent(event -> {
-      event.mCommitReason = val;
+        event.mCommitReason = val;
     });
   }
 
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index b3cbe45..f92d38d 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -52,6 +52,8 @@
 import com.android.server.UiModeManagerInternal;
 import com.android.server.UiThread;
 import com.android.server.autofill.Helper;
+import com.android.server.autofill.PresentationStatsEventLogger;
+import com.android.server.autofill.SaveEventLogger;
 import com.android.server.utils.Slogf;
 
 import java.io.PrintWriter;
@@ -326,7 +328,7 @@
             @NonNull ValueFinder valueFinder, @NonNull ComponentName componentName,
             @NonNull AutoFillUiCallback callback, @NonNull Context context,
             @NonNull PendingUi pendingSaveUi, boolean isUpdate, boolean compatMode,
-            boolean showServiceIcon) {
+            boolean showServiceIcon, @Nullable SaveEventLogger mSaveEventLogger) {
         if (sVerbose) {
             Slogf.v(TAG, "showSaveUi(update=%b) for %s and display %d: %s", isUpdate,
                     componentName.toShortString(), context.getDisplayId(), info);
@@ -355,6 +357,9 @@
                 @Override
                 public void onSave() {
                     log.setType(MetricsEvent.TYPE_ACTION);
+                    if (mSaveEventLogger != null) {
+                        mSaveEventLogger.maybeSetSaveButtonClicked(true);
+                    }
                     hideSaveUiUiThread(callback);
                     callback.save();
                     destroySaveUiUiThread(pendingSaveUi, true);
@@ -363,6 +368,9 @@
                 @Override
                 public void onCancel(IntentSender listener) {
                     log.setType(MetricsEvent.TYPE_DISMISS);
+                    if (mSaveEventLogger != null) {
+                        mSaveEventLogger.maybeSetCancelButtonClicked(true);
+                    }
                     hideSaveUiUiThread(callback);
                     if (listener != null) {
                         try {
@@ -384,6 +392,9 @@
                         callback.cancelSave();
                     }
                     mMetricsLogger.write(log);
+                    if (mSaveEventLogger != null) {
+                        mSaveEventLogger.maybeSetDialogDismissed(true);
+                    }
                 }
 
                 @Override
@@ -400,7 +411,8 @@
     public void showFillDialog(@NonNull AutofillId focusedId, @NonNull FillResponse response,
             @Nullable String filterText, @Nullable String servicePackageName,
             @NonNull ComponentName componentName, @Nullable Drawable serviceIcon,
-            @NonNull AutoFillUiCallback callback, int sessionId, boolean compatMode) {
+            @NonNull AutoFillUiCallback callback, int sessionId, boolean compatMode,
+            @Nullable PresentationStatsEventLogger mPresentationStatsEventLogger) {
         if (sVerbose) {
             Slog.v(TAG, "showFillDialog for "
                     + componentName.toShortString() + ": " + response);
@@ -442,6 +454,10 @@
                         @Override
                         public void onDatasetPicked(Dataset dataset) {
                             log(MetricsEvent.TYPE_ACTION);
+                            if (mPresentationStatsEventLogger != null) {
+                                mPresentationStatsEventLogger.maybeSetPositiveCtaButtonClicked(
+                                    true);
+                            }
                             hideFillDialogUiThread(callback);
                             if (mCallback != null) {
                                 final int datasetIndex = response.getDatasets().indexOf(dataset);
@@ -453,6 +469,9 @@
                         @Override
                         public void onDismissed() {
                             log(MetricsEvent.TYPE_DISMISS);
+                            if (mPresentationStatsEventLogger != null) {
+                                mPresentationStatsEventLogger.maybeSetDialogDismissed(true);
+                            }
                             hideFillDialogUiThread(callback);
                             callback.requestShowSoftInput(focusedId);
                             callback.requestFallbackFromFillDialog();
@@ -461,6 +480,10 @@
                         @Override
                         public void onCanceled() {
                             log(MetricsEvent.TYPE_CLOSE);
+                            if (mPresentationStatsEventLogger != null) {
+                                mPresentationStatsEventLogger.maybeSetNegativeCtaButtonClicked(
+                                    true);
+                            }
                             hideFillDialogUiThread(callback);
                             callback.requestShowSoftInput(focusedId);
                             callback.requestFallbackFromFillDialog();
diff --git a/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java b/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java
index dec0e76..dbeb624 100644
--- a/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java
@@ -29,6 +29,7 @@
 import android.service.autofill.Dataset;
 import android.service.autofill.FillResponse;
 import android.text.TextUtils;
+import android.util.DisplayMetrics;
 import android.util.PluralsMessageFormatter;
 import android.util.Slog;
 import android.view.ContextThemeWrapper;
@@ -177,7 +178,14 @@
         window.setGravity(Gravity.BOTTOM | Gravity.CENTER);
         window.setCloseOnTouchOutside(true);
         final WindowManager.LayoutParams params = window.getAttributes();
-        params.width = WindowManager.LayoutParams.MATCH_PARENT;
+
+        DisplayMetrics displayMetrics = new DisplayMetrics();
+        window.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
+        final int screenWidth = displayMetrics.widthPixels;
+        final int maxWidth =
+                mContext.getResources().getDimensionPixelSize(R.dimen.autofill_dialog_max_width);
+        params.width = Math.min(screenWidth, maxWidth);
+
         params.accessibilityTitle =
                 mContext.getString(R.string.autofill_picker_accessibility_title);
         params.windowAnimations = R.style.AutofillSaveAnimation;
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index 1204259..f035d07 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -48,6 +48,7 @@
 import android.text.method.LinkMovementMethod;
 import android.text.style.ClickableSpan;
 import android.util.ArraySet;
+import android.util.DisplayMetrics;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -361,7 +362,14 @@
         window.setGravity(Gravity.BOTTOM | Gravity.CENTER);
         window.setCloseOnTouchOutside(true);
         final WindowManager.LayoutParams params = window.getAttributes();
-        params.width = WindowManager.LayoutParams.MATCH_PARENT;
+
+        DisplayMetrics displayMetrics = new DisplayMetrics();
+        window.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
+        final int screenWidth = displayMetrics.widthPixels;
+        final int maxWidth =
+                context.getResources().getDimensionPixelSize(R.dimen.autofill_dialog_max_width);
+        params.width = Math.min(screenWidth, maxWidth);
+
         params.accessibilityTitle = context.getString(R.string.autofill_save_accessibility_title);
         params.windowAnimations = R.style.AutofillSaveAnimation;
         params.setTrustedOverlay();
@@ -563,25 +571,7 @@
     private void setServiceIcon(Context context, View view, Drawable serviceIcon) {
         final ImageView iconView = view.findViewById(R.id.autofill_save_icon);
         final Resources res = context.getResources();
-
-        final int maxWidth = res.getDimensionPixelSize(R.dimen.autofill_save_icon_max_size);
-        final int maxHeight = maxWidth;
-        final int actualWidth = serviceIcon.getMinimumWidth();
-        final int actualHeight = serviceIcon.getMinimumHeight();
-
-        if (actualWidth <= maxWidth && actualHeight <= maxHeight) {
-            if (sDebug) {
-                Slog.d(TAG, "Adding service icon "
-                        + "(" + actualWidth + "x" + actualHeight + ") as it's less than maximum "
-                        + "(" + maxWidth + "x" + maxHeight + ").");
-            }
-            iconView.setImageDrawable(serviceIcon);
-        } else {
-            Slog.w(TAG, "Not adding service icon of size "
-                    + "(" + actualWidth + "x" + actualHeight + ") because maximum is "
-                    + "(" + maxWidth + "x" + maxHeight + ").");
-            ((ViewGroup)iconView.getParent()).removeView(iconView);
-        }
+        iconView.setImageDrawable(serviceIcon);
     }
 
     private static boolean isValidLink(PendingIntent pendingIntent, Intent intent) {
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index 77990af..8cbb5dc 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -900,9 +900,6 @@
             mAgent.doRestoreFinished(mEphemeralOpToken,
                     backupManagerService.getBackupManagerBinder());
 
-            // Ask the agent for logs after doRestoreFinished() to allow it to finalize its logs.
-            BackupManagerMonitorUtils.monitorAgentLoggingResults(mMonitor, mCurrentPackage, mAgent);
-
             // If we get this far, the callback or timeout will schedule the
             // next restore state, so we're done
         } catch (Exception e) {
@@ -1323,6 +1320,11 @@
                 EventLog.writeEvent(EventLogTags.RESTORE_PACKAGE,
                         mCurrentPackage.packageName, size);
 
+                // Ask the agent for logs after doRestoreFinished() has completed executing to allow
+                // it to finalize its logs.
+                BackupManagerMonitorUtils.monitorAgentLoggingResults(mMonitor, mCurrentPackage,
+                        mAgent);
+
                 // Just go back to running the restore queue
                 keyValueAgentCleanup();
 
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceConfig.java b/services/companion/java/com/android/server/companion/CompanionDeviceConfig.java
index 8570515..a2b71e0 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceConfig.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceConfig.java
@@ -16,6 +16,7 @@
 
 package com.android.server.companion;
 
+import android.os.Binder;
 import android.provider.DeviceConfig;
 
 /**
@@ -34,7 +35,12 @@
      * Returns whether the given flag is currently enabled, with a default value of {@code false}.
      */
     public static boolean isEnabled(String flag) {
-        return DeviceConfig.getBoolean(NAMESPACE_COMPANION, flag, /* defaultValue= */ false);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return DeviceConfig.getBoolean(NAMESPACE_COMPANION, flag, /* defaultValue= */ false);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     /**
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 7975e49..6b99494 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -306,6 +306,7 @@
         } else if (phase == PHASE_BOOT_COMPLETED) {
             // Run the Inactive Association Removal job service daily.
             InactiveAssociationsRemovalService.schedule(getContext());
+            mCrossDeviceSyncController.onBootCompleted();
         }
     }
 
@@ -1382,10 +1383,11 @@
         }
 
         @Override
-        public void registerCallMetadataSyncCallback(CrossDeviceSyncControllerCallback callback) {
+        public void registerCallMetadataSyncCallback(CrossDeviceSyncControllerCallback callback,
+                @CrossDeviceSyncControllerCallback.Type int type) {
             if (CompanionDeviceConfig.isEnabled(
                     CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
-                mCrossDeviceSyncController.registerCallMetadataSyncCallback(callback);
+                mCrossDeviceSyncController.registerCallMetadataSyncCallback(callback, type);
             }
         }
 
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerServiceInternal.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerServiceInternal.java
index 3b108e6..c5ef4e4 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerServiceInternal.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerServiceInternal.java
@@ -36,7 +36,8 @@
      * Registers a callback from an InCallService / ConnectionService to CDM to process sync
      * requests and perform call control actions.
      */
-    void registerCallMetadataSyncCallback(CrossDeviceSyncControllerCallback callback);
+    void registerCallMetadataSyncCallback(CrossDeviceSyncControllerCallback callback,
+            @CrossDeviceSyncControllerCallback.Type int type);
 
     /**
      * Requests a sync from an InCallService / ConnectionService to CDM, for the given association
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java b/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java
index c511429..04fbab4 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java
@@ -26,6 +26,7 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.server.companion.datatransfer.SystemDataTransferRequestStore;
+import com.android.server.companion.datatransfer.contextsync.BitmapUtils;
 import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncController;
 import com.android.server.companion.presence.CompanionDevicePresenceMonitor;
 import com.android.server.companion.transport.CompanionTransportManager;
@@ -168,13 +169,17 @@
                 case "send-context-sync-call-facilitators-message": {
                     associationId = getNextIntArgRequired();
                     int numberOfFacilitators = getNextIntArgRequired();
+                    String facilitatorName = getNextArgRequired();
+                    String facilitatorId = getNextArgRequired();
                     final ProtoOutputStream pos = new ProtoOutputStream();
                     pos.write(ContextSyncMessage.VERSION, 1);
                     final long telecomToken = pos.start(ContextSyncMessage.TELECOM);
                     for (int i = 0; i < numberOfFacilitators; i++) {
                         final long facilitatorsToken = pos.start(Telecom.FACILITATORS);
-                        pos.write(Telecom.CallFacilitator.NAME, "Call Facilitator App #" + i);
-                        pos.write(Telecom.CallFacilitator.IDENTIFIER, "com.android.test" + i);
+                        pos.write(Telecom.CallFacilitator.NAME,
+                                numberOfFacilitators == 1 ? facilitatorName : facilitatorName + i);
+                        pos.write(Telecom.CallFacilitator.IDENTIFIER,
+                                numberOfFacilitators == 1 ? facilitatorId : facilitatorId + i);
                         pos.end(facilitatorsToken);
                     }
                     pos.end(telecomToken);
@@ -188,6 +193,15 @@
                     associationId = getNextIntArgRequired();
                     String callId = getNextArgRequired();
                     String facilitatorId = getNextArgRequired();
+                    int status = getNextIntArgRequired();
+                    boolean acceptControl = getNextBooleanArgRequired();
+                    boolean rejectControl = getNextBooleanArgRequired();
+                    boolean silenceControl = getNextBooleanArgRequired();
+                    boolean muteControl = getNextBooleanArgRequired();
+                    boolean unmuteControl = getNextBooleanArgRequired();
+                    boolean endControl = getNextBooleanArgRequired();
+                    boolean holdControl = getNextBooleanArgRequired();
+                    boolean unholdControl = getNextBooleanArgRequired();
                     final ProtoOutputStream pos = new ProtoOutputStream();
                     pos.write(ContextSyncMessage.VERSION, 1);
                     final long telecomToken = pos.start(ContextSyncMessage.TELECOM);
@@ -195,15 +209,40 @@
                     pos.write(Telecom.Call.ID, callId);
                     final long originToken = pos.start(Telecom.Call.ORIGIN);
                     pos.write(Telecom.Call.Origin.CALLER_ID, "Caller Name");
+                    pos.write(Telecom.Call.Origin.APP_ICON, BitmapUtils.renderDrawableToByteArray(
+                            mService.getContext().getPackageManager().getApplicationIcon(
+                                    facilitatorId)));
                     final long facilitatorToken = pos.start(
                             Telecom.Request.CreateAction.FACILITATOR);
                     pos.write(Telecom.CallFacilitator.NAME, "Test App Name");
                     pos.write(Telecom.CallFacilitator.IDENTIFIER, facilitatorId);
                     pos.end(facilitatorToken);
                     pos.end(originToken);
-                    pos.write(Telecom.Call.STATUS, Telecom.Call.RINGING);
-                    pos.write(Telecom.Call.CONTROLS, Telecom.ACCEPT);
-                    pos.write(Telecom.Call.CONTROLS, Telecom.REJECT);
+                    pos.write(Telecom.Call.STATUS, status);
+                    if (acceptControl) {
+                        pos.write(Telecom.Call.CONTROLS, Telecom.ACCEPT);
+                    }
+                    if (rejectControl) {
+                        pos.write(Telecom.Call.CONTROLS, Telecom.REJECT);
+                    }
+                    if (silenceControl) {
+                        pos.write(Telecom.Call.CONTROLS, Telecom.SILENCE);
+                    }
+                    if (muteControl) {
+                        pos.write(Telecom.Call.CONTROLS, Telecom.MUTE);
+                    }
+                    if (unmuteControl) {
+                        pos.write(Telecom.Call.CONTROLS, Telecom.UNMUTE);
+                    }
+                    if (endControl) {
+                        pos.write(Telecom.Call.CONTROLS, Telecom.END);
+                    }
+                    if (holdControl) {
+                        pos.write(Telecom.Call.CONTROLS, Telecom.PUT_ON_HOLD);
+                    }
+                    if (unholdControl) {
+                        pos.write(Telecom.Call.CONTROLS, Telecom.TAKE_OFF_HOLD);
+                    }
                     pos.end(callsToken);
                     pos.end(telecomToken);
                     mTransportManager.createEmulatedTransport(associationId)
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/BitmapUtils.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/BitmapUtils.java
new file mode 100644
index 0000000..829041a
--- /dev/null
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/BitmapUtils.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.companion.datatransfer.contextsync;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+
+import java.io.ByteArrayOutputStream;
+
+/** Provides bitmap utility operations for rendering drawables to byte arrays. */
+public class BitmapUtils {
+
+    private static final int APP_ICON_BITMAP_DIMENSION = 256;
+
+    /** Render a drawable to a bitmap, which is then reformatted as a byte array. */
+    public static byte[] renderDrawableToByteArray(Drawable drawable) {
+        if (drawable instanceof BitmapDrawable) {
+            // Can't recycle the drawable's bitmap, so handle separately
+            final Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
+            if (bitmap.getWidth() > APP_ICON_BITMAP_DIMENSION
+                    || bitmap.getHeight() > APP_ICON_BITMAP_DIMENSION) {
+                // Downscale, as the original drawable bitmap is too large.
+                final Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap,
+                        APP_ICON_BITMAP_DIMENSION, APP_ICON_BITMAP_DIMENSION, /* filter= */ true);
+                final byte[] renderedBitmap = renderBitmapToByteArray(scaledBitmap);
+                scaledBitmap.recycle();
+                return renderedBitmap;
+            }
+            return renderBitmapToByteArray(bitmap);
+        }
+        final Bitmap bitmap = Bitmap.createBitmap(APP_ICON_BITMAP_DIMENSION,
+                APP_ICON_BITMAP_DIMENSION,
+                Bitmap.Config.ARGB_8888);
+        try {
+            final Canvas canvas = new Canvas(bitmap);
+            drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
+            drawable.draw(canvas);
+            return renderBitmapToByteArray(bitmap);
+        } finally {
+            bitmap.recycle();
+        }
+    }
+
+    private static byte[] renderBitmapToByteArray(Bitmap bitmap) {
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream(bitmap.getByteCount());
+        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
+        return baos.toByteArray();
+    }
+}
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java
index 459bf98..7371824 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java
@@ -17,6 +17,7 @@
 package com.android.server.companion.datatransfer.contextsync;
 
 import android.media.AudioManager;
+import android.net.Uri;
 import android.os.Bundle;
 import android.telecom.Call;
 import android.telecom.Connection;
@@ -62,20 +63,14 @@
                         final CallMetadataSyncConnection existingConnection =
                                 mActiveConnections.get(new CallMetadataSyncConnectionIdentifier(
                                         associationId, call.getId()));
-                        if (existingConnection == null) {
-                            final Bundle extras = new Bundle();
-                            extras.putInt(CrossDeviceSyncController.EXTRA_ASSOCIATION_ID,
-                                    associationId);
-                            extras.putParcelable(CrossDeviceSyncController.EXTRA_CALL, call);
-                            mTelecomManager.addNewIncomingCall(call.getPhoneAccountHandle(),
-                                    extras);
-                        } else {
+                        if (existingConnection != null) {
                             existingConnection.update(call);
                         }
                     }
                     // Remove obsolete calls.
                     mActiveConnections.values().removeIf(connection -> {
-                        if (!callMetadataSyncData.hasCall(connection.getCallId())) {
+                        if (associationId == connection.getAssociationId()
+                                && !callMetadataSyncData.hasCall(connection.getCallId())) {
                             connection.setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
                             return true;
                         }
@@ -91,7 +86,8 @@
         mAudioManager = getSystemService(AudioManager.class);
         mTelecomManager = getSystemService(TelecomManager.class);
         mCdmsi = LocalServices.getService(CompanionDeviceManagerServiceInternal.class);
-        mCdmsi.registerCallMetadataSyncCallback(mCrossDeviceSyncControllerCallback);
+        mCdmsi.registerCallMetadataSyncCallback(mCrossDeviceSyncControllerCallback,
+                CrossDeviceSyncControllerCallback.TYPE_CONNECTION_SERVICE);
     }
 
     @Override
@@ -101,6 +97,11 @@
                 CrossDeviceSyncController.EXTRA_ASSOCIATION_ID);
         final CallMetadataSyncData.Call call = connectionRequest.getExtras().getParcelable(
                 CrossDeviceSyncController.EXTRA_CALL, CallMetadataSyncData.Call.class);
+        // InCallServices outside of framework (like Dialer's) might try to read this, and crash
+        // when they can't. Remove it once we're done with it, as well as the other internal ones.
+        connectionRequest.getExtras().remove(CrossDeviceSyncController.EXTRA_CALL);
+        connectionRequest.getExtras().remove(CrossDeviceSyncController.EXTRA_CALL_FACILITATOR_ID);
+        connectionRequest.getExtras().remove(CrossDeviceSyncController.EXTRA_ASSOCIATION_ID);
         final CallMetadataSyncConnection connection = new CallMetadataSyncConnection(
                 mTelecomManager,
                 mAudioManager,
@@ -113,15 +114,17 @@
                                 CrossDeviceSyncController.createCallControlMessage(callId, action));
                     }
                 });
-        connection.setConnectionProperties(
-                Connection.PROPERTY_IS_EXTERNAL_CALL | Connection.PROPERTY_SELF_MANAGED);
+        connection.setConnectionProperties(Connection.PROPERTY_IS_EXTERNAL_CALL);
+        connection.setInitializing();
         return connection;
     }
 
     @Override
     public void onCreateIncomingConnectionFailed(PhoneAccountHandle phoneAccountHandle,
             ConnectionRequest connectionRequest) {
-        Slog.e(TAG, "onCreateIncomingConnectionFailed for: " + phoneAccountHandle.getId());
+        final String id =
+                phoneAccountHandle != null ? phoneAccountHandle.getId() : "unknown PhoneAccount";
+        Slog.e(TAG, "onCreateOutgoingConnectionFailed for: " + id);
     }
 
     @Override
@@ -132,7 +135,6 @@
         final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
         call.setId(UUID.randomUUID().toString());
         call.setStatus(android.companion.Telecom.Call.UNKNOWN_STATUS);
-        call.setPhoneAccountHandle(phoneAccountHandle);
         final CallMetadataSyncData.CallFacilitator callFacilitator =
                 new CallMetadataSyncData.CallFacilitator(phoneAccount.getLabel().toString(),
                         phoneAccount.getExtras().getString(
@@ -142,6 +144,10 @@
         final int associationId = connectionRequest.getExtras().getInt(
                 CrossDeviceSyncController.EXTRA_ASSOCIATION_ID);
 
+        connectionRequest.getExtras().remove(CrossDeviceSyncController.EXTRA_CALL);
+        connectionRequest.getExtras().remove(CrossDeviceSyncController.EXTRA_CALL_FACILITATOR_ID);
+        connectionRequest.getExtras().remove(CrossDeviceSyncController.EXTRA_ASSOCIATION_ID);
+
         final CallMetadataSyncConnection connection = new CallMetadataSyncConnection(
                 mTelecomManager,
                 mAudioManager,
@@ -154,8 +160,7 @@
                                 CrossDeviceSyncController.createCallControlMessage(callId, action));
                     }
                 });
-        connection.setConnectionProperties(
-                Connection.PROPERTY_IS_EXTERNAL_CALL | Connection.PROPERTY_SELF_MANAGED);
+        connection.setConnectionProperties(Connection.PROPERTY_IS_EXTERNAL_CALL);
 
         mCdmsi.sendCrossDeviceSyncMessage(associationId,
                 CrossDeviceSyncController.createCallCreateMessage(call.getId(),
@@ -168,13 +173,21 @@
     @Override
     public void onCreateOutgoingConnectionFailed(PhoneAccountHandle phoneAccountHandle,
             ConnectionRequest connectionRequest) {
-        Slog.e(TAG, "onCreateIncomingConnectionFailed for: " + phoneAccountHandle.getId());
+        final String id =
+                phoneAccountHandle != null ? phoneAccountHandle.getId() : "unknown PhoneAccount";
+        Slog.e(TAG, "onCreateOutgoingConnectionFailed for: " + id);
     }
 
     @Override
     public void onCreateConnectionComplete(Connection connection) {
         if (connection instanceof CallMetadataSyncConnection) {
-            ((CallMetadataSyncConnection) connection).initialize();
+            final CallMetadataSyncConnection callMetadataSyncConnection =
+                    (CallMetadataSyncConnection) connection;
+            callMetadataSyncConnection.initialize();
+            mActiveConnections.put(new CallMetadataSyncConnectionIdentifier(
+                            callMetadataSyncConnection.getAssociationId(),
+                            callMetadataSyncConnection.getCallId()),
+                    callMetadataSyncConnection);
         }
     }
 
@@ -242,7 +255,11 @@
             return mCall.getId();
         }
 
-        public void initialize() {
+        public int getAssociationId() {
+            return mAssociationId;
+        }
+
+        private void initialize() {
             final int status = mCall.getStatus();
             if (status == android.companion.Telecom.Call.RINGING_SILENCED) {
                 mTelecomManager.silenceRinger();
@@ -254,12 +271,21 @@
                 setActive();
             } else if (state == Call.STATE_HOLDING) {
                 setOnHold();
+            } else if (state == Call.STATE_DISCONNECTED) {
+                setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
             } else {
-                Slog.e(TAG, "Could not initialize call to unknown state");
+                setInitialized();
+            }
+
+            final String callerId = mCall.getCallerId();
+            if (callerId != null) {
+                setCallerDisplayName(callerId, TelecomManager.PRESENTATION_ALLOWED);
+                setAddress(Uri.fromParts("custom", mCall.getCallerId(), null),
+                        TelecomManager.PRESENTATION_ALLOWED);
             }
 
             final Bundle extras = new Bundle();
-            extras.putString(CrossDeviceCall.EXTRA_CALL_ID, mCall.getId());
+            extras.putString(CrossDeviceSyncController.EXTRA_CALL_ID, mCall.getId());
             putExtras(extras);
 
             int capabilities = getConnectionCapabilities();
@@ -280,7 +306,7 @@
             }
         }
 
-        public void update(CallMetadataSyncData.Call call) {
+        private void update(CallMetadataSyncData.Call call) {
             final int status = call.getStatus();
             if (status == android.companion.Telecom.Call.RINGING_SILENCED
                     && mCall.getStatus() != android.companion.Telecom.Call.RINGING_SILENCED) {
@@ -295,31 +321,29 @@
                     setActive();
                 } else if (state == Call.STATE_HOLDING) {
                     setOnHold();
+                } else if (state == Call.STATE_DISCONNECTED) {
+                    setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
                 } else {
                     Slog.e(TAG, "Could not update call to unknown state");
                 }
             }
 
             int capabilities = getConnectionCapabilities();
+            mCall.setControls(call.getControls());
             final boolean hasHoldControl = mCall.hasControl(
                     android.companion.Telecom.PUT_ON_HOLD)
                     || mCall.hasControl(android.companion.Telecom.TAKE_OFF_HOLD);
-            if (hasHoldControl != ((getConnectionCapabilities() & CAPABILITY_HOLD)
-                    == CAPABILITY_HOLD)) {
-                if (hasHoldControl) {
-                    capabilities |= CAPABILITY_HOLD;
-                } else {
-                    capabilities &= ~CAPABILITY_HOLD;
-                }
+            if (hasHoldControl) {
+                capabilities |= CAPABILITY_HOLD;
+            } else {
+                capabilities &= ~CAPABILITY_HOLD;
             }
-            final boolean hasMuteControl = mCall.hasControl(android.companion.Telecom.MUTE);
-            if (hasMuteControl != ((getConnectionCapabilities() & CAPABILITY_MUTE)
-                    == CAPABILITY_MUTE)) {
-                if (hasMuteControl) {
-                    capabilities |= CAPABILITY_MUTE;
-                } else {
-                    capabilities &= ~CAPABILITY_MUTE;
-                }
+            final boolean hasMuteControl = mCall.hasControl(android.companion.Telecom.MUTE)
+                    || mCall.hasControl(android.companion.Telecom.UNMUTE);
+            if (hasMuteControl) {
+                capabilities |= CAPABILITY_MUTE;
+            } else {
+                capabilities &= ~CAPABILITY_MUTE;
             }
             mAudioManager.setMicrophoneMute(
                     mCall.hasControl(android.companion.Telecom.UNMUTE));
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncData.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncData.java
index b3cf772..d8621cb 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncData.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncData.java
@@ -20,7 +20,6 @@
 import android.companion.ContextSyncMessage;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.telecom.PhoneAccountHandle;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -189,7 +188,6 @@
         private String mCallerId;
         private byte[] mAppIcon;
         private CallFacilitator mFacilitator;
-        private PhoneAccountHandle mPhoneAccountHandle;
         private int mStatus;
         private final Set<Integer> mControls = new HashSet<>();
 
@@ -200,9 +198,6 @@
             call.setAppIcon(parcel.readBlob());
             call.setFacilitator(parcel.readParcelable(CallFacilitator.class.getClassLoader(),
                     CallFacilitator.class));
-            call.setPhoneAccountHandle(
-                    parcel.readParcelable(PhoneAccountHandle.class.getClassLoader(),
-                            android.telecom.PhoneAccountHandle.class));
             call.setStatus(parcel.readInt());
             final int numberOfControls = parcel.readInt();
             for (int i = 0; i < numberOfControls; i++) {
@@ -217,7 +212,6 @@
             parcel.writeString(mCallerId);
             parcel.writeBlob(mAppIcon);
             parcel.writeParcelable(mFacilitator, parcelableFlags);
-            parcel.writeParcelable(mPhoneAccountHandle, parcelableFlags);
             parcel.writeInt(mStatus);
             parcel.writeInt(mControls.size());
             for (int control : mControls) {
@@ -241,10 +235,6 @@
             mFacilitator = facilitator;
         }
 
-        void setPhoneAccountHandle(PhoneAccountHandle phoneAccountHandle) {
-            mPhoneAccountHandle = phoneAccountHandle;
-        }
-
         void setStatus(int status) {
             mStatus = status;
         }
@@ -253,6 +243,11 @@
             mControls.add(control);
         }
 
+        void setControls(Set<Integer> controls) {
+            mControls.clear();
+            mControls.addAll(controls);
+        }
+
         String getId() {
             return mId;
         }
@@ -269,10 +264,6 @@
             return mFacilitator;
         }
 
-        PhoneAccountHandle getPhoneAccountHandle() {
-            return mPhoneAccountHandle;
-        }
-
         int getStatus() {
             return mStatus;
         }
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncInCallService.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncInCallService.java
index 1f5e168..b46d5d3 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncInCallService.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncInCallService.java
@@ -79,16 +79,15 @@
                         int callControlAction) {
                     final CrossDeviceCall crossDeviceCall = getCallForId(crossDeviceCallId,
                             mCurrentCalls.values());
+                    if (crossDeviceCall == null) {
+                        return;
+                    }
                     switch (callControlAction) {
                         case android.companion.Telecom.ACCEPT:
-                            if (crossDeviceCall != null) {
-                                crossDeviceCall.doAccept();
-                            }
+                            crossDeviceCall.doAccept();
                             break;
                         case android.companion.Telecom.REJECT:
-                            if (crossDeviceCall != null) {
-                                crossDeviceCall.doReject();
-                            }
+                            crossDeviceCall.doReject();
                             break;
                         case android.companion.Telecom.SILENCE:
                             doSilence();
@@ -100,19 +99,13 @@
                             doUnmute();
                             break;
                         case android.companion.Telecom.END:
-                            if (crossDeviceCall != null) {
-                                crossDeviceCall.doEnd();
-                            }
+                            crossDeviceCall.doEnd();
                             break;
                         case android.companion.Telecom.PUT_ON_HOLD:
-                            if (crossDeviceCall != null) {
-                                crossDeviceCall.doPutOnHold();
-                            }
+                            crossDeviceCall.doPutOnHold();
                             break;
                         case android.companion.Telecom.TAKE_OFF_HOLD:
-                            if (crossDeviceCall != null) {
-                                crossDeviceCall.doTakeOffHold();
-                            }
+                            crossDeviceCall.doTakeOffHold();
                             break;
                         default:
                     }
@@ -148,7 +141,8 @@
         super.onCreate();
         if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
             mCdmsi = LocalServices.getService(CompanionDeviceManagerServiceInternal.class);
-            mCdmsi.registerCallMetadataSyncCallback(mCrossDeviceSyncControllerCallback);
+            mCdmsi.registerCallMetadataSyncCallback(mCrossDeviceSyncControllerCallback,
+                    CrossDeviceSyncControllerCallback.TYPE_IN_CALL_SERVICE);
         }
     }
 
@@ -156,7 +150,7 @@
         if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)
                 && mNumberOfActiveSyncAssociations > 0) {
             mCurrentCalls.putAll(getCalls().stream().collect(Collectors.toMap(call -> call,
-                    call -> new CrossDeviceCall(getPackageManager(), call, getCallAudioState()))));
+                    call -> new CrossDeviceCall(this, call, getCallAudioState()))));
             mCurrentCalls.keySet().forEach(call -> call.registerCallback(mTelecomCallback,
                     getMainThreadHandler()));
             sync(getUserId());
@@ -182,7 +176,7 @@
         if (CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)
                 && mNumberOfActiveSyncAssociations > 0) {
             mCurrentCalls.put(call,
-                    new CrossDeviceCall(getPackageManager(), call, getCallAudioState()));
+                    new CrossDeviceCall(this, call, getCallAudioState()));
             call.registerCallback(mTelecomCallback);
             sync(getUserId());
         }
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java
index 168068e..fec6923 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java
@@ -17,20 +17,20 @@
 package com.android.server.companion.datatransfer.contextsync;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
+import android.net.Uri;
 import android.telecom.Call;
 import android.telecom.CallAudioState;
+import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.io.ByteArrayOutputStream;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.UUID;
@@ -40,47 +40,57 @@
 
     private static final String TAG = "CrossDeviceCall";
 
-    public static final String EXTRA_CALL_ID =
-            "com.android.companion.datatransfer.contextsync.extra.CALL_ID";
-    private static final int APP_ICON_BITMAP_DIMENSION = 256;
-
     private final String mId;
-    private Call mCall;
+    private final Call mCall;
     @VisibleForTesting boolean mIsEnterprise;
-    @VisibleForTesting boolean mIsOtt;
     private final String mCallingAppPackageName;
     private String mCallingAppName;
     private byte[] mCallingAppIcon;
     private String mCallerDisplayName;
+    private int mCallerDisplayNamePresentation;
     private int mStatus = android.companion.Telecom.Call.UNKNOWN_STATUS;
     private String mContactDisplayName;
+    private Uri mHandle;
+    private int mHandlePresentation;
     private boolean mIsMuted;
     private final Set<Integer> mControls = new HashSet<>();
+    private final boolean mIsCallPlacedByContextSync;
 
-    public CrossDeviceCall(PackageManager packageManager, @NonNull Call call,
+    public CrossDeviceCall(Context context, @NonNull Call call,
             CallAudioState callAudioState) {
-        this(packageManager, call.getDetails(), callAudioState);
-        mCall = call;
-        call.putExtra(EXTRA_CALL_ID, mId);
+        this(context, call, call.getDetails(), callAudioState);
     }
 
-    CrossDeviceCall(PackageManager packageManager, Call.Details callDetails,
+    CrossDeviceCall(Context context, Call.Details callDetails,
             CallAudioState callAudioState) {
+        this(context, /* call= */ null, callDetails, callAudioState);
+    }
+
+    private CrossDeviceCall(Context context, @Nullable Call call,
+            Call.Details callDetails, CallAudioState callAudioState) {
+        mCall = call;
         final String predefinedId = callDetails.getIntentExtras() != null
-                ? callDetails.getIntentExtras().getString(EXTRA_CALL_ID) : null;
-        mId = predefinedId != null ? predefinedId : UUID.randomUUID().toString();
+                ? callDetails.getIntentExtras().getString(CrossDeviceSyncController.EXTRA_CALL_ID)
+                : null;
+        final String generatedId = UUID.randomUUID().toString();
+        mId = predefinedId != null ? (generatedId + predefinedId) : generatedId;
+        if (call != null) {
+            call.putExtra(CrossDeviceSyncController.EXTRA_CALL_ID, mId);
+        }
+        mIsCallPlacedByContextSync =
+                new ComponentName(context, CallMetadataSyncConnectionService.class)
+                        .equals(callDetails.getAccountHandle().getComponentName());
         mCallingAppPackageName =
                 callDetails.getAccountHandle().getComponentName().getPackageName();
-        mIsOtt = (callDetails.getCallCapabilities() & Call.Details.PROPERTY_SELF_MANAGED)
-                == Call.Details.PROPERTY_SELF_MANAGED;
         mIsEnterprise = (callDetails.getCallProperties() & Call.Details.PROPERTY_ENTERPRISE_CALL)
                 == Call.Details.PROPERTY_ENTERPRISE_CALL;
+        final PackageManager packageManager = context.getPackageManager();
         try {
             final ApplicationInfo applicationInfo = packageManager
                     .getApplicationInfo(mCallingAppPackageName,
                             PackageManager.ApplicationInfoFlags.of(0));
             mCallingAppName = packageManager.getApplicationLabel(applicationInfo).toString();
-            mCallingAppIcon = renderDrawableToByteArray(
+            mCallingAppIcon = BitmapUtils.renderDrawableToByteArray(
                     packageManager.getApplicationIcon(applicationInfo));
         } catch (PackageManager.NameNotFoundException e) {
             Slog.e(TAG, "Could not get application info for package " + mCallingAppPackageName, e);
@@ -89,40 +99,6 @@
         updateCallDetails(callDetails);
     }
 
-    private byte[] renderDrawableToByteArray(Drawable drawable) {
-        if (drawable instanceof BitmapDrawable) {
-            // Can't recycle the drawable's bitmap, so handle separately
-            final Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
-            if (bitmap.getWidth() > APP_ICON_BITMAP_DIMENSION
-                    || bitmap.getHeight() > APP_ICON_BITMAP_DIMENSION) {
-                // Downscale, as the original drawable bitmap is too large.
-                final Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap,
-                        APP_ICON_BITMAP_DIMENSION, APP_ICON_BITMAP_DIMENSION, /* filter= */ true);
-                final byte[] renderedBitmap = renderBitmapToByteArray(scaledBitmap);
-                scaledBitmap.recycle();
-                return renderedBitmap;
-            }
-            return renderBitmapToByteArray(bitmap);
-        }
-        final Bitmap bitmap = Bitmap.createBitmap(APP_ICON_BITMAP_DIMENSION,
-                APP_ICON_BITMAP_DIMENSION,
-                Bitmap.Config.ARGB_8888);
-        try {
-            final Canvas canvas = new Canvas(bitmap);
-            drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
-            drawable.draw(canvas);
-            return renderBitmapToByteArray(bitmap);
-        } finally {
-            bitmap.recycle();
-        }
-    }
-
-    private byte[] renderBitmapToByteArray(Bitmap bitmap) {
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream(bitmap.getByteCount());
-        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
-        return baos.toByteArray();
-    }
-
     /**
      * Update the mute state of this call. No-op if the call is not capable of being muted.
      *
@@ -148,7 +124,10 @@
     @VisibleForTesting
     void updateCallDetails(Call.Details callDetails) {
         mCallerDisplayName = callDetails.getCallerDisplayName();
+        mCallerDisplayNamePresentation = callDetails.getCallerDisplayNamePresentation();
         mContactDisplayName = callDetails.getContactDisplayName();
+        mHandle = callDetails.getHandle();
+        mHandlePresentation = callDetails.getHandlePresentation();
         mStatus = convertStateToStatus(callDetails.getState());
         mControls.clear();
         if (mStatus == android.companion.Telecom.Call.RINGING
@@ -185,7 +164,14 @@
                 return android.companion.Telecom.Call.ONGOING;
             case Call.STATE_RINGING:
                 return android.companion.Telecom.Call.RINGING;
+            case Call.STATE_AUDIO_PROCESSING:
+                return android.companion.Telecom.Call.AUDIO_PROCESSING;
+            case Call.STATE_SIMULATED_RINGING:
+                return android.companion.Telecom.Call.RINGING_SIMULATED;
+            case Call.STATE_DISCONNECTED:
+                return android.companion.Telecom.Call.DISCONNECTED;
             default:
+                Slog.e(TAG, "Couldn't resolve state to status: " + callState);
                 return android.companion.Telecom.Call.UNKNOWN_STATUS;
         }
     }
@@ -203,6 +189,12 @@
             case android.companion.Telecom.Call.RINGING:
             case android.companion.Telecom.Call.RINGING_SILENCED:
                 return Call.STATE_RINGING;
+            case android.companion.Telecom.Call.AUDIO_PROCESSING:
+                return Call.STATE_AUDIO_PROCESSING;
+            case android.companion.Telecom.Call.RINGING_SIMULATED:
+                return Call.STATE_SIMULATED_RINGING;
+            case android.companion.Telecom.Call.DISCONNECTED:
+                return Call.STATE_DISCONNECTED;
             case android.companion.Telecom.Call.UNKNOWN_STATUS:
             default:
                 return Call.STATE_NEW;
@@ -235,10 +227,23 @@
      * @param isAdminBlocked whether there is an admin that has blocked contacts over Bluetooth
      */
     public String getReadableCallerId(boolean isAdminBlocked) {
-        if (mIsOtt) {
+        if (mIsEnterprise && isAdminBlocked) {
+            // Cannot use any contact information.
+            return getNonContactString();
+        }
+        return mContactDisplayName != null ? mContactDisplayName : getNonContactString();
+    }
+
+    private String getNonContactString() {
+        if (mCallerDisplayName != null
+                && mCallerDisplayNamePresentation == TelecomManager.PRESENTATION_ALLOWED) {
             return mCallerDisplayName;
         }
-        return mIsEnterprise && isAdminBlocked ? mCallerDisplayName : mContactDisplayName;
+        if (mHandle != null && mHandle.getSchemeSpecificPart() != null
+                && mHandlePresentation == TelecomManager.PRESENTATION_ALLOWED) {
+            return mHandle.getSchemeSpecificPart();
+        }
+        return null;
     }
 
     public int getStatus() {
@@ -249,6 +254,10 @@
         return mControls;
     }
 
+    public boolean isCallPlacedByContextSync() {
+        return mIsCallPlacedByContextSync;
+    }
+
     void doAccept() {
         mCall.answer(VideoProfile.STATE_AUDIO_ONLY);
     }
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java
index 937d7fe..bf82f3f 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java
@@ -20,6 +20,7 @@
 
 import android.app.admin.DevicePolicyManager;
 import android.companion.AssociationInfo;
+import android.companion.CompanionDeviceManager;
 import android.companion.ContextSyncMessage;
 import android.companion.IOnMessageReceivedListener;
 import android.companion.IOnTransportsChangedListener;
@@ -44,8 +45,10 @@
 import com.android.server.companion.transport.CompanionTransportManager;
 
 import java.io.IOException;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -54,6 +57,7 @@
 import java.util.Objects;
 import java.util.Set;
 import java.util.UUID;
+import java.util.stream.Collectors;
 
 /**
  * Monitors connections and sending / receiving of synced data.
@@ -62,6 +66,13 @@
 
     private static final String TAG = "CrossDeviceSyncController";
 
+    public static final String EXTRA_CALL_ID =
+            "com.android.companion.datatransfer.contextsync.extra.CALL_ID";
+    static final String EXTRA_FACILITATOR_ICON =
+            "com.android.companion.datatransfer.contextsync.extra.FACILITATOR_ICON";
+    static final String EXTRA_IS_REMOTE_ORIGIN =
+            "com.android.companion.datatransfer.contextsync.extra.IS_REMOTE_ORIGIN";
+
     static final String EXTRA_ASSOCIATION_ID =
             "com.android.server.companion.datatransfer.contextsync.extra.ASSOCIATION_ID";
     static final String EXTRA_CALL =
@@ -78,11 +89,13 @@
     private final Context mContext;
     private final CompanionTransportManager mCompanionTransportManager;
     private final PhoneAccountManager mPhoneAccountManager;
+    private final CallManager mCallManager;
     private final List<AssociationInfo> mConnectedAssociations = new ArrayList<>();
     private final Set<Integer> mBlocklist = new HashSet<>();
     private final List<CallMetadataSyncData.CallFacilitator> mCallFacilitators = new ArrayList<>();
 
-    private CrossDeviceSyncControllerCallback mCrossDeviceSyncControllerCallback;
+    private WeakReference<CrossDeviceSyncControllerCallback> mInCallServiceCallbackRef;
+    private WeakReference<CrossDeviceSyncControllerCallback> mConnectionServiceCallbackRef;
 
     public CrossDeviceSyncController(Context context,
             CompanionTransportManager companionTransportManager) {
@@ -104,25 +117,77 @@
                         mConnectedAssociations);
                 mConnectedAssociations.clear();
                 mConnectedAssociations.addAll(newAssociations);
-                if (mCrossDeviceSyncControllerCallback == null) {
-                    Slog.w(TAG, "No callback to report transports changed");
-                    return;
-                }
                 for (AssociationInfo associationInfo : newAssociations) {
-                    if (!existingAssociations.contains(associationInfo)
-                            && !isAssociationBlocked(associationInfo.getId())) {
-                        mCrossDeviceSyncControllerCallback.updateNumberOfActiveSyncAssociations(
-                                associationInfo.getUserId(), /* added= */ true);
-                        mCrossDeviceSyncControllerCallback.requestCrossDeviceSync(associationInfo);
+                    if (!existingAssociations.contains(associationInfo)) {
+                        // New association.
+                        if (!isAssociationBlocked(associationInfo)) {
+                            final CrossDeviceSyncControllerCallback callback =
+                                    mInCallServiceCallbackRef != null
+                                            ? mInCallServiceCallbackRef.get() : null;
+                            if (callback != null) {
+                                callback.updateNumberOfActiveSyncAssociations(
+                                        associationInfo.getUserId(), /* added= */ true);
+                                callback.requestCrossDeviceSync(associationInfo);
+                            } else {
+                                Slog.w(TAG, "No callback to report new transport");
+                                syncMessageToDevice(associationInfo.getId(),
+                                        createFacilitatorMessage());
+                            }
+                        } else {
+                            mBlocklist.add(associationInfo.getId());
+                            Slog.i(TAG, "New association was blocked from context syncing");
+                        }
                     }
                 }
                 for (AssociationInfo associationInfo : existingAssociations) {
                     if (!newAssociations.contains(associationInfo)) {
-                        if (isAssociationBlocked(associationInfo.getId())) {
-                            mBlocklist.remove(associationInfo.getId());
-                        } else {
-                            mCrossDeviceSyncControllerCallback.updateNumberOfActiveSyncAssociations(
-                                    associationInfo.getUserId(), /* added= */ false);
+                        // Removed association!
+                        mBlocklist.remove(associationInfo.getId());
+                        if (!isAssociationBlockedLocal(associationInfo.getId())) {
+                            final CrossDeviceSyncControllerCallback callback =
+                                    mInCallServiceCallbackRef != null
+                                            ? mInCallServiceCallbackRef.get() : null;
+                            if (callback != null) {
+                                callback.updateNumberOfActiveSyncAssociations(
+                                        associationInfo.getUserId(), /* added= */ false);
+                            } else {
+                                Slog.w(TAG, "No callback to report removed transport");
+                            }
+                        }
+                    } else {
+                        // Stable association!
+                        final boolean systemBlocked = isAssociationBlocked(associationInfo);
+                        if (isAssociationBlockedLocal(associationInfo.getId()) != systemBlocked) {
+                            // Block state has changed.
+                            final CrossDeviceSyncControllerCallback callback =
+                                    mInCallServiceCallbackRef != null
+                                            ? mInCallServiceCallbackRef.get() : null;
+                            if (!systemBlocked) {
+                                Slog.i(TAG, "Unblocking existing association for context sync");
+                                mBlocklist.remove(associationInfo.getId());
+                                if (callback != null) {
+                                    callback.updateNumberOfActiveSyncAssociations(
+                                            associationInfo.getUserId(), /* added= */ true);
+                                    callback.requestCrossDeviceSync(associationInfo);
+                                } else {
+                                    Slog.w(TAG, "No callback to report changed transport");
+                                    syncMessageToDevice(associationInfo.getId(),
+                                            createFacilitatorMessage());
+                                }
+                            } else {
+                                Slog.i(TAG, "Blocking existing association for context sync");
+                                mBlocklist.add(associationInfo.getId());
+                                if (callback != null) {
+                                    callback.updateNumberOfActiveSyncAssociations(
+                                            associationInfo.getUserId(), /* added= */ false);
+                                } else {
+                                    Slog.w(TAG, "No callback to report changed transport");
+                                }
+                                // Send empty message to device to clear its data (otherwise it
+                                // will get stale)
+                                syncMessageToDevice(associationInfo.getId(),
+                                        createEmptyMessage());
+                            }
                         }
                     }
                 }
@@ -132,22 +197,76 @@
                 new IOnMessageReceivedListener.Stub() {
                     @Override
                     public void onMessageReceived(int associationId, byte[] data) {
+                        if (isAssociationBlockedLocal(associationId)) {
+                            return;
+                        }
                         final CallMetadataSyncData processedData = processTelecomDataFromSync(data);
                         mPhoneAccountManager.updateFacilitators(associationId, processedData);
-                        processCallCreateRequests(associationId, processedData);
-                        if (mCrossDeviceSyncControllerCallback == null) {
+                        mCallManager.updateCalls(associationId, processedData);
+                        processCallCreateRequests(processedData);
+                        if (mInCallServiceCallbackRef == null
+                                && mConnectionServiceCallbackRef == null) {
                             Slog.w(TAG, "No callback to process context sync message");
                             return;
                         }
-                        mCrossDeviceSyncControllerCallback.processContextSyncMessage(associationId,
-                                processedData);
+                        final CrossDeviceSyncControllerCallback inCallServiceCallback =
+                                mInCallServiceCallbackRef != null ? mInCallServiceCallbackRef.get()
+                                        : null;
+                        if (inCallServiceCallback != null) {
+                            inCallServiceCallback.processContextSyncMessage(associationId,
+                                    processedData);
+                        } else {
+                            // This is dead; get rid of it lazily
+                            mInCallServiceCallbackRef = null;
+                        }
+
+                        final CrossDeviceSyncControllerCallback connectionServiceCallback =
+                                mConnectionServiceCallbackRef != null
+                                        ? mConnectionServiceCallbackRef.get() : null;
+                        if (connectionServiceCallback != null) {
+                            connectionServiceCallback.processContextSyncMessage(associationId,
+                                    processedData);
+                        } else {
+                            // This is dead; get rid of it lazily
+                            mConnectionServiceCallbackRef = null;
+                        }
                     }
                 });
         mPhoneAccountManager = new PhoneAccountManager(mContext);
+        mCallManager = new CallManager(mContext, mPhoneAccountManager);
     }
 
-    private void processCallCreateRequests(int associationId,
-            CallMetadataSyncData callMetadataSyncData) {
+    private static boolean isAssociationBlocked(AssociationInfo info) {
+        return (info.getSystemDataSyncFlags() & CompanionDeviceManager.FLAG_CALL_METADATA)
+                != CompanionDeviceManager.FLAG_CALL_METADATA;
+    }
+
+    /** Invoke set-up tasks that happen when boot is completed. */
+    public void onBootCompleted() {
+        if (!CompanionDeviceConfig.isEnabled(CompanionDeviceConfig.ENABLE_CONTEXT_SYNC_TELECOM)) {
+            return;
+        }
+
+        mPhoneAccountManager.onBootCompleted();
+
+        final TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
+        if (telecomManager != null && telecomManager.getCallCapablePhoneAccounts().size() != 0) {
+            final PhoneAccountHandle defaultOutgoingTelAccountHandle =
+                    telecomManager.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL);
+            if (defaultOutgoingTelAccountHandle != null) {
+                final PhoneAccount defaultOutgoingTelAccount = telecomManager.getPhoneAccount(
+                        defaultOutgoingTelAccountHandle);
+                if (defaultOutgoingTelAccount != null) {
+                    mCallFacilitators.add(
+                            new CallMetadataSyncData.CallFacilitator(
+                                    defaultOutgoingTelAccount.getLabel().toString(),
+                                    FACILITATOR_ID_SYSTEM));
+                }
+            }
+        }
+    }
+
+    private void processCallCreateRequests(CallMetadataSyncData callMetadataSyncData) {
         final Iterator<CallMetadataSyncData.CallCreateRequest> iterator =
                 callMetadataSyncData.getCallCreateRequests().iterator();
         while (iterator.hasNext()) {
@@ -159,7 +278,7 @@
                     final Uri uri = Uri.fromParts(PhoneAccount.SCHEME_TEL,
                             request.getAddress().replaceAll("\\D+", ""), /* fragment= */ null);
                     final Bundle extras = new Bundle();
-                    extras.putString(CrossDeviceCall.EXTRA_CALL_ID, request.getId());
+                    extras.putString(EXTRA_CALL_ID, request.getId());
                     final Bundle outerExtras = new Bundle();
                     outerExtras.putParcelable(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, extras);
                     mContext.getSystemService(TelecomManager.class).placeCall(uri, outerExtras);
@@ -171,39 +290,33 @@
         }
     }
 
-    private boolean isAssociationBlocked(int associationId) {
+    /**
+     * This keeps track of "previous" state to calculate deltas. Use {@link #isAssociationBlocked}
+     * for all other use cases.
+     */
+    private boolean isAssociationBlockedLocal(int associationId) {
         return mBlocklist.contains(associationId);
     }
 
     /** Registers the call metadata callback. */
-    public void registerCallMetadataSyncCallback(CrossDeviceSyncControllerCallback callback) {
-        mCrossDeviceSyncControllerCallback = callback;
-        for (AssociationInfo associationInfo : mConnectedAssociations) {
-            if (!isAssociationBlocked(associationInfo.getId())) {
-                mCrossDeviceSyncControllerCallback.updateNumberOfActiveSyncAssociations(
-                        associationInfo.getUserId(), /* added= */ true);
-                mCrossDeviceSyncControllerCallback.requestCrossDeviceSync(associationInfo);
+    public void registerCallMetadataSyncCallback(CrossDeviceSyncControllerCallback callback,
+            @CrossDeviceSyncControllerCallback.Type int type) {
+        if (type == CrossDeviceSyncControllerCallback.TYPE_IN_CALL_SERVICE) {
+            mInCallServiceCallbackRef = new WeakReference<>(callback);
+            for (AssociationInfo associationInfo : mConnectedAssociations) {
+                if (!isAssociationBlocked(associationInfo)) {
+                    mBlocklist.remove(associationInfo.getId());
+                    callback.updateNumberOfActiveSyncAssociations(associationInfo.getUserId(),
+                            /* added= */ true);
+                    callback.requestCrossDeviceSync(associationInfo);
+                } else {
+                    mBlocklist.add(associationInfo.getId());
+                }
             }
-        }
-    }
-
-    /** Allow specific associated devices to enable / disable syncing. */
-    public void setSyncEnabled(AssociationInfo associationInfo, boolean enabled) {
-        if (enabled) {
-            if (isAssociationBlocked(associationInfo.getId())) {
-                mBlocklist.remove(associationInfo.getId());
-                mCrossDeviceSyncControllerCallback.updateNumberOfActiveSyncAssociations(
-                        associationInfo.getUserId(), /* added= */ true);
-                mCrossDeviceSyncControllerCallback.requestCrossDeviceSync(associationInfo);
-            }
+        } else if (type == CrossDeviceSyncControllerCallback.TYPE_CONNECTION_SERVICE) {
+            mConnectionServiceCallbackRef = new WeakReference<>(callback);
         } else {
-            if (!isAssociationBlocked(associationInfo.getId())) {
-                mBlocklist.add(associationInfo.getId());
-                mCrossDeviceSyncControllerCallback.updateNumberOfActiveSyncAssociations(
-                        associationInfo.getUserId(), /* added= */ false);
-                // Send empty message to device to clear its data (otherwise it will get stale)
-                syncMessageToDevice(associationInfo.getId(), createEmptyMessage());
-            }
+            Slog.e(TAG, "Cannot register callback of unknown type: " + type);
         }
     }
 
@@ -221,8 +334,7 @@
     public void syncToAllDevicesForUserId(int userId, Collection<CrossDeviceCall> calls) {
         final Set<Integer> associationIds = new HashSet<>();
         for (AssociationInfo associationInfo : mConnectedAssociations) {
-            if (associationInfo.getUserId() == userId && !isAssociationBlocked(
-                    associationInfo.getId())) {
+            if (associationInfo.getUserId() == userId && !isAssociationBlocked(associationInfo)) {
                 associationIds.add(associationInfo.getId());
             }
         }
@@ -244,7 +356,7 @@
      */
     public void syncToSingleDevice(AssociationInfo associationInfo,
             Collection<CrossDeviceCall> calls) {
-        if (isAssociationBlocked(associationInfo.getId())) {
+        if (isAssociationBlocked(associationInfo)) {
             Slog.e(TAG, "Cannot sync to requested device; connection is blocked");
             return;
         }
@@ -261,7 +373,7 @@
      * @param message         The message to sync.
      */
     public void syncMessageToDevice(int associationId, byte[] message) {
-        if (isAssociationBlocked(associationId)) {
+        if (isAssociationBlockedLocal(associationId)) {
             Slog.e(TAG, "Cannot sync to requested device; connection is blocked");
             return;
         }
@@ -466,6 +578,10 @@
         pos.write(ContextSyncMessage.VERSION, CURRENT_VERSION);
         final long telecomToken = pos.start(ContextSyncMessage.TELECOM);
         for (CrossDeviceCall call : calls) {
+            if (call.isCallPlacedByContextSync()) {
+                // Do not sync any calls which our "ours" as that would be duplicative.
+                continue;
+            }
             final long callsToken = pos.start(Telecom.CALLS);
             pos.write(Telecom.Call.ID, call.getId());
             final long originToken = pos.start(Telecom.Call.ORIGIN);
@@ -534,6 +650,50 @@
         return pos.getBytes();
     }
 
+    /** Create a facilitator-only message, used before any calls are available as a call intake. */
+    private byte[] createFacilitatorMessage() {
+        return createCallUpdateMessage(Collections.emptyList(), -1);
+    }
+
+    @VisibleForTesting
+    static class CallManager {
+
+        @VisibleForTesting final Map<Integer, Set<String>> mCallIds = new HashMap<>();
+        private final TelecomManager mTelecomManager;
+        private final PhoneAccountManager mPhoneAccountManager;
+
+        CallManager(Context context, PhoneAccountManager phoneAccountManager) {
+            mTelecomManager = context.getSystemService(TelecomManager.class);
+            mPhoneAccountManager = phoneAccountManager;
+        }
+
+        /** Add any new calls to Telecom. The ConnectionService will handle everything else. */
+        void updateCalls(int associationId, CallMetadataSyncData data) {
+            final Set<String> oldCallIds = mCallIds.getOrDefault(associationId, new HashSet<>());
+            final Set<String> newCallIds = data.getCalls().stream().map(
+                    CallMetadataSyncData.Call::getId).collect(Collectors.toSet());
+            if (oldCallIds.equals(newCallIds)) {
+                return;
+            }
+
+            for (CallMetadataSyncData.Call currentCall : data.getCalls()) {
+                if (!oldCallIds.contains(currentCall.getId())
+                        && currentCall.getFacilitator() != null) {
+                    final Bundle extras = new Bundle();
+                    extras.putInt(EXTRA_ASSOCIATION_ID, associationId);
+                    extras.putBoolean(EXTRA_IS_REMOTE_ORIGIN, true);
+                    extras.putParcelable(EXTRA_CALL, currentCall);
+                    extras.putString(EXTRA_CALL_ID, currentCall.getId());
+                    extras.putByteArray(EXTRA_FACILITATOR_ICON, currentCall.getAppIcon());
+                    final PhoneAccountHandle handle = mPhoneAccountManager.getPhoneAccountHandle(
+                            associationId, currentCall.getFacilitator().getIdentifier());
+                    mTelecomManager.addNewIncomingCall(handle, extras);
+                }
+            }
+            mCallIds.put(associationId, newCallIds);
+        }
+    }
+
     static class PhoneAccountManager {
         private final Map<PhoneAccountHandleIdentifier, PhoneAccountHandle> mPhoneAccountHandles =
                 new HashMap<>();
@@ -546,6 +706,10 @@
                     CallMetadataSyncConnectionService.class);
         }
 
+        void onBootCompleted() {
+            mTelecomManager.clearPhoneAccounts();
+        }
+
         PhoneAccountHandle getPhoneAccountHandle(int associationId, String appIdentifier) {
             return mPhoneAccountHandles.get(
                     new PhoneAccountHandleIdentifier(associationId, appIdentifier));
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerCallback.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerCallback.java
index 31e10a8..8a0ba27 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerCallback.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerCallback.java
@@ -16,11 +16,25 @@
 
 package com.android.server.companion.datatransfer.contextsync;
 
+import android.annotation.IntDef;
 import android.companion.AssociationInfo;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /** Callback for call metadata syncing. */
 public abstract class CrossDeviceSyncControllerCallback {
 
+    static final int TYPE_CONNECTION_SERVICE = 1;
+    static final int TYPE_IN_CALL_SERVICE = 2;
+    @IntDef(prefix = { "TYPE_" }, value = {
+            TYPE_CONNECTION_SERVICE,
+            TYPE_IN_CALL_SERVICE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {
+    }
+
     void processContextSyncMessage(int associationId, CallMetadataSyncData callMetadataSyncData) {}
 
     void requestCrossDeviceSync(AssociationInfo associationInfo) {}
diff --git a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
index 0457e9a..5a3db4b 100644
--- a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
+++ b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
@@ -53,8 +53,6 @@
     private static final int VERSION = 1;
     private static final int HEADER_LENGTH = 6;
 
-    private static final String HANDSHAKE_PROTOCOL = "AES_256_CBC-HMAC_SHA256";
-
     private final InputStream mInput;
     private final OutputStream mOutput;
     private final Callback mCallback;
@@ -62,14 +60,16 @@
     private final AttestationVerifier mVerifier;
 
     private volatile boolean mStopped;
-    private boolean mInProgress;
+    private volatile boolean mInProgress;
 
     private Role mRole;
+    private byte[] mClientInit;
     private D2DHandshakeContext mHandshakeContext;
     private D2DConnectionContextV1 mConnectionContext;
 
     private String mAlias;
     private int mVerificationResult;
+    private boolean mPskVerified;
 
 
     /**
@@ -202,8 +202,8 @@
         }
 
         try {
-            initiateHandshake();
             mInProgress = true;
+            initiateHandshake();
         } catch (BadHandleException e) {
             throw new SecureChannelException("Failed to initiate handshake protocol.", e);
         }
@@ -329,12 +329,56 @@
 
         mRole = Role.Initiator;
         mHandshakeContext = D2DHandshakeContext.forInitiator();
+        mClientInit = mHandshakeContext.getNextHandshakeMessage();
 
         // Send Client Init
         if (DEBUG) {
             Slog.d(TAG, "Sending Ukey2 Client Init message");
         }
-        sendMessage(MessageType.HANDSHAKE_INIT, mHandshakeContext.getNextHandshakeMessage());
+        sendMessage(MessageType.HANDSHAKE_INIT, constructHandshakeInitMessage(mClientInit));
+    }
+
+    // In an occasion where both participants try to initiate a handshake, resolve the conflict
+    // with a dice roll simulated by the message byte content comparison.
+    // The higher value wins! (a.k.a. gets to be the initiator)
+    private byte[] handleHandshakeCollision(byte[] handshakeInitMessage)
+            throws IOException, HandshakeException, BadHandleException, CryptoException {
+
+        // First byte indicates message type; 0 = CLIENT INIT, 1 = SERVER INIT
+        ByteBuffer buffer = ByteBuffer.wrap(handshakeInitMessage);
+        boolean isClientInit = buffer.get() == 0;
+        byte[] handshakeMessage = new byte[buffer.remaining()];
+        buffer.get(handshakeMessage);
+
+        // If received message is Server Init or current role is Responder, then there was
+        // no collision. Return extracted handshake message.
+        if (mHandshakeContext == null || !isClientInit) {
+            return handshakeMessage;
+        }
+
+        Slog.w(TAG, "Detected a Ukey2 handshake role collision. Negotiating a role.");
+
+        // if received message is "larger" than the sent message, then reset the handshake context.
+        if (compareByteArray(mClientInit, handshakeMessage) < 0) {
+            Slog.d(TAG, "Assigned: Responder");
+            mHandshakeContext = null;
+            return handshakeMessage;
+        } else {
+            Slog.d(TAG, "Assigned: Initiator; Discarding received Client Init");
+
+            // Wait for another init message after discarding the client init
+            ByteBuffer nextInitMessage = ByteBuffer.wrap(readMessage(MessageType.HANDSHAKE_INIT));
+
+            // Throw if this message is a Client Init again; 0 = CLIENT INIT, 1 = SERVER INIT
+            if (nextInitMessage.get() == 0) {
+                // This should never happen!
+                throw new HandshakeException("Failed to resolve Ukey2 handshake role collision.");
+            }
+            byte[] nextHandshakeMessage = new byte[nextInitMessage.remaining()];
+            nextInitMessage.get(nextHandshakeMessage);
+
+            return nextHandshakeMessage;
+        }
     }
 
     private void exchangeHandshake()
@@ -345,8 +389,15 @@
         }
 
         // Waiting for message
-        byte[] handshakeMessage = readMessage(MessageType.HANDSHAKE_INIT);
+        byte[] handshakeInitMessage = readMessage(MessageType.HANDSHAKE_INIT);
 
+        // Mark "in-progress" upon receiving the first message
+        mInProgress = true;
+
+        // Handle a potential collision where both devices tried to initiate a connection
+        byte[] handshakeMessage = handleHandshakeCollision(handshakeInitMessage);
+
+        // Proceed with the rest of Ukey2 handshake
         if (mHandshakeContext == null) { // Server-side logic
             mRole = Role.Responder;
             mHandshakeContext = D2DHandshakeContext.forResponder();
@@ -361,7 +412,8 @@
             if (DEBUG) {
                 Slog.d(TAG, "Sending Ukey2 Server Init message");
             }
-            sendMessage(MessageType.HANDSHAKE_INIT, mHandshakeContext.getNextHandshakeMessage());
+            sendMessage(MessageType.HANDSHAKE_INIT,
+                    constructHandshakeInitMessage(mHandshakeContext.getNextHandshakeMessage()));
 
             // Receive Client Finish
             if (DEBUG) {
@@ -418,9 +470,9 @@
                 ? Role.Responder
                 : Role.Initiator,
                 mPreSharedKey);
-        boolean authenticated = Arrays.equals(receivedAuthToken, expectedAuthToken);
+        mPskVerified = Arrays.equals(receivedAuthToken, expectedAuthToken);
 
-        if (!authenticated) {
+        if (!mPskVerified) {
             throw new SecureChannelException("Failed to verify the hash of pre-shared key.");
         }
 
@@ -477,10 +529,21 @@
     }
 
     private boolean isSecured() {
+        // Is ukey-2 encrypted
         if (mConnectionContext == null) {
             return false;
         }
-        return mVerifier == null || mVerificationResult == RESULT_SUCCESS;
+        // Is authenticated
+        return mPskVerified || mVerificationResult == RESULT_SUCCESS;
+    }
+
+    // First byte indicates message type; 0 = CLIENT INIT, 1 = SERVER INIT
+    // This information is needed to help resolve potential role collision.
+    private byte[] constructHandshakeInitMessage(byte[] message) {
+        return ByteBuffer.allocate(1 + message.length)
+                .put((byte) (Role.Initiator.equals(mRole) ? 0 : 1))
+                .put(message)
+                .array();
     }
 
     private byte[] constructToken(D2DHandshakeContext.Role role, byte[] authValue)
@@ -494,6 +557,22 @@
                 .array());
     }
 
+    // Arbitrary comparator
+    private int compareByteArray(byte[] a, byte[] b) {
+        if (a == b) {
+            return 0;
+        }
+        if (a.length != b.length) {
+            return a.length - b.length;
+        }
+        for (int i = 0; i < a.length; i++) {
+            if (a[i] != b[i]) {
+                return a[i] - b[i];
+            }
+        }
+        return 0;
+    }
+
     private String generateAlias() {
         String alias;
         do {
diff --git a/services/companion/java/com/android/server/companion/transport/SecureTransport.java b/services/companion/java/com/android/server/companion/transport/SecureTransport.java
index 949f39a..2d856b9 100644
--- a/services/companion/java/com/android/server/companion/transport/SecureTransport.java
+++ b/services/companion/java/com/android/server/companion/transport/SecureTransport.java
@@ -29,7 +29,6 @@
 import java.nio.ByteBuffer;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Future;
 
 class SecureTransport extends Transport implements SecureChannel.Callback {
     private final SecureChannel mSecureChannel;
@@ -68,24 +67,13 @@
     }
 
     @Override
-    public Future<byte[]> requestForResponse(int message, byte[] data) {
-        // Check if channel is secured and start securing
-        if (!mShouldProcessRequests) {
-            Slog.d(TAG, "Establishing secure connection.");
-            try {
-                mSecureChannel.establishSecureConnection();
-            } catch (Exception e) {
-                Slog.w(TAG, "Failed to initiate secure channel handshake.", e);
-                onError(e);
-            }
-        }
-
-        return super.requestForResponse(message, data);
-    }
-
-    @Override
     protected void sendMessage(int message, int sequence, @NonNull byte[] data)
             throws IOException {
+        // Check if channel is secured; otherwise start securing
+        if (!mShouldProcessRequests) {
+            establishSecureConnection();
+        }
+
         if (DEBUG) {
             Slog.d(TAG, "Queueing message 0x" + Integer.toHexString(message)
                     + " sequence " + sequence + " length " + data.length
@@ -103,6 +91,16 @@
         }
     }
 
+    private void establishSecureConnection() {
+        Slog.d(TAG, "Establishing secure connection.");
+        try {
+            mSecureChannel.establishSecureConnection();
+        } catch (Exception e) {
+            Slog.w(TAG, "Failed to initiate secure channel handshake.", e);
+            onError(e);
+        }
+    }
+
     @Override
     public void onSecureConnection() {
         mShouldProcessRequests = true;
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index ad4c0bf..e9b9980 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -55,6 +55,7 @@
 import android.view.Display;
 import android.widget.Toast;
 
+import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.DumpUtils;
@@ -156,7 +157,7 @@
             VirtualDeviceImpl virtualDevice = virtualDevicesSnapshot.get(i);
             virtualDevice.showToastWhereUidIsRunning(appUid,
                     getContext().getString(
-                            com.android.internal.R.string.vdm_camera_access_denied,
+                            R.string.vdm_camera_access_denied,
                             virtualDevice.getDisplayName()),
                     Toast.LENGTH_LONG, Looper.myLooper());
         }
@@ -623,6 +624,18 @@
         }
 
         @Override
+        public void onAuthenticationPrompt(int uid) {
+            synchronized (mVirtualDeviceManagerLock) {
+                for (int i = 0; i < mVirtualDevices.size(); i++) {
+                    VirtualDeviceImpl device = mVirtualDevices.valueAt(i);
+                    device.showToastWhereUidIsRunning(uid,
+                            R.string.app_streaming_blocked_message_for_fingerprint_dialog,
+                            Toast.LENGTH_LONG, Looper.getMainLooper());
+                }
+            }
+        }
+
+        @Override
         public int getBaseVirtualDisplayFlags(IVirtualDevice virtualDevice) {
             return ((VirtualDeviceImpl) virtualDevice).getBaseVirtualDisplayFlags();
         }
diff --git a/services/core/java/com/android/server/DockObserver.java b/services/core/java/com/android/server/DockObserver.java
index 5156c54..fb527c1 100644
--- a/services/core/java/com/android/server/DockObserver.java
+++ b/services/core/java/com/android/server/DockObserver.java
@@ -37,6 +37,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.DumpUtils;
+import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.ExtconUEventObserver.ExtconInfo;
 
 import java.io.FileDescriptor;
@@ -195,6 +196,8 @@
     @Override
     public void onStart() {
         publishBinderService(TAG, new BinderService());
+        // Logs dock state after setDockStateFromProviderLocked sets mReportedDockState
+        FrameworkStatsLog.write(FrameworkStatsLog.DOCK_STATE_CHANGED, mReportedDockState);
     }
 
     @Override
@@ -256,7 +259,6 @@
                     + mReportedDockState);
             final int previousDockState = mPreviousDockState;
             mPreviousDockState = mReportedDockState;
-
             // Skip the dock intent if not yet provisioned.
             final ContentResolver cr = getContext().getContentResolver();
             if (!mDeviceProvisionedObserver.isDeviceProvisioned()) {
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index c3dda71..ae095b5 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -71,6 +71,11 @@
                     "exclude-annotation": "org.junit.Ignore"
                 }
             ]
+        },
+        {
+            // GWP-ASan's CTS test ensures that recoverable tombstones work,
+            // which is emitted by the NativeTombstoneManager.
+            "name": "CtsGwpAsanTestCases"
         }
     ],
     "presubmit-large": [
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 96766a2..31d60f2 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -262,8 +262,7 @@
     private static final boolean DEBUG_DELAYED_SERVICE = DEBUG_SERVICE;
     private static final boolean DEBUG_DELAYED_STARTS = DEBUG_DELAYED_SERVICE;
 
-    // STOPSHIP(b/260012573) turn it off.
-    private static final boolean DEBUG_SHORT_SERVICE = true; // DEBUG_SERVICE;
+    private static final boolean DEBUG_SHORT_SERVICE = DEBUG_SERVICE;
 
     private static final boolean LOG_SERVICE_START_STOP = DEBUG_SERVICE;
 
@@ -2215,6 +2214,8 @@
                         }
                     }
 
+                    boolean resetNeededForLogging = false;
+
                     // Re-evaluate mAllowWhileInUsePermissionInFgs and mAllowStartForeground
                     // (i.e. while-in-use and BFSL flags) if needed.
                     //
@@ -2297,8 +2298,22 @@
                                 !r.isForeground
                                 && delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs;
                         if (resetNeeded) {
-                            resetFgsRestrictionLocked(r);
+                            // We don't want to reset mDebugWhileInUseReasonInBindService here --
+                            // we'll instead reset it in the following code, using the simulated
+                            // legacy logic.
+                            resetFgsRestrictionLocked(r,
+                                    /*resetDebugWhileInUseReasonInBindService=*/ false);
                         }
+
+                        // Simulate the reset flow in the legacy logic to reset
+                        // mDebugWhileInUseReasonInBindService.
+                        // (Which is only used to compare to the old logic.)
+                        final long legacyDelayMs = SystemClock.elapsedRealtime() - r.createRealTime;
+                        if ((r.mStartForegroundCount == 0)
+                                && (legacyDelayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs)) {
+                            r.mDebugWhileInUseReasonInBindService = REASON_DENIED;
+                        }
+
                         setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(),
                                 r.appInfo.uid, r.intent.getIntent(), r, r.userId,
                                 BackgroundStartPrivileges.NONE,
@@ -2315,12 +2330,24 @@
                             r.mInfoAllowStartForeground = temp;
                         }
                         r.mLoggedInfoAllowStartForeground = false;
+
+                        resetNeededForLogging = resetNeeded;
                     }
 
                     // If the service has any bindings and it's not yet a FGS
                     // we compare the new and old while-in-use logics.
                     // (If it's not the first startForeground() call, we already reset the
                     // while-in-use and BFSL flags, so the logic change wouldn't matter.)
+                    //
+                    // Note, mDebugWhileInUseReasonInBindService does *not* fully simulate the
+                    // legacy logic, because we'll only set it in bindService(), but the actual
+                    // mAllowWhileInUsePermissionInFgsReason can change afterwards, in a subsequent
+                    // Service.startForeground(). This check will only provide "rough" check.
+                    // But if mDebugWhileInUseReasonInBindService is _not_ DENIED, and
+                    // mDebugWhileInUseReasonInStartForeground _is_ DENIED, then that means we'd
+                    // now detected a behavior change.
+                    // OTOH, if it's changing from non-DENIED to another non-DENIED, that may
+                    // not be a problem.
                     if (enableFgsWhileInUseFix
                             && !r.isForeground
                             && (r.getConnections().size() > 0)
@@ -2330,6 +2357,10 @@
                                 + reasonCodeToString(r.mDebugWhileInUseReasonInBindService)
                                 + " new="
                                 + reasonCodeToString(r.mDebugWhileInUseReasonInStartForeground)
+                                + " startForegroundCount=" + r.mStartForegroundCount
+                                + " started=" + r.startRequested
+                                + " num_bindings=" + r.getConnections().size()
+                                + " resetNeeded=" + resetNeededForLogging
                                 + " "
                                 + r.shortInstanceName);
                     }
@@ -2668,7 +2699,10 @@
                         + " code=" + code
                         + " callerApp=" + r.app
                         + " targetSDK=" + r.app.info.targetSdkVersion
-                        + " requiredPermissions=" + policyInfo.toPermissionString();
+                        + " requiredPermissions=" + policyInfo.toPermissionString()
+                        + (policyInfo.hasForegroundOnlyPermission()
+                        ? " and the app must be in the eligible state/exemptions"
+                        + " to access the foreground only permission" : "");
                 Slog.wtfQuiet(TAG, msg);
                 Slog.w(TAG, msg);
             } break;
@@ -2678,7 +2712,10 @@
                         + " callerApp=" + r.app
                         + " targetSDK=" + r.app.info.targetSdkVersion
                         + " requires permissions: "
-                        + policyInfo.toPermissionString());
+                        + policyInfo.toPermissionString()
+                        + (policyInfo.hasForegroundOnlyPermission()
+                        ? " and the app must be in the eligible state/exemptions"
+                        + " to access the foreground only permission" : ""));
             } break;
             case FGS_TYPE_POLICY_CHECK_OK:
             default:
@@ -4504,10 +4541,11 @@
                         + ", uid=" + callingUid
                         + " requires " + r.permission);
                 return new ServiceLookupResult(r.permission);
-            } else if (Manifest.permission.BIND_HOTWORD_DETECTION_SERVICE.equals(r.permission)
+            } else if ((Manifest.permission.BIND_HOTWORD_DETECTION_SERVICE.equals(r.permission)
+                    || Manifest.permission.BIND_VISUAL_QUERY_DETECTION_SERVICE.equals(r.permission))
                     && callingUid != Process.SYSTEM_UID) {
-                // Hotword detection must run in its own sandbox, and we don't even trust
-                // its enclosing application to bind to it - only the system.
+                // Hotword detection and visual query detection must run in its own sandbox, and we
+                // don't even trust its enclosing application to bind to it - only the system.
                 // TODO(b/185746653) remove this special case and generalize
                 Slog.w(TAG, "Permission Denial: Accessing service " + r.shortInstanceName
                         + " from pid=" + callingPid
@@ -5243,6 +5281,7 @@
                     final IApplicationThread thread = app.getThread();
                     final int pid = app.getPid();
                     final UidRecord uidRecord = app.getUidRecord();
+                    r.isolationHostProc = app;
                     if (thread != null) {
                         try {
                             if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
@@ -7567,15 +7606,27 @@
         }
     }
 
+    /**
+     * Reset various while-in-use and BFSL related information.
+     */
     void resetFgsRestrictionLocked(ServiceRecord r) {
+        resetFgsRestrictionLocked(r, /*resetDebugWhileInUseReasonInBindService=*/ true);
+    }
+
+    /**
+     * Reset various while-in-use and BFSL related information.
+     */
+    void resetFgsRestrictionLocked(ServiceRecord r,
+            boolean resetDebugWhileInUseReasonInBindService) {
         r.mAllowWhileInUsePermissionInFgs = false;
         r.mAllowWhileInUsePermissionInFgsReason = REASON_DENIED;
         r.mDebugWhileInUseReasonInStartForeground = REASON_DENIED;
-        // We don't reset mWhileInUseReasonInBindService here, because if we do this, we would
-        // lose it in the "reevaluation" case in startForeground(), where we call
-        // resetFgsRestrictionLocked().
-        // Not resetting this is fine because it's only used in the first Service.startForeground()
-        // case, and there's no situations where we call resetFgsRestrictionLocked() before that.
+
+        // In Service.startForeground(), we reset this field using a legacy logic,
+        // so resetting this field is optional.
+        if (resetDebugWhileInUseReasonInBindService) {
+            r.mDebugWhileInUseReasonInBindService = REASON_DENIED;
+        }
         r.mAllowStartForeground = REASON_DENIED;
         r.mInfoAllowStartForeground = null;
         r.mInfoTempFgsAllowListReason = null;
@@ -8251,7 +8302,9 @@
                 mAm.getUidStateLocked(r.appInfo.uid),
                 mAm.getUidProcessCapabilityLocked(r.appInfo.uid),
                 mAm.getUidStateLocked(r.mRecentCallingUid),
-                mAm.getUidProcessCapabilityLocked(r.mRecentCallingUid));
+                mAm.getUidProcessCapabilityLocked(r.mRecentCallingUid),
+                0,
+                0);
 
         int event = 0;
         if (state == FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER) {
@@ -8426,6 +8479,9 @@
                 true, false, null, false,
                 AppOpsManager.ATTRIBUTION_FLAGS_NONE, AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE);
         registerAppOpCallbackLocked(r);
+        synchronized (mFGSLogger) {
+            mFGSLogger.logForegroundServiceStart(r.appInfo.uid, 0, r);
+        }
         logFGSStateChangeLocked(r,
                 FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER,
                 0, FGS_STOP_REASON_UNKNOWN, FGS_TYPE_POLICY_CHECK_UNKNOWN);
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 3841b6a..3b44633 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -1061,7 +1061,7 @@
     private static final String KEY_ENABLE_FGS_WHILE_IN_USE_FIX =
             "key_enable_fgs_while_in_use_fix";
 
-    private static final boolean DEFAULT_ENABLE_FGS_WHILE_IN_USE_FIX = true;
+    private static final boolean DEFAULT_ENABLE_FGS_WHILE_IN_USE_FIX = false;
 
     public volatile boolean mEnableFgsWhileInUseFix = DEFAULT_ENABLE_FGS_WHILE_IN_USE_FIX;
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 658e664..3d02c96 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1175,17 +1175,21 @@
     static final class StickyBroadcast {
         public Intent intent;
         public boolean deferUntilActive;
+        public int originalCallingUid;
 
-        public static StickyBroadcast create(Intent intent, boolean deferUntilActive) {
+        public static StickyBroadcast create(Intent intent, boolean deferUntilActive,
+                int originalCallingUid) {
             final StickyBroadcast b = new StickyBroadcast();
             b.intent = intent;
             b.deferUntilActive = deferUntilActive;
+            b.originalCallingUid = originalCallingUid;
             return b;
         }
 
         @Override
         public String toString() {
-            return "{intent=" + intent + ", defer=" + deferUntilActive + "}";
+            return "{intent=" + intent + ", defer=" + deferUntilActive + ", originalCallingUid="
+                    + originalCallingUid + "}";
         }
     }
 
@@ -11119,6 +11123,9 @@
                                 pw.print(" [D]");
                             }
                             pw.println();
+                            pw.print("      originalCallingUid: ");
+                            pw.println(broadcasts.get(i).originalCallingUid);
+                            pw.println();
                             Bundle bundle = intent.getExtras();
                             if (bundle != null) {
                                 pw.print("      extras: ");
@@ -14008,16 +14015,25 @@
             if (allSticky != null) {
                 ArrayList receivers = new ArrayList();
                 receivers.add(bf);
+                sticky = null;
 
                 final int stickyCount = allSticky.size();
                 for (int i = 0; i < stickyCount; i++) {
                     final StickyBroadcast broadcast = allSticky.get(i);
+                    final int originalStickyCallingUid = allSticky.get(i).originalCallingUid;
+                    // TODO(b/281889567): consider using checkComponentPermission instead of
+                    //  canAccessUnexportedComponents
+                    if (sticky == null && (exported || originalStickyCallingUid == callingUid
+                            || ActivityManager.canAccessUnexportedComponents(
+                            originalStickyCallingUid))) {
+                        sticky = broadcast.intent;
+                    }
                     BroadcastQueue queue = broadcastQueueForIntent(broadcast.intent);
                     BroadcastRecord r = new BroadcastRecord(queue, broadcast.intent, null,
                             null, null, -1, -1, false, null, null, null, null, OP_NONE,
                             BroadcastOptions.makeWithDeferUntilActive(broadcast.deferUntilActive),
                             receivers, null, null, 0, null, null, false, true, true, -1,
-                            BackgroundStartPrivileges.NONE,
+                            originalStickyCallingUid, BackgroundStartPrivileges.NONE,
                             false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */,
                             null /* filterExtrasForReceiver */);
                     queue.enqueueBroadcastLocked(r);
@@ -14895,12 +14911,13 @@
             for (i = 0; i < stickiesCount; i++) {
                 if (intent.filterEquals(list.get(i).intent)) {
                     // This sticky already exists, replace it.
-                    list.set(i, StickyBroadcast.create(new Intent(intent), deferUntilActive));
+                    list.set(i, StickyBroadcast.create(new Intent(intent), deferUntilActive,
+                            callingUid));
                     break;
                 }
             }
             if (i >= stickiesCount) {
-                list.add(StickyBroadcast.create(new Intent(intent), deferUntilActive));
+                list.add(StickyBroadcast.create(new Intent(intent), deferUntilActive, callingUid));
             }
         }
 
@@ -18324,16 +18341,17 @@
         @Override
         public boolean hasRunningForegroundService(int uid, int foregroundServicetype) {
             synchronized (ActivityManagerService.this) {
-                return mProcessList.searchEachLruProcessesLOSP(true, app -> {
-                    if (app.uid != uid) {
-                        return null;
-                    }
-
+                final UidRecord uidRec = mProcessList.mActiveUids.get(uid);
+                if (uidRec == null) {
+                    return false;
+                }
+                for (int i = uidRec.getNumOfProcs() - 1; i >= 0; i--) {
+                    final ProcessRecord app = uidRec.getProcessRecordByIndex(i);
                     if ((app.mServices.containsAnyForegroundServiceTypes(foregroundServicetype))) {
-                        return Boolean.TRUE;
+                        return true;
                     }
-                    return null;
-                }) != null;
+                }
+                return false;
             }
         }
 
@@ -18877,12 +18895,14 @@
 
     @Override
     public void waitForBroadcastIdle() {
-        waitForBroadcastIdle(LOG_WRITER_INFO);
+        waitForBroadcastIdle(LOG_WRITER_INFO, false);
     }
 
-    public void waitForBroadcastIdle(@NonNull PrintWriter pw) {
+    void waitForBroadcastIdle(@NonNull PrintWriter pw, boolean flushBroadcastLoopers) {
         enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
-        BroadcastLoopers.waitForIdle(pw);
+        if (flushBroadcastLoopers) {
+            BroadcastLoopers.waitForIdle(pw);
+        }
         for (BroadcastQueue queue : mBroadcastQueues) {
             queue.waitForIdle(pw);
         }
@@ -18895,7 +18915,7 @@
         waitForBroadcastBarrier(LOG_WRITER_INFO, false, false);
     }
 
-    public void waitForBroadcastBarrier(@NonNull PrintWriter pw,
+    void waitForBroadcastBarrier(@NonNull PrintWriter pw,
             boolean flushBroadcastLoopers, boolean flushApplicationThreads) {
         enforceCallingPermission(permission.DUMP, "waitForBroadcastBarrier()");
         if (flushBroadcastLoopers) {
@@ -18913,7 +18933,7 @@
      * Wait for all pending {@link IApplicationThread} events to be processed in
      * all currently running apps.
      */
-    public void waitForApplicationBarrier(@NonNull PrintWriter pw) {
+    void waitForApplicationBarrier(@NonNull PrintWriter pw) {
         final CountDownLatch finishedLatch = new CountDownLatch(1);
         final AtomicInteger pingCount = new AtomicInteger(0);
         final AtomicInteger pongCount = new AtomicInteger(0);
@@ -19018,8 +19038,11 @@
             long delayedDurationMs) {
         Objects.requireNonNull(targetPackage);
         Preconditions.checkArgumentNonnegative(delayedDurationMs);
-        Preconditions.checkState(mEnableModernQueue, "Not valid in legacy queue");
         enforceCallingPermission(permission.DUMP, "forceDelayBroadcastDelivery()");
+        // Ignore request if modern queue is not enabled
+        if (!mEnableModernQueue) {
+            return;
+        }
 
         for (BroadcastQueue queue : mBroadcastQueues) {
             queue.forceDelayBroadcastDelivery(targetPackage, delayedDurationMs);
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 8759e3f..add22bd 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -918,6 +918,7 @@
     }
 
     int runSendBroadcast(PrintWriter pw) throws RemoteException {
+        pw = new PrintWriter(new TeeWriter(LOG_WRITER_INFO, pw));
         Intent intent;
         try {
             intent = makeIntent(UserHandle.USER_CURRENT);
@@ -931,9 +932,10 @@
         pw.println("Broadcasting: " + intent);
         pw.flush();
         Bundle bundle = mBroadcastOptions == null ? null : mBroadcastOptions.toBundle();
-        mInterface.broadcastIntentWithFeature(null, null, intent, null, receiver, 0, null, null,
-                requiredPermissions, null, null, android.app.AppOpsManager.OP_NONE, bundle, true,
-                false, mUserId);
+        final int result = mInterface.broadcastIntentWithFeature(null, null, intent, null,
+                receiver, 0, null, null, requiredPermissions, null, null,
+                android.app.AppOpsManager.OP_NONE, bundle, true, false, mUserId);
+        Slogf.i(TAG, "Broadcasted %s: " + result, intent);
         if (!mAsync) {
             receiver.waitForFinish();
         }
@@ -3445,7 +3447,17 @@
 
     int runWaitForBroadcastIdle(PrintWriter pw) throws RemoteException {
         pw = new PrintWriter(new TeeWriter(LOG_WRITER_INFO, pw));
-        mInternal.waitForBroadcastIdle(pw);
+        boolean flushBroadcastLoopers = false;
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            if (opt.equals("--flush-broadcast-loopers")) {
+                flushBroadcastLoopers = true;
+            } else {
+                getErrPrintWriter().println("Error: Unknown option: " + opt);
+                return -1;
+            }
+        }
+        mInternal.waitForBroadcastIdle(pw, flushBroadcastLoopers);
         return 0;
     }
 
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index 05e1370..16f2226 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -1202,6 +1202,14 @@
 
         mCachedAppsWatermarkData.updateCachedAppsHighWatermarkIfNecessaryLocked(
                 numCached + numEmpty, now);
+        boolean allChanged;
+        int trackerMemFactor;
+        synchronized (mService.mProcessStats.mLock) {
+            allChanged = mService.mProcessStats.setMemFactorLocked(memFactor,
+                    mService.mAtmInternal == null || !mService.mAtmInternal.isSleeping(),
+                    SystemClock.uptimeMillis() /* re-acquire the time within the lock */);
+            trackerMemFactor = mService.mProcessStats.getMemFactorLocked();
+        }
 
         if (mService.mConstants.USE_MODERN_TRIM) {
             // Modern trim is not sent based on lowmem state
@@ -1235,14 +1243,6 @@
 
         mLastMemoryLevel = memFactor;
         mLastNumProcesses = mService.mProcessList.getLruSizeLOSP();
-        boolean allChanged;
-        int trackerMemFactor;
-        synchronized (mService.mProcessStats.mLock) {
-            allChanged = mService.mProcessStats.setMemFactorLocked(memFactor,
-                    mService.mAtmInternal == null || !mService.mAtmInternal.isSleeping(),
-                    SystemClock.uptimeMillis() /* re-acquire the time within the lock */);
-            trackerMemFactor = mService.mProcessStats.getMemFactorLocked();
-        }
         if (memFactor != ADJ_MEM_FACTOR_NORMAL) {
             if (mLowRamStartTime == 0) {
                 mLowRamStartTime = now;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 36da888..dc6f858 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -2287,34 +2287,6 @@
         }
     }
 
-    /**
-     * Bluetooth on stat logging
-     */
-    @Override
-    @EnforcePermission(BLUETOOTH_CONNECT)
-    public void noteBluetoothOn(int uid, int reason, String packageName) {
-        super.noteBluetoothOn_enforcePermission();
-
-        FrameworkStatsLog.write_non_chained(FrameworkStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED,
-                Binder.getCallingUid(), null,
-                FrameworkStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__ENABLED,
-                reason, packageName);
-    }
-
-    /**
-     * Bluetooth off stat logging
-     */
-    @Override
-    @EnforcePermission(BLUETOOTH_CONNECT)
-    public void noteBluetoothOff(int uid, int reason, String packageName) {
-        super.noteBluetoothOff_enforcePermission();
-
-        FrameworkStatsLog.write_non_chained(FrameworkStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED,
-                Binder.getCallingUid(), null,
-                FrameworkStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__DISABLED,
-                reason, packageName);
-    }
-
     @Override
     @EnforcePermission(UPDATE_DEVICE_STATS)
     public void noteBleScanStarted(final WorkSource ws, final boolean isUnoptimized) {
diff --git a/services/core/java/com/android/server/am/BroadcastConstants.java b/services/core/java/com/android/server/am/BroadcastConstants.java
index 87214de..8c1fd51 100644
--- a/services/core/java/com/android/server/am/BroadcastConstants.java
+++ b/services/core/java/com/android/server/am/BroadcastConstants.java
@@ -247,6 +247,26 @@
     private static final long DEFAULT_DELAY_URGENT_MILLIS = -120_000;
 
     /**
+     * For {@link BroadcastQueueModernImpl}: Delay to apply to broadcasts to
+     * foreground processes, typically a negative value to indicate they should be
+     * executed before most other pending broadcasts.
+     */
+    public long DELAY_FOREGROUND_PROC_MILLIS = DEFAULT_DELAY_FOREGROUND_PROC_MILLIS;
+    private static final String KEY_DELAY_FOREGROUND_PROC_MILLIS =
+            "bcast_delay_foreground_proc_millis";
+    private static final long DEFAULT_DELAY_FOREGROUND_PROC_MILLIS = -120_000;
+
+    /**
+     * For {@link BroadcastQueueModernImpl}: Delay to apply to broadcasts to
+     * persistent processes, typically a negative value to indicate they should be
+     * executed before most other pending broadcasts.
+     */
+    public long DELAY_PERSISTENT_PROC_MILLIS = DEFAULT_DELAY_FOREGROUND_PROC_MILLIS;
+    private static final String KEY_DELAY_PERSISTENT_PROC_MILLIS =
+            "bcast_delay_persistent_proc_millis";
+    private static final long DEFAULT_DELAY_PERSISTENT_PROC_MILLIS = -120_000;
+
+    /**
      * For {@link BroadcastQueueModernImpl}: Maximum number of complete
      * historical broadcasts to retain for debugging purposes.
      */
@@ -272,6 +292,15 @@
     private static final String KEY_CORE_DEFER_UNTIL_ACTIVE = "bcast_core_defer_until_active";
     private static final boolean DEFAULT_CORE_DEFER_UNTIL_ACTIVE = true;
 
+    /**
+     * For {@link BroadcastQueueModernImpl}: How frequently we should check for the pending
+     * cold start validity.
+     */
+    public long PENDING_COLD_START_CHECK_INTERVAL_MILLIS = 30 * 1000;
+    private static final String KEY_PENDING_COLD_START_CHECK_INTERVAL_MILLIS =
+            "pending_cold_start_check_interval_millis";
+    private static final long DEFAULT_PENDING_COLD_START_CHECK_INTERVAL_MILLIS = 30_000;
+
     // Settings override tracking for this instance
     private String mSettingsKey;
     private SettingsObserver mSettingsObserver;
@@ -411,12 +440,19 @@
                     DEFAULT_DELAY_CACHED_MILLIS);
             DELAY_URGENT_MILLIS = getDeviceConfigLong(KEY_DELAY_URGENT_MILLIS,
                     DEFAULT_DELAY_URGENT_MILLIS);
+            DELAY_FOREGROUND_PROC_MILLIS = getDeviceConfigLong(KEY_DELAY_FOREGROUND_PROC_MILLIS,
+                    DEFAULT_DELAY_FOREGROUND_PROC_MILLIS);
+            DELAY_PERSISTENT_PROC_MILLIS = getDeviceConfigLong(KEY_DELAY_PERSISTENT_PROC_MILLIS,
+                    DEFAULT_DELAY_PERSISTENT_PROC_MILLIS);
             MAX_HISTORY_COMPLETE_SIZE = getDeviceConfigInt(KEY_MAX_HISTORY_COMPLETE_SIZE,
                     DEFAULT_MAX_HISTORY_COMPLETE_SIZE);
             MAX_HISTORY_SUMMARY_SIZE = getDeviceConfigInt(KEY_MAX_HISTORY_SUMMARY_SIZE,
                     DEFAULT_MAX_HISTORY_SUMMARY_SIZE);
             CORE_DEFER_UNTIL_ACTIVE = getDeviceConfigBoolean(KEY_CORE_DEFER_UNTIL_ACTIVE,
                     DEFAULT_CORE_DEFER_UNTIL_ACTIVE);
+            PENDING_COLD_START_CHECK_INTERVAL_MILLIS = getDeviceConfigLong(
+                    KEY_PENDING_COLD_START_CHECK_INTERVAL_MILLIS,
+                    DEFAULT_PENDING_COLD_START_CHECK_INTERVAL_MILLIS);
         }
 
         // TODO: migrate BroadcastRecord to accept a BroadcastConstants
@@ -463,6 +499,10 @@
                     TimeUtils.formatDuration(DELAY_CACHED_MILLIS)).println();
             pw.print(KEY_DELAY_URGENT_MILLIS,
                     TimeUtils.formatDuration(DELAY_URGENT_MILLIS)).println();
+            pw.print(KEY_DELAY_FOREGROUND_PROC_MILLIS,
+                    TimeUtils.formatDuration(DELAY_FOREGROUND_PROC_MILLIS)).println();
+            pw.print(KEY_DELAY_PERSISTENT_PROC_MILLIS,
+                    TimeUtils.formatDuration(DELAY_PERSISTENT_PROC_MILLIS)).println();
             pw.print(KEY_MAX_HISTORY_COMPLETE_SIZE, MAX_HISTORY_COMPLETE_SIZE).println();
             pw.print(KEY_MAX_HISTORY_SUMMARY_SIZE, MAX_HISTORY_SUMMARY_SIZE).println();
             pw.print(KEY_MAX_CONSECUTIVE_URGENT_DISPATCHES,
@@ -471,6 +511,8 @@
                     MAX_CONSECUTIVE_NORMAL_DISPATCHES).println();
             pw.print(KEY_CORE_DEFER_UNTIL_ACTIVE,
                     CORE_DEFER_UNTIL_ACTIVE).println();
+            pw.print(KEY_PENDING_COLD_START_CHECK_INTERVAL_MILLIS,
+                    PENDING_COLD_START_CHECK_INTERVAL_MILLIS).println();
             pw.decreaseIndent();
             pw.println();
         }
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
index 2803b4b..9b53af2 100644
--- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
@@ -1015,6 +1015,7 @@
     static final int REASON_CONTAINS_INSTRUMENTED = 16;
     static final int REASON_CONTAINS_MANIFEST = 17;
     static final int REASON_FOREGROUND = 18;
+    static final int REASON_CORE_UID = 19;
 
     @IntDef(flag = false, prefix = { "REASON_" }, value = {
             REASON_EMPTY,
@@ -1035,6 +1036,7 @@
             REASON_CONTAINS_INSTRUMENTED,
             REASON_CONTAINS_MANIFEST,
             REASON_FOREGROUND,
+            REASON_CORE_UID,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Reason {}
@@ -1059,6 +1061,7 @@
             case REASON_CONTAINS_INSTRUMENTED: return "CONTAINS_INSTRUMENTED";
             case REASON_CONTAINS_MANIFEST: return "CONTAINS_MANIFEST";
             case REASON_FOREGROUND: return "FOREGROUND";
+            case REASON_CORE_UID: return "CORE_UID";
             default: return Integer.toString(reason);
         }
     }
@@ -1098,8 +1101,14 @@
                 mRunnableAt = runnableAt + constants.DELAY_URGENT_MILLIS;
                 mRunnableAtReason = REASON_INSTRUMENTED;
             } else if (mUidForeground) {
-                mRunnableAt = runnableAt + constants.DELAY_URGENT_MILLIS;
+                mRunnableAt = runnableAt + constants.DELAY_FOREGROUND_PROC_MILLIS;
                 mRunnableAtReason = REASON_FOREGROUND;
+            } else if (mProcessPersistent) {
+                mRunnableAt = runnableAt + constants.DELAY_PERSISTENT_PROC_MILLIS;
+                mRunnableAtReason = REASON_PERSISTENT;
+            } else if (UserHandle.isCore(uid)) {
+                mRunnableAt = runnableAt;
+                mRunnableAtReason = REASON_CORE_UID;
             } else if (mCountOrdered > 0) {
                 mRunnableAt = runnableAt;
                 mRunnableAtReason = REASON_CONTAINS_ORDERED;
@@ -1112,9 +1121,6 @@
             } else if (mCountManifest > 0) {
                 mRunnableAt = runnableAt;
                 mRunnableAtReason = REASON_CONTAINS_MANIFEST;
-            } else if (mProcessPersistent) {
-                mRunnableAt = runnableAt;
-                mRunnableAtReason = REASON_PERSISTENT;
             } else if (mUidCached) {
                 if (r.deferUntilActive) {
                     // All enqueued broadcasts are deferrable, defer
@@ -1257,7 +1263,7 @@
         BroadcastProcessQueue test = head;
         BroadcastProcessQueue tail = null;
         while (test != null) {
-            if (test.getRunnableAt() >= itemRunnableAt) {
+            if (test.getRunnableAt() > itemRunnableAt) {
                 item.runnableAtNext = test;
                 item.runnableAtPrev = test.runnableAtPrev;
                 if (item.runnableAtNext != null) {
diff --git a/services/core/java/com/android/server/am/BroadcastQueueImpl.java b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
index 7f3ceb5..e389821 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
@@ -18,6 +18,7 @@
 
 import static android.app.ActivityManager.RESTRICTION_LEVEL_RESTRICTED_BUCKET;
 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_START_RECEIVER;
+import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED;
 import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY;
 import static android.os.Process.ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE;
 import static android.text.TextUtils.formatSimple;
@@ -384,6 +385,16 @@
         maybeReportBroadcastDispatchedEventLocked(r, r.curReceiver.applicationInfo.uid);
         r.intent.setComponent(r.curComponent);
 
+        // See if we need to delay the freezer based on BroadcastOptions
+        if (r.options != null
+                && r.options.getTemporaryAppAllowlistDuration() > 0
+                && r.options.getTemporaryAppAllowlistType()
+                    == TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED) {
+            mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(app,
+                    CachedAppOptimizer.UNFREEZE_REASON_START_RECEIVER,
+                    r.options.getTemporaryAppAllowlistDuration());
+        }
+
         boolean started = false;
         try {
             if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
@@ -930,8 +941,13 @@
             Slog.v(TAG, "Broadcast temp allowlist uid=" + uid + " duration=" + duration
                     + " type=" + type + " : " + b.toString());
         }
-        mService.tempAllowlistUidLocked(uid, duration, reasonCode, b.toString(), type,
-                r.callingUid);
+
+        // Only add to temp allowlist if it's not the APP_FREEZING_DELAYED type. That will be
+        // handled when the broadcast is actually being scheduled on the app thread.
+        if (type != TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED) {
+            mService.tempAllowlistUidLocked(uid, duration, reasonCode, b.toString(), type,
+                    r.callingUid);
+        }
     }
 
     private void processNextBroadcast(boolean fromMsg) {
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index d9b3157..22c0855 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -62,6 +62,7 @@
 import android.os.BundleMerger;
 import android.os.Handler;
 import android.os.Message;
+import android.os.PowerExemptionManager;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -247,6 +248,7 @@
     private static final int MSG_DELIVERY_TIMEOUT_HARD = 3;
     private static final int MSG_BG_ACTIVITY_START_TIMEOUT = 4;
     private static final int MSG_CHECK_HEALTH = 5;
+    private static final int MSG_CHECK_PENDING_COLD_START_VALIDITY = 6;
 
     private void enqueueUpdateRunningList() {
         mLocalHandler.removeMessages(MSG_UPDATE_RUNNING_LIST);
@@ -283,6 +285,10 @@
                 checkHealth();
                 return true;
             }
+            case MSG_CHECK_PENDING_COLD_START_VALIDITY: {
+                checkPendingColdStartValidity();
+                return true;
+            }
         }
         return false;
     };
@@ -449,10 +455,14 @@
                 // skip to look for another warm process
                 if (mRunningColdStart == null) {
                     mRunningColdStart = queue;
-                } else {
+                } else if (isPendingColdStartValid()) {
                     // Move to considering next runnable queue
                     queue = nextQueue;
                     continue;
+                } else {
+                    // Pending cold start is not valid, so clear it and move on.
+                    clearInvalidPendingColdStart();
+                    mRunningColdStart = queue;
                 }
             }
 
@@ -485,11 +495,46 @@
             mService.updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_START_RECEIVER);
         }
 
+        checkPendingColdStartValidity();
         checkAndRemoveWaitingFor();
 
         traceEnd(cookie);
     }
 
+    private boolean isPendingColdStartValid() {
+        if (mRunningColdStart.app.getPid() > 0) {
+            // If the process has already started, check if it wasn't killed.
+            return !mRunningColdStart.app.isKilled();
+        } else {
+            // Otherwise, check if the process start is still pending.
+            return mRunningColdStart.app.isPendingStart();
+        }
+    }
+
+    private void clearInvalidPendingColdStart() {
+        logw("Clearing invalid pending cold start: " + mRunningColdStart);
+        onApplicationCleanupLocked(mRunningColdStart.app);
+    }
+
+    private void checkPendingColdStartValidity() {
+        // There are a few cases where a starting process gets killed but AMS doesn't report
+        // this event. So, once we start waiting for a pending cold start, periodically check
+        // if the pending start is still valid and if not, clear it so that the queue doesn't
+        // keep waiting for the process start forever.
+        synchronized (mService) {
+            // If there is no pending cold start, then nothing to do.
+            if (mRunningColdStart == null) {
+                return;
+            }
+            if (isPendingColdStartValid()) {
+                mLocalHandler.sendEmptyMessageDelayed(MSG_CHECK_PENDING_COLD_START_VALIDITY,
+                        mConstants.PENDING_COLD_START_CHECK_INTERVAL_MILLIS);
+            } else {
+                clearInvalidPendingColdStart();
+            }
+        }
+    }
+
     @Override
     public boolean onApplicationAttachedLocked(@NonNull ProcessRecord app) {
         // Process records can be recycled, so always start by looking up the
@@ -675,6 +720,7 @@
                     // supplied, then ignore the delivery group policy.
                     return;
                 }
+                // TODO: Don't merge with the same BroadcastRecord more than once.
                 broadcastConsumer = (record, recordIndex) -> {
                     r.intent.mergeExtras(record.intent, extrasMerger);
                     mBroadcastConsumerSkipAndCanceled.accept(record, recordIndex);
@@ -685,10 +731,31 @@
                 return;
         }
         forEachMatchingBroadcast(QUEUE_PREDICATE_ANY, (testRecord, testIndex) -> {
+            // If the receiver is already in a terminal state, then ignore it.
+            if (isDeliveryStateTerminal(testRecord.getDeliveryState(testIndex))) {
+                return false;
+            }
             // We only allow caller to remove broadcasts they enqueued
-            return (r.callingUid == testRecord.callingUid)
-                    && (r.userId == testRecord.userId)
-                    && r.matchesDeliveryGroup(testRecord);
+            if ((r.callingUid != testRecord.callingUid)
+                    || (r.userId != testRecord.userId)
+                    || !r.matchesDeliveryGroup(testRecord)) {
+                return false;
+            }
+            // TODO: If a process is in a deferred state, we can always apply the policy as long
+            // as it is one of the receivers for the new broadcast.
+
+            // For ordered broadcast, check if the receivers for the new broadcast is a superset
+            // of those for the previous one as skipping and removing only one of them could result
+            // in an inconsistent state.
+            if (testRecord.ordered || testRecord.resultTo != null) {
+                // TODO: Cache this result in some way so that we don't have to perform the
+                // same check for all the broadcast receivers.
+                return r.containsAllReceivers(testRecord.receivers);
+            } else if (testRecord.prioritized) {
+                return r.containsAllReceivers(testRecord.receivers);
+            } else {
+                return r.containsReceiver(testRecord.receivers.get(testIndex));
+            }
         }, broadcastConsumer, true);
     }
 
@@ -878,12 +945,20 @@
             mLocalHandler.sendMessageDelayed(
                     Message.obtain(mLocalHandler, MSG_BG_ACTIVITY_START_TIMEOUT, args), timeout);
         }
-
         if (r.options != null && r.options.getTemporaryAppAllowlistDuration() > 0) {
-            mService.tempAllowlistUidLocked(queue.uid,
-                    r.options.getTemporaryAppAllowlistDuration(),
-                    r.options.getTemporaryAppAllowlistReasonCode(), r.toShortString(),
-                    r.options.getTemporaryAppAllowlistType(), r.callingUid);
+            if (r.options.getTemporaryAppAllowlistType()
+                    == PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_APP_FREEZING_DELAYED) {
+                // Only delay freezer, don't add to any temp allowlist
+                // TODO: Add a unit test
+                mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(app,
+                        CachedAppOptimizer.UNFREEZE_REASON_START_RECEIVER,
+                        r.options.getTemporaryAppAllowlistDuration());
+            } else {
+                mService.tempAllowlistUidLocked(queue.uid,
+                        r.options.getTemporaryAppAllowlistDuration(),
+                        r.options.getTemporaryAppAllowlistReasonCode(), r.toShortString(),
+                        r.options.getTemporaryAppAllowlistType(), r.callingUid);
+            }
         }
 
         if (DEBUG_BROADCAST) logv("Scheduling " + r + " to warm " + app);
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index a9274408..564b1fe 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -79,6 +79,9 @@
     final @Nullable String callerFeatureId; // which feature in the package sent this
     final int callingPid;   // the pid of who sent this
     final int callingUid;   // the uid of who sent this
+
+    final int originalStickyCallingUid;
+            // if this is a sticky broadcast, the Uid of the original sender
     final boolean callerInstantApp; // caller is an Instant App?
     final boolean callerInstrumented; // caller is being instrumented?
     final boolean ordered;  // serialize the send to receivers?
@@ -330,7 +333,8 @@
             pw.print(prefix); pw.print("resultAbort="); pw.print(resultAbort);
                     pw.print(" ordered="); pw.print(ordered);
                     pw.print(" sticky="); pw.print(sticky);
-                    pw.print(" initialSticky="); pw.println(initialSticky);
+                    pw.print(" initialSticky="); pw.print(initialSticky);
+                    pw.print(" originalStickyCallingUid="); pw.println(originalStickyCallingUid);
         }
         if (nextReceiver != 0) {
             pw.print(prefix); pw.print("nextReceiver="); pw.println(nextReceiver);
@@ -399,6 +403,27 @@
         }
     }
 
+    BroadcastRecord(BroadcastQueue queue,
+            Intent intent, ProcessRecord callerApp, String callerPackage,
+            @Nullable String callerFeatureId, int callingPid, int callingUid,
+            boolean callerInstantApp, String resolvedType,
+            String[] requiredPermissions, String[] excludedPermissions,
+            String[] excludedPackages, int appOp,
+            BroadcastOptions options, List receivers,
+            ProcessRecord resultToApp, IIntentReceiver resultTo, int resultCode,
+            String resultData, Bundle resultExtras, boolean serialized, boolean sticky,
+            boolean initialSticky, int userId,
+            @NonNull BackgroundStartPrivileges backgroundStartPrivileges,
+            boolean timeoutExempt,
+            @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) {
+        this(queue, intent, callerApp, callerPackage, callerFeatureId, callingPid,
+                callingUid, callerInstantApp, resolvedType, requiredPermissions,
+                excludedPermissions, excludedPackages, appOp, options, receivers, resultToApp,
+                resultTo, resultCode, resultData, resultExtras, serialized, sticky,
+                initialSticky, userId, -1, backgroundStartPrivileges, timeoutExempt,
+                filterExtrasForReceiver);
+    }
+
     BroadcastRecord(BroadcastQueue _queue,
             Intent _intent, ProcessRecord _callerApp, String _callerPackage,
             @Nullable String _callerFeatureId, int _callingPid, int _callingUid,
@@ -408,7 +433,7 @@
             BroadcastOptions _options, List _receivers,
             ProcessRecord _resultToApp, IIntentReceiver _resultTo, int _resultCode,
             String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky,
-            boolean _initialSticky, int _userId,
+            boolean _initialSticky, int _userId, int originalStickyCallingUid,
             @NonNull BackgroundStartPrivileges backgroundStartPrivileges,
             boolean timeoutExempt,
             @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) {
@@ -460,6 +485,7 @@
         interactive = options != null && options.isInteractive();
         shareIdentity = options != null && options.isShareIdentityEnabled();
         this.filterExtrasForReceiver = filterExtrasForReceiver;
+        this.originalStickyCallingUid = originalStickyCallingUid;
     }
 
     /**
@@ -524,6 +550,7 @@
         shareIdentity = from.shareIdentity;
         urgent = from.urgent;
         filterExtrasForReceiver = from.filterExtrasForReceiver;
+        originalStickyCallingUid = from.originalStickyCallingUid;
     }
 
     /**
@@ -1065,6 +1092,24 @@
         }
     }
 
+    boolean containsReceiver(@NonNull Object receiver) {
+        for (int i = receivers.size() - 1; i >= 0; --i) {
+            if (isReceiverEquals(receiver, receivers.get(i))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    boolean containsAllReceivers(@NonNull List<Object> otherReceivers) {
+        for (int i = otherReceivers.size() - 1; i >= 0; --i) {
+            if (!containsReceiver(otherReceivers.get(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     boolean matchesDeliveryGroup(@NonNull BroadcastRecord other) {
         return matchesDeliveryGroup(this, other);
     }
diff --git a/services/core/java/com/android/server/am/BroadcastSkipPolicy.java b/services/core/java/com/android/server/am/BroadcastSkipPolicy.java
index 6718319..5f918cf 100644
--- a/services/core/java/com/android/server/am/BroadcastSkipPolicy.java
+++ b/services/core/java/com/android/server/am/BroadcastSkipPolicy.java
@@ -563,14 +563,15 @@
 
         // Ensure that broadcasts are only sent to other apps if they are explicitly marked as
         // exported, or are System level broadcasts
+        final int originalCallingUid = r.sticky ? r.originalStickyCallingUid : r.callingUid;
         if (!filter.exported && checkComponentPermission(null, r.callingPid,
-                r.callingUid, filter.receiverList.uid, filter.exported)
+                originalCallingUid, filter.receiverList.uid, filter.exported)
                 != PackageManager.PERMISSION_GRANTED) {
             return "Exported Denial: sending "
                     + r.intent.toString()
                     + ", action: " + r.intent.getAction()
                     + " from " + r.callerPackage
-                    + " (uid=" + r.callingUid + ")"
+                    + " (uid=" + originalCallingUid + ")"
                     + " due to receiver " + filter.receiverList.app
                     + " (uid " + filter.receiverList.uid + ")"
                     + " not specifying RECEIVER_EXPORTED";
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 3e82d55..7773190 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -47,6 +47,7 @@
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 
 import android.annotation.IntDef;
+import android.annotation.UptimeMillisLong;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal.OomAdjReason;
 import android.app.ActivityThread;
@@ -1278,14 +1279,35 @@
         return true;
     }
 
+    /**
+     * Returns the earliest time (relative) from now that the app can be frozen.
+     * @param app The app to update
+     * @param delayMillis How much to delay freezing by
+     */
+    @GuardedBy("mProcLock")
+    private long updateEarliestFreezableTime(ProcessRecord app, long delayMillis) {
+        final long now = SystemClock.uptimeMillis();
+        app.mOptRecord.setEarliestFreezableTime(
+                Math.max(app.mOptRecord.getEarliestFreezableTime(), now + delayMillis));
+        return app.mOptRecord.getEarliestFreezableTime() - now;
+    }
+
     // This will ensure app will be out of the freezer for at least mFreezerDebounceTimeout.
     @GuardedBy("mAm")
     void unfreezeTemporarily(ProcessRecord app, @UnfreezeReason int reason) {
+        unfreezeTemporarily(app, reason, mFreezerDebounceTimeout);
+    }
+
+    // This will ensure app will be out of the freezer for at least mFreezerDebounceTimeout.
+    @GuardedBy("mAm")
+    void unfreezeTemporarily(ProcessRecord app, @UnfreezeReason int reason, long delayMillis) {
         if (mUseFreezer) {
             synchronized (mProcLock) {
+                // Move the earliest freezable time further, if necessary
+                final long delay = updateEarliestFreezableTime(app, delayMillis);
                 if (app.mOptRecord.isFrozen() || app.mOptRecord.isPendingFreeze()) {
                     unfreezeAppLSP(app, reason);
-                    freezeAppAsyncLSP(app);
+                    freezeAppAsyncLSP(app, delay);
                 }
             }
         }
@@ -1293,11 +1315,17 @@
 
     @GuardedBy({"mAm", "mProcLock"})
     void freezeAppAsyncLSP(ProcessRecord app) {
-        freezeAppAsyncInternalLSP(app, mFreezerDebounceTimeout, false);
+        freezeAppAsyncLSP(app, updateEarliestFreezableTime(app, mFreezerDebounceTimeout));
     }
 
     @GuardedBy({"mAm", "mProcLock"})
-    void freezeAppAsyncInternalLSP(ProcessRecord app, long delayMillis, boolean force) {
+    private void freezeAppAsyncLSP(ProcessRecord app, @UptimeMillisLong long delayMillis) {
+        freezeAppAsyncInternalLSP(app, delayMillis, false);
+    }
+
+    @GuardedBy({"mAm", "mProcLock"})
+    void freezeAppAsyncInternalLSP(ProcessRecord app, @UptimeMillisLong long delayMillis,
+            boolean force) {
         final ProcessCachedOptimizerRecord opt = app.mOptRecord;
         if (opt.isPendingFreeze()) {
             // Skip redundant DO_FREEZE message
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 844f175..7482e64 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -97,10 +97,6 @@
         sGlobalSettingToTypeMap.put(
                 Settings.Global.ANGLE_EGL_FEATURES, String.class);
         sGlobalSettingToTypeMap.put(
-                Settings.Global.ANGLE_DEFERLIST, String.class);
-        sGlobalSettingToTypeMap.put(
-                Settings.Global.ANGLE_DEFERLIST_MODE, String.class);
-        sGlobalSettingToTypeMap.put(
                 Settings.Global.SHOW_ANGLE_IN_USE_DIALOG_BOX, String.class);
         sGlobalSettingToTypeMap.put(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, int.class);
         sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_APP, String.class);
diff --git a/services/core/java/com/android/server/am/DropboxRateLimiter.java b/services/core/java/com/android/server/am/DropboxRateLimiter.java
index 727d4df9..b5c7215 100644
--- a/services/core/java/com/android/server/am/DropboxRateLimiter.java
+++ b/services/core/java/com/android/server/am/DropboxRateLimiter.java
@@ -40,7 +40,7 @@
     // If a process is rate limited twice in a row we consider it crash-looping and rate limit it
     // more aggressively.
     private static final int STRICT_RATE_LIMIT_ALLOWED_ENTRIES = 1;
-    private static final long STRICT_RATE_LIMIT_BUFFER_DURATION = 60 * DateUtils.MINUTE_IN_MILLIS;
+    private static final long STRICT_RATE_LIMIT_BUFFER_DURATION = 20 * DateUtils.MINUTE_IN_MILLIS;
 
     @GuardedBy("mErrorClusterRecords")
     private final ArrayMap<String, ErrorRecord> mErrorClusterRecords = new ArrayMap<>();
diff --git a/services/core/java/com/android/server/am/ForegroundServiceTypeLoggerModule.java b/services/core/java/com/android/server/am/ForegroundServiceTypeLoggerModule.java
index 7908907..80406e6 100644
--- a/services/core/java/com/android/server/am/ForegroundServiceTypeLoggerModule.java
+++ b/services/core/java/com/android/server/am/ForegroundServiceTypeLoggerModule.java
@@ -34,8 +34,11 @@
 import android.content.ComponentName;
 import android.content.pm.ServiceInfo;
 import android.util.ArrayMap;
+import android.util.IntArray;
+import android.util.LongArray;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseIntArray;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FrameworkStatsLog;
@@ -90,13 +93,13 @@
         // These counts will only be added to the open call count below if
         // an FGS is started. If an FGS is NOT started, then this count should
         // gradually hit zero as close calls are decremented.
-        final SparseArray<Integer> mOpenedWithoutFgsCount = new SparseArray<>();
+        final SparseIntArray mOpenedWithoutFgsCount = new SparseIntArray();
 
         // Here we keep track of the count of in-flight calls.
         // We only want to log the first open call and the last
         // close call so that we get the largest duration
         // possible.
-        final SparseArray<Integer> mOpenWithFgsCount = new SparseArray<>();
+        final SparseIntArray mOpenWithFgsCount = new SparseIntArray();
 
         // A stack that keeps a list of API calls in the order
         // that they were called. This represents the ongoing
@@ -105,6 +108,11 @@
         // to another ordered map, keyed by the component name
         // to facilitate removing the record from the structure
         final SparseArray<ArrayMap<ComponentName, ServiceRecord>> mRunningFgs = new SparseArray<>();
+
+        // A map of API types to last FGS stop call timestamps
+        // We use this to get the duration an API was active after
+        // the stop call.
+        final SparseArray<Long> mLastFgsTimeStamp = new SparseArray<>();
     }
 
     // SparseArray that tracks all UIDs that have made various
@@ -126,12 +134,12 @@
             mUids.put(uid, uidState);
         }
         // grab the appropriate types
-        final ArrayList<Integer> apiTypes =
+        final IntArray apiTypes =
                 convertFgsTypeToApiTypes(record.foregroundServiceType);
         // now we need to iterate through the types
         // and insert the new record as needed
-        final ArrayList<Integer> apiTypesFound = new ArrayList<>();
-        final ArrayList<Long> timestampsFound = new ArrayList<>();
+        final IntArray apiTypesFound = new IntArray();
+        final LongArray timestampsFound = new LongArray();
         for (int i = 0, size = apiTypes.size(); i < size; i++) {
             final int apiType = apiTypes.get(i);
             int fgsIndex = uidState.mRunningFgs.indexOfKey(apiType);
@@ -165,19 +173,15 @@
                 uidState.mApiOpenCalls.remove(apiType);
             }
         }
-        if (!apiTypesFound.isEmpty()) {
+        if (apiTypesFound.size() != 0) {
             // log a state change
-            int[] types = new int[apiTypesFound.size()];
-            long[] timestamps = new long[apiTypesFound.size()];
             for (int i = 0, size = apiTypesFound.size(); i < size; i++) {
-                types[i] = apiTypesFound.get(i);
-                timestamps[i] = timestampsFound.get(i);
+                logFgsApiEvent(record,
+                        FGS_STATE_CHANGED_API_CALL,
+                        FGS_API_BEGIN_WITH_FGS,
+                        apiTypesFound.get(i),
+                        timestampsFound.get(i));
             }
-            logFgsApiEvent(record,
-                    FGS_STATE_CHANGED_API_CALL,
-                    FGS_API_BEGIN_WITH_FGS,
-                    types,
-                    timestamps);
         }
     }
 
@@ -189,10 +193,10 @@
         // we need to log all the API end events and remove the start events
         // then we remove the FGS from the various stacks
         // and also clean up the start calls stack by UID
-        final ArrayList<Integer> apiTypes = convertFgsTypeToApiTypes(record.foregroundServiceType);
+        final IntArray apiTypes = convertFgsTypeToApiTypes(record.foregroundServiceType);
         final UidState uidState = mUids.get(uid);
         if (uidState == null) {
-            Slog.wtfStack(TAG, "FGS stop call being logged with no start call for UID for UID "
+            Slog.w(TAG, "FGS stop call being logged with no start call for UID for UID "
                     + uid
                     + " in package " + record.packageName);
             return;
@@ -201,8 +205,9 @@
         final ArrayList<Long> timestampsFound = new ArrayList<>();
         for (int i = 0, size = apiTypes.size(); i < size; i++) {
             final int apiType = apiTypes.get(i);
-            if (!uidState.mOpenWithFgsCount.contains(apiType)) {
-                Slog.wtfStack(TAG, "Logger should be tracking FGS types correctly for UID " + uid
+            final int apiTypeIndex = uidState.mOpenWithFgsCount.indexOfKey(apiType);
+            if (apiTypeIndex < 0) {
+                Slog.w(TAG, "Logger should be tracking FGS types correctly for UID " + uid
                         + " in package " + record.packageName);
                 continue;
             }
@@ -212,7 +217,7 @@
             // we just skip logging
             final FgsApiRecord closedApi = uidState.mApiClosedCalls.get(apiType);
             if (closedApi != null
-                    && uidState.mOpenWithFgsCount.get(apiType) == 0) {
+                    && uidState.mOpenWithFgsCount.valueAt(apiTypeIndex) == 0) {
                 apisFound.add(apiType);
                 timestampsFound.add(closedApi.mTimeStart);
                 // remove the last API close call
@@ -231,19 +236,17 @@
             if (runningFgsOfType.size() == 0) {
                 // there's no more FGS running for this type, just get rid of it
                 uidState.mRunningFgs.remove(apiType);
+                // but we need to keep track of the timestamp in case an API stops
+                uidState.mLastFgsTimeStamp.put(apiType, record.mFgsExitTime);
             }
         }
         if (!apisFound.isEmpty()) {
             // time to log the call
-            int[] types = new int[apisFound.size()];
-            long[] timestamps = new long[apisFound.size()];
             for (int i = 0; i < apisFound.size(); i++) {
-                types[i] = apisFound.get(i);
-                timestamps[i] = timestampsFound.get(i);
+                logFgsApiEvent(record,
+                        FGS_STATE_CHANGED_API_CALL,
+                        FGS_API_END_WITH_FGS, apisFound.get(i), timestampsFound.get(i));
             }
-            logFgsApiEvent(record,
-                    FGS_STATE_CHANGED_API_CALL,
-                    FGS_API_END_WITH_FGS, types, timestamps);
         }
     }
 
@@ -303,8 +306,8 @@
         final ArrayMap<ComponentName, ServiceRecord> fgsListMap = uidState.mRunningFgs.get(apiType);
 
         // now we get the relevant FGS to log with
-        final int[] apiTypes = {apiType};
-        final long[] timestamps = {callStart.mTimeStart};
+        final int apiTypes = apiType;
+        final long timestamps = callStart.mTimeStart;
         if (uidState.mOpenWithFgsCount.valueAt(openWithFgsIndex) == 1) {
             for (ServiceRecord record : fgsListMap.values()) {
                 logFgsApiEvent(record,
@@ -333,7 +336,8 @@
             Slog.w(TAG, "API event end called before start!");
             return -1;
         }
-        if (uidState.mOpenWithFgsCount.contains(apiType)) {
+        final int apiIndex = uidState.mOpenWithFgsCount.indexOfKey(apiType);
+        if (apiIndex >= 0) {
             // are there any calls that started with an FGS?
             if (uidState.mOpenWithFgsCount.get(apiType) != 0) {
                 // we should decrement the count, since we only
@@ -347,20 +351,20 @@
                 // we just log that an event happened w/ no
                 // FGS associated. This is to avoid dangling
                 // events
-                final long[] timestamp = {System.currentTimeMillis()};
-                final int[] apiTypes = {apiType};
+                final long timestamp = System.currentTimeMillis();
+                final int apiTypes = apiType;
                 logFgsApiEventWithNoFgs(uid, FGS_API_END_WITHOUT_FGS, apiTypes, timestamp);
                 // we should now remove the count, so as to signal that
                 // there was never an FGS called that can be associated
-                uidState.mOpenWithFgsCount.remove(apiType);
-                return timestamp[0];
+                uidState.mOpenWithFgsCount.removeAt(apiIndex);
+                return timestamp;
             }
         }
         // we know now that this call is not coming from an
         // open FGS associated API call. So it is likely
         // a part of an unassociated call that has now been
         // closed. So we decrement that count
-        if (!uidState.mOpenedWithoutFgsCount.contains(apiType)) {
+        if (uidState.mOpenedWithoutFgsCount.indexOfKey(apiType) < 0) {
             // initialize if we don't contain
             uidState.mOpenedWithoutFgsCount.put(apiType, 0);
         }
@@ -392,8 +396,8 @@
             return;
         }
         final ArrayMap<ComponentName, ServiceRecord> fgsRecords = uidState.mRunningFgs.get(apiType);
-        final int[] apiTypes = {apiType};
-        final long[] timestamp = {System.currentTimeMillis()};
+        final int apiTypes = apiType;
+        final long timestamp = System.currentTimeMillis();
         for (ServiceRecord record : fgsRecords.values()) {
             logFgsApiEvent(record,
                     FGS_STATE_CHANGED_API_CALL,
@@ -403,8 +407,8 @@
         }
     }
 
-    private ArrayList<Integer> convertFgsTypeToApiTypes(int fgsType) {
-        final ArrayList<Integer> types = new ArrayList<>();
+    private IntArray convertFgsTypeToApiTypes(int fgsType) {
+        final IntArray types = new IntArray();
         if ((fgsType & ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA)
                 == ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA) {
             types.add(FOREGROUND_SERVICE_API_TYPE_CAMERA);
@@ -449,7 +453,13 @@
     @VisibleForTesting
     public void logFgsApiEvent(ServiceRecord r, int fgsState,
             @FgsApiState int apiState,
-            @ForegroundServiceApiType int[] apiType, long[] timestamp) {
+            @ForegroundServiceApiType int apiType, long timestamp) {
+        final long apiDurationBeforeFgsStart = r.mFgsEnterTime - timestamp;
+        final long apiDurationAfterFgsEnd = timestamp - r.mFgsExitTime;
+        final int[] apiTypes = new int[1];
+        apiTypes[0] = apiType;
+        final long[] timeStamps = new long[1];
+        timeStamps[0] = timestamp;
         FrameworkStatsLog.write(FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED,
                 r.appInfo.uid,
                 r.shortInstanceName,
@@ -474,12 +484,14 @@
                 r.mFgsDelegation != null ? r.mFgsDelegation.mOptions.mDelegationService
                         : ForegroundServiceDelegationOptions.DELEGATION_SERVICE_DEFAULT,
                 apiState,
-                apiType,
-                timestamp,
+                apiTypes,
+                timeStamps,
                 ActivityManager.PROCESS_STATE_UNKNOWN,
                 ActivityManager.PROCESS_CAPABILITY_NONE,
                 ActivityManager.PROCESS_STATE_UNKNOWN,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
+                ActivityManager.PROCESS_CAPABILITY_NONE,
+                apiDurationBeforeFgsStart,
+                apiDurationAfterFgsEnd);
     }
 
     /**
@@ -489,7 +501,18 @@
     @VisibleForTesting
     public void logFgsApiEventWithNoFgs(int uid,
             @FgsApiState int apiState,
-            @ForegroundServiceApiType int[] apiType, long[] timestamp) {
+            @ForegroundServiceApiType int apiType, long timestamp) {
+        long apiDurationAfterFgsEnd = 0;
+        UidState uidState = mUids.get(uid);
+        if (uidState != null) {
+            if (uidState.mLastFgsTimeStamp.contains(apiType)) {
+                apiDurationAfterFgsEnd = timestamp - uidState.mLastFgsTimeStamp.get(apiType);
+            }
+        }
+        final int[] apiTypes = new int[1];
+        apiTypes[0] = apiType;
+        final long[] timeStamps = new long[1];
+        timeStamps[0] = timestamp;
         FrameworkStatsLog.write(FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED,
                 uid,
                 null,
@@ -512,12 +535,14 @@
                 0,
                 0,
                 apiState,
-                apiType,
-                timestamp,
+                apiTypes,
+                timeStamps,
                 ActivityManager.PROCESS_STATE_UNKNOWN,
                 ActivityManager.PROCESS_CAPABILITY_NONE,
                 ActivityManager.PROCESS_STATE_UNKNOWN,
-                ActivityManager.PROCESS_CAPABILITY_NONE);
+                ActivityManager.PROCESS_CAPABILITY_NONE,
+                0,
+                apiDurationAfterFgsEnd);
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 1e5f187..85a0185 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -837,7 +837,7 @@
      */
     @GuardedBy("mService")
     void enqueueOomAdjTargetLocked(ProcessRecord app) {
-        if (app != null) {
+        if (app != null && app.mState.getMaxAdj() > FOREGROUND_APP_ADJ) {
             mPendingProcessSet.add(app);
         }
     }
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index cb26c13..202d407 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -42,6 +42,7 @@
 import android.os.IBinder;
 import android.os.PowerWhitelistManager;
 import android.os.PowerWhitelistManager.ReasonCode;
+import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.TransactionTooLargeException;
@@ -348,21 +349,22 @@
      * use caller's BAL permission.
      */
     public static BackgroundStartPrivileges getBackgroundStartPrivilegesAllowedByCaller(
-            @Nullable ActivityOptions activityOptions, int callingUid) {
+            @Nullable ActivityOptions activityOptions, int callingUid,
+            @Nullable String callingPackage) {
         if (activityOptions == null) {
             // since the ActivityOptions were not created by the app itself, determine the default
             // for the app
-            return getDefaultBackgroundStartPrivileges(callingUid);
+            return getDefaultBackgroundStartPrivileges(callingUid, callingPackage);
         }
         return getBackgroundStartPrivilegesAllowedByCaller(activityOptions.toBundle(),
-                callingUid);
+                callingUid, callingPackage);
     }
 
     private static BackgroundStartPrivileges getBackgroundStartPrivilegesAllowedByCaller(
-            @Nullable Bundle options, int callingUid) {
+            @Nullable Bundle options, int callingUid, @Nullable String callingPackage) {
         if (options == null || !options.containsKey(
                         ActivityOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED)) {
-            return getDefaultBackgroundStartPrivileges(callingUid);
+            return getDefaultBackgroundStartPrivileges(callingUid, callingPackage);
         }
         return options.getBoolean(ActivityOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED)
                 ? BackgroundStartPrivileges.ALLOW_BAL
@@ -381,8 +383,18 @@
                     android.Manifest.permission.LOG_COMPAT_CHANGE
             })
     public static BackgroundStartPrivileges getDefaultBackgroundStartPrivileges(
-            int callingUid) {
-        boolean isChangeEnabledForApp = CompatChanges.isChangeEnabled(
+            int callingUid, @Nullable String callingPackage) {
+        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
+            // We temporarily allow BAL for system processes, while we verify that all valid use
+            // cases are opted in explicitly to grant their BAL permission.
+            // Background: In many cases devices are running additional apps that share UID with
+            // the system. If one of these apps targets a lower SDK the change is not active, but
+            // as soon as that app is upgraded (or removed) BAL would be blocked. (b/283138430)
+            return BackgroundStartPrivileges.ALLOW_BAL;
+        }
+        boolean isChangeEnabledForApp = callingPackage != null ? CompatChanges.isChangeEnabled(
+                DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER, callingPackage,
+                UserHandle.getUserHandleForUid(callingUid)) : CompatChanges.isChangeEnabled(
                 DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER, callingUid);
         if (isChangeEnabledForApp) {
             return BackgroundStartPrivileges.ALLOW_FGS;
@@ -638,7 +650,7 @@
         // temporarily allow receivers and services to open activities from background if the
         // PendingIntent.send() caller was foreground at the time of sendInner() call
         if (uid != callingUid && controller.mAtmInternal.isUidForeground(callingUid)) {
-            return getBackgroundStartPrivilegesAllowedByCaller(options, callingUid);
+            return getBackgroundStartPrivilegesAllowedByCaller(options, callingUid, null);
         }
         return BackgroundStartPrivileges.NONE;
     }
diff --git a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
index e8c8f6d..7841b69 100644
--- a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
+++ b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import android.annotation.UptimeMillisLong;
 import android.app.ActivityManagerInternal.OomAdjReason;
 
 import com.android.internal.annotations.GuardedBy;
@@ -119,6 +120,12 @@
     @GuardedBy("mProcLock")
     private boolean mPendingFreeze;
 
+    /**
+     * This is the soonest the process can be allowed to freeze, in uptime millis
+     */
+    @GuardedBy("mProcLock")
+    private @UptimeMillisLong long mEarliestFreezableTimeMillis;
+
     @GuardedBy("mProcLock")
     long getLastCompactTime() {
         return mLastCompactTime;
@@ -264,6 +271,16 @@
     }
 
     @GuardedBy("mProcLock")
+    @UptimeMillisLong long getEarliestFreezableTime() {
+        return mEarliestFreezableTimeMillis;
+    }
+
+    @GuardedBy("mProcLock")
+    void setEarliestFreezableTime(@UptimeMillisLong long earliestFreezableTimeMillis) {
+        mEarliestFreezableTimeMillis = earliestFreezableTimeMillis;
+    }
+
+    @GuardedBy("mProcLock")
     boolean isFreezeExempt() {
         return mFreezeExempt;
     }
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index c393213..4342cb9 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -107,6 +107,7 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.storage.StorageManagerInternal;
+import android.provider.DeviceConfig;
 import android.system.Os;
 import android.system.OsConstants;
 import android.text.TextUtils;
@@ -181,6 +182,8 @@
     static final String ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY =
             "persist.sys.vold_app_data_isolation_enabled";
 
+    private static final String APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS = ":isSdkSandboxNext";
+
     // OOM adjustments for processes in various states:
 
     // Uninitialized value for any major or minor adj fields
@@ -538,6 +541,78 @@
 
     ActivityManagerGlobalLock mProcLock;
 
+    private static final String PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS =
+            "apply_sdk_sandbox_next_restrictions";
+    private static final boolean DEFAULT_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS = false;
+
+    @GuardedBy("mService")
+    private ProcessListSettingsListener mProcessListSettingsListener;
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    ProcessListSettingsListener getProcessListSettingsListener() {
+        synchronized (mService) {
+            if (mProcessListSettingsListener == null) {
+                mProcessListSettingsListener = new ProcessListSettingsListener(mService.mContext);
+                mProcessListSettingsListener.registerObserver();
+            }
+            return mProcessListSettingsListener;
+        }
+    }
+
+    static class ProcessListSettingsListener implements DeviceConfig.OnPropertiesChangedListener {
+
+        private final Context mContext;
+        private final Object mLock = new Object();
+
+        @GuardedBy("mLock")
+        private boolean mSdkSandboxApplyRestrictionsNext =
+                DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_ADSERVICES,
+                PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS,
+                DEFAULT_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS);
+
+        ProcessListSettingsListener(Context context) {
+            mContext = context;
+        }
+
+        private void registerObserver() {
+            DeviceConfig.addOnPropertiesChangedListener(
+                    DeviceConfig.NAMESPACE_ADSERVICES, mContext.getMainExecutor(), this);
+        }
+
+        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+        void unregisterObserver() {
+            DeviceConfig.removeOnPropertiesChangedListener(this);
+        }
+
+        boolean applySdkSandboxRestrictionsNext() {
+            synchronized (mLock) {
+                return mSdkSandboxApplyRestrictionsNext;
+            }
+        }
+
+        @Override
+        public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
+            synchronized (mLock) {
+                for (String name : properties.getKeyset()) {
+                    if (name == null) {
+                        continue;
+                    }
+
+                    switch (name) {
+                        case PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS:
+                            mSdkSandboxApplyRestrictionsNext =
+                                properties.getBoolean(
+                                    PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS,
+                                    DEFAULT_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS);
+                            break;
+                        default:
+                    }
+                }
+            }
+        }
+    }
+
     final class IsolatedUidRange {
         @VisibleForTesting
         public final int mFirstUid;
@@ -1883,8 +1958,9 @@
                         new IllegalStateException("SELinux tag not defined for "
                                 + app.info.packageName + " (uid " + app.uid + ")"));
             }
-            final String seInfo = app.info.seInfo
-                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
+
+            String seInfo = updateSeInfo(app);
+
             // Start the process.  It will either succeed and return a result containing
             // the PID of the new process, or else throw a RuntimeException.
             final String entryPoint = "android.app.ActivityThread";
@@ -1907,6 +1983,21 @@
         }
     }
 
+    @VisibleForTesting
+    @GuardedBy("mService")
+    String updateSeInfo(ProcessRecord app) {
+        String extraInfo = "";
+        // By the time the first the SDK sandbox process is started, device config service
+        // should be available.
+        if (app.isSdkSandbox
+                && getProcessListSettingsListener().applySdkSandboxRestrictionsNext()) {
+            extraInfo = APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS;
+        }
+
+        return app.info.seInfo
+                + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser) + extraInfo;
+    }
+
 
     @GuardedBy("mService")
     boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
@@ -3091,6 +3182,10 @@
         if (isSdkSandbox) {
             uid = sdkSandboxUid;
         }
+        if (Process.isSdkSandboxUid(uid) && (!isSdkSandbox || sdkSandboxClientAppPackage == null)) {
+            Slog.e(TAG, "Abort creating new sandbox process as required parameters are missing.");
+            return null;
+        }
         if (isolated) {
             if (isolatedUid == 0) {
                 IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord);
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index b22ece3..1f39d1b 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -175,7 +175,7 @@
     // while-in-use permissions in FGS started from background might be restricted.
     boolean mAllowWhileInUsePermissionInFgs;
     @PowerExemptionManager.ReasonCode
-    int mAllowWhileInUsePermissionInFgsReason;
+    int mAllowWhileInUsePermissionInFgsReason = REASON_DENIED;
 
     // Integer version of mAllowWhileInUsePermissionInFgs that we keep track to compare
     // the old and new logics.
@@ -622,12 +622,13 @@
             pw.println(mBackgroundStartPrivilegesByStartMerged);
         }
         pw.print(prefix); pw.print("mAllowWhileInUsePermissionInFgsReason=");
-        pw.println(mAllowWhileInUsePermissionInFgsReason);
+        pw.println(PowerExemptionManager.reasonCodeToString(mAllowWhileInUsePermissionInFgsReason));
 
         pw.print(prefix); pw.print("debugWhileInUseReasonInStartForeground=");
-        pw.println(mDebugWhileInUseReasonInStartForeground);
+        pw.println(PowerExemptionManager.reasonCodeToString(
+                mDebugWhileInUseReasonInStartForeground));
         pw.print(prefix); pw.print("debugWhileInUseReasonInBindService=");
-        pw.println(mDebugWhileInUseReasonInBindService);
+        pw.println(PowerExemptionManager.reasonCodeToString(mDebugWhileInUseReasonInBindService));
 
         pw.print(prefix); pw.print("allowUiJobScheduling="); pw.println(mAllowUiJobScheduling);
         pw.print(prefix); pw.print("recentCallingPackage=");
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 334c145..76a994e 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -151,6 +151,8 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
@@ -1707,7 +1709,8 @@
                     mInjector.getWindowManager().setSwitchingUser(true);
                     // Only lock if the user has a secure keyguard PIN/Pattern/Pwd
                     if (mInjector.getKeyguardManager().isDeviceSecure(userId)) {
-                        mInjector.getWindowManager().lockNow(null);
+                        // Make sure the device is locked before moving on with the user switch
+                        mInjector.lockDeviceNowAndWaitForKeyguardShown();
                     }
                 }
 
@@ -3444,6 +3447,11 @@
         WindowManagerService getWindowManager() {
             return mService.mWindowManager;
         }
+
+        ActivityTaskManagerInternal getActivityTaskManagerInternal() {
+            return mService.mAtmInternal;
+        }
+
         void activityManagerOnUserStopped(@UserIdInt int userId) {
             LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId);
         }
@@ -3567,6 +3575,8 @@
                 if (mUserSwitchingDialog != null) {
                     mUserSwitchingDialog.dismiss(onDismissed);
                     mUserSwitchingDialog = null;
+                } else if (onDismissed != null) {
+                    onDismissed.run();
                 }
             }
         }
@@ -3665,5 +3675,43 @@
         void onSystemUserVisibilityChanged(boolean visible) {
             getUserManagerInternal().onSystemUserVisibilityChanged(visible);
         }
+
+        void lockDeviceNowAndWaitForKeyguardShown() {
+            if (getWindowManager().isKeyguardLocked()) {
+                return;
+            }
+
+            final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
+            t.traceBegin("lockDeviceNowAndWaitForKeyguardShown");
+
+            final CountDownLatch latch = new CountDownLatch(1);
+            ActivityTaskManagerInternal.ScreenObserver screenObserver =
+                    new ActivityTaskManagerInternal.ScreenObserver() {
+                        @Override
+                        public void onAwakeStateChanged(boolean isAwake) {
+
+                        }
+
+                        @Override
+                        public void onKeyguardStateChanged(boolean isShowing) {
+                            if (isShowing) {
+                                latch.countDown();
+                            }
+                        }
+                    };
+
+            getActivityTaskManagerInternal().registerScreenObserver(screenObserver);
+            getWindowManager().lockDeviceNow();
+            try {
+                if (!latch.await(20, TimeUnit.SECONDS)) {
+                    throw new RuntimeException("Keyguard is not shown in 20 seconds");
+                }
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            } finally {
+                getActivityTaskManagerInternal().unregisterScreenObserver(screenObserver);
+                t.traceEnd();
+            }
+        }
     }
 }
diff --git a/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java b/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java
index f520f6a..4dfd9b0 100644
--- a/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java
+++ b/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java
@@ -19,6 +19,7 @@
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.OP_NONE;
 import static android.app.AppOpsManager.OP_SCHEDULE_EXACT_ALARM;
+import static android.app.AppOpsManager.OP_USE_FULL_SCREEN_INTENT;
 import static android.app.AppOpsManager.WATCH_FOREGROUND_CHANGES;
 import static android.app.AppOpsManager.opRestrictsRead;
 import static android.app.AppOpsManager.opToDefaultMode;
@@ -41,6 +42,7 @@
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.permission.PermissionManager;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
@@ -107,7 +109,7 @@
      * {@link #upgradeLocked(int)} below. The first version was 1.
      */
     @VisibleForTesting
-    static final int CURRENT_VERSION = 3;
+    static final int CURRENT_VERSION = 4;
 
     /**
      * This stores the version of appops.xml seen at boot. If this is smaller than
@@ -1074,7 +1076,12 @@
                 upgradeScheduleExactAlarmLocked();
                 // fall through
             case 2:
-                // for future upgrades
+                // split the appops.xml into appops.xml to store appop state and apppops_access.xml
+                // to store app-op access.
+                // fall through
+            case 3:
+                resetUseFullScreenIntentLocked();
+                // fall through
         }
         scheduleFastWriteLocked();
     }
@@ -1145,6 +1152,38 @@
         }
     }
 
+    /**
+     * A cleanup step for U Beta 2 that reverts the OP_USE_FULL_SCREEN_INTENT's mode to MODE_DEFAULT
+     * if the permission flags for the USE_FULL_SCREEN_INTENT permission does not have USER_SET.
+     */
+    @VisibleForTesting
+    @GuardedBy("mLock")
+    void resetUseFullScreenIntentLocked() {
+        final PermissionManagerServiceInternal pmsi = LocalServices.getService(
+                PermissionManagerServiceInternal.class);
+        final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
+        final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
+        final PermissionManager permissionManager =
+                mContext.getSystemService(PermissionManager.class);
+
+        final String permissionName = AppOpsManager.opToPermission(OP_USE_FULL_SCREEN_INTENT);
+        final String[] packagesDeclaringPermission =
+            pmsi.getAppOpPermissionPackages(permissionName);
+        final int[] userIds = umi.getUserIds();
+
+        for (final String pkg : packagesDeclaringPermission) {
+            for (int userId : userIds) {
+                final int uid = pmi.getPackageUid(pkg, 0, userId);
+                final int flags = permissionManager.getPermissionFlags(pkg, permissionName,
+                        UserHandle.of(userId));
+                if ((flags & PackageManager.FLAG_PERMISSION_USER_SET) == 0) {
+                    setUidMode(uid, OP_USE_FULL_SCREEN_INTENT,
+                            AppOpsManager.opToDefaultMode(OP_USE_FULL_SCREEN_INTENT));
+                }
+            }
+        }
+    }
+
     @VisibleForTesting
     List<Integer> getUidsWithNonDefaultModes() {
         List<Integer> result = new ArrayList<>();
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 1f3795a..a110169 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -44,7 +44,6 @@
 import static android.app.AppOpsManager.OP_RECORD_AUDIO;
 import static android.app.AppOpsManager.OP_RECORD_AUDIO_HOTWORD;
 import static android.app.AppOpsManager.OP_RECORD_AUDIO_SANDBOXED;
-import static android.app.AppOpsManager.OP_RUN_ANY_IN_BACKGROUND;
 import static android.app.AppOpsManager.OP_VIBRATE;
 import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_FAILED;
 import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_STARTED;
@@ -1770,11 +1769,6 @@
     @Override
     public void setUidMode(int code, int uid, int mode) {
         setUidMode(code, uid, mode, null);
-        if (code == OP_RUN_ANY_IN_BACKGROUND) {
-            // TODO (b/280869337): Remove this once we have the required data.
-            Slog.wtfStack(TAG, "setUidMode called for RUN_ANY_IN_BACKGROUND by uid: "
-                    + UserHandle.formatUid(Binder.getCallingUid()));
-        }
     }
 
     private void setUidMode(int code, int uid, int mode,
@@ -1950,17 +1944,6 @@
     @Override
     public void setMode(int code, int uid, @NonNull String packageName, int mode) {
         setMode(code, uid, packageName, mode, null);
-        final int callingUid = Binder.getCallingUid();
-        if (code == OP_RUN_ANY_IN_BACKGROUND && mode != MODE_ALLOWED) {
-            // TODO (b/280869337): Remove this once we have the required data.
-            final String callingPackage = ArrayUtils.firstOrNull(getPackagesForUid(callingUid));
-            Slog.wtfStack(TAG,
-                    "RUN_ANY_IN_BACKGROUND for package " + packageName + " changed to mode: "
-                            + modeToName(mode) + " via setMode. Calling package: " + callingPackage
-                            + ", calling uid: " + UserHandle.formatUid(callingUid)
-                            + ", calling pid: " + Binder.getCallingPid()
-                            + ", system pid: " + Process.myPid());
-        }
     }
 
     void setMode(int code, int uid, @NonNull String packageName, int mode,
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 71401f4..d7a5ee9 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -209,6 +209,7 @@
     private void init() {
         setupMessaging(mContext);
 
+        initAudioHalBluetoothState();
         initRoutingStrategyIds();
         mPreferredCommunicationDevice = null;
         updateActiveCommunicationDevice();
@@ -419,6 +420,20 @@
             mBtHelper.stopBluetoothSco(eventSource);
         }
 
+        // In BT classic for communication, the device changes from a2dp to sco device, but for
+        // LE Audio it stays the same and we must trigger the proper stream volume alignment, if
+        // LE Audio communication device is activated after the audio system has already switched to
+        // MODE_IN_CALL mode.
+        if (isBluetoothLeAudioRequested()) {
+            final int streamType = mAudioService.getBluetoothContextualVolumeStream();
+            final int leAudioVolIndex = getVssVolumeForDevice(streamType, device.getInternalType());
+            final int leAudioMaxVolIndex = getMaxVssVolumeForStream(streamType);
+            if (AudioService.DEBUG_COMM_RTE) {
+                Log.v(TAG, "setCommunicationRouteForClient restoring LE Audio device volume lvl.");
+            }
+            postSetLeAudioVolumeIndex(leAudioVolIndex, leAudioMaxVolIndex, streamType);
+        }
+
         updateCommunicationRoute(eventSource);
     }
 
@@ -632,6 +647,16 @@
     }
 
     /**
+     * Helper method on top of isDeviceRequestedForCommunication() indicating if
+     * Bluetooth LE Audio communication device is currently requested or not.
+     * @return true if Bluetooth LE Audio device is requested, false otherwise.
+     */
+    /*package*/ boolean isBluetoothLeAudioRequested() {
+        return isDeviceRequestedForCommunication(AudioDeviceInfo.TYPE_BLE_HEADSET)
+                || isDeviceRequestedForCommunication(AudioDeviceInfo.TYPE_BLE_SPEAKER);
+    }
+
+    /**
      * Indicates if preferred route selection for communication is Bluetooth SCO.
      * @return true if Bluetooth SCO is preferred , false otherwise.
      */
@@ -864,21 +889,174 @@
         }
     }
 
-    /**
-     * Current Bluetooth SCO audio active state indicated by BtHelper via setBluetoothScoOn().
-     */
+    // Lock protecting state variable related to Bluetooth audio state
+    private final Object mBluetoothAudioStateLock = new Object();
+
+    // Current Bluetooth SCO audio active state indicated by BtHelper via setBluetoothScoOn().
+    @GuardedBy("mBluetoothAudioStateLock")
     private boolean mBluetoothScoOn;
+    // value of BT_SCO parameter currently applied to audio HAL.
+    @GuardedBy("mBluetoothAudioStateLock")
+    private boolean mBluetoothScoOnApplied;
+
+    // A2DP suspend state requested by AudioManager.setA2dpSuspended() API.
+    @GuardedBy("mBluetoothAudioStateLock")
+    private boolean mBluetoothA2dpSuspendedExt;
+    // A2DP suspend state requested by AudioDeviceInventory.
+    @GuardedBy("mBluetoothAudioStateLock")
+    private boolean mBluetoothA2dpSuspendedInt;
+    // value of BT_A2dpSuspendedSCO parameter currently applied to audio HAL.
+
+    @GuardedBy("mBluetoothAudioStateLock")
+    private boolean mBluetoothA2dpSuspendedApplied;
+
+    // LE Audio suspend state requested by AudioManager.setLeAudioSuspended() API.
+    @GuardedBy("mBluetoothAudioStateLock")
+    private boolean mBluetoothLeSuspendedExt;
+    // LE Audio suspend state requested by AudioDeviceInventory.
+    @GuardedBy("mBluetoothAudioStateLock")
+    private boolean mBluetoothLeSuspendedInt;
+    // value of LeAudioSuspended parameter currently applied to audio HAL.
+    @GuardedBy("mBluetoothAudioStateLock")
+    private boolean mBluetoothLeSuspendedApplied;
+
+    private void initAudioHalBluetoothState() {
+        synchronized (mBluetoothAudioStateLock) {
+            mBluetoothScoOnApplied = false;
+            AudioSystem.setParameters("BT_SCO=off");
+            mBluetoothA2dpSuspendedApplied = false;
+            AudioSystem.setParameters("A2dpSuspended=false");
+            mBluetoothLeSuspendedApplied = false;
+            AudioSystem.setParameters("LeAudioSuspended=false");
+        }
+    }
+
+    @GuardedBy("mBluetoothAudioStateLock")
+    private void updateAudioHalBluetoothState() {
+        if (mBluetoothScoOn != mBluetoothScoOnApplied) {
+            if (AudioService.DEBUG_COMM_RTE) {
+                Log.v(TAG, "updateAudioHalBluetoothState() mBluetoothScoOn: "
+                        + mBluetoothScoOn + ", mBluetoothScoOnApplied: " + mBluetoothScoOnApplied);
+            }
+            if (mBluetoothScoOn) {
+                if (!mBluetoothA2dpSuspendedApplied) {
+                    AudioSystem.setParameters("A2dpSuspended=true");
+                    mBluetoothA2dpSuspendedApplied = true;
+                }
+                if (!mBluetoothLeSuspendedApplied) {
+                    AudioSystem.setParameters("LeAudioSuspended=true");
+                    mBluetoothLeSuspendedApplied = true;
+                }
+                AudioSystem.setParameters("BT_SCO=on");
+            } else {
+                AudioSystem.setParameters("BT_SCO=off");
+            }
+            mBluetoothScoOnApplied = mBluetoothScoOn;
+        }
+        if (!mBluetoothScoOnApplied) {
+            if ((mBluetoothA2dpSuspendedExt || mBluetoothA2dpSuspendedInt)
+                    != mBluetoothA2dpSuspendedApplied) {
+                if (AudioService.DEBUG_COMM_RTE) {
+                    Log.v(TAG, "updateAudioHalBluetoothState() mBluetoothA2dpSuspendedExt: "
+                            + mBluetoothA2dpSuspendedExt
+                            + ", mBluetoothA2dpSuspendedInt: " + mBluetoothA2dpSuspendedInt
+                            + ", mBluetoothA2dpSuspendedApplied: "
+                            + mBluetoothA2dpSuspendedApplied);
+                }
+                mBluetoothA2dpSuspendedApplied =
+                        mBluetoothA2dpSuspendedExt || mBluetoothA2dpSuspendedInt;
+                if (mBluetoothA2dpSuspendedApplied) {
+                    AudioSystem.setParameters("A2dpSuspended=true");
+                } else {
+                    AudioSystem.setParameters("A2dpSuspended=false");
+                }
+            }
+            if ((mBluetoothLeSuspendedExt || mBluetoothLeSuspendedInt)
+                    != mBluetoothLeSuspendedApplied) {
+                if (AudioService.DEBUG_COMM_RTE) {
+                    Log.v(TAG, "updateAudioHalBluetoothState() mBluetoothLeSuspendedExt: "
+                            + mBluetoothLeSuspendedExt
+                            + ", mBluetoothLeSuspendedInt: " + mBluetoothLeSuspendedInt
+                            + ", mBluetoothLeSuspendedApplied: " + mBluetoothLeSuspendedApplied);
+                }
+                mBluetoothLeSuspendedApplied =
+                        mBluetoothLeSuspendedExt || mBluetoothLeSuspendedInt;
+                if (mBluetoothLeSuspendedApplied) {
+                    AudioSystem.setParameters("LeAudioSuspended=true");
+                } else {
+                    AudioSystem.setParameters("LeAudioSuspended=false");
+                }
+            }
+        }
+    }
 
     /*package*/ void setBluetoothScoOn(boolean on, String eventSource) {
         if (AudioService.DEBUG_COMM_RTE) {
             Log.v(TAG, "setBluetoothScoOn: " + on + " " + eventSource);
         }
-        synchronized (mDeviceStateLock) {
+        synchronized (mBluetoothAudioStateLock) {
             mBluetoothScoOn = on;
+            updateAudioHalBluetoothState();
             postUpdateCommunicationRouteClient(eventSource);
         }
     }
 
+    /*package*/ void setA2dpSuspended(boolean enable, boolean internal, String eventSource) {
+        synchronized (mBluetoothAudioStateLock) {
+            if (AudioService.DEBUG_COMM_RTE) {
+                Log.v(TAG, "setA2dpSuspended source: " + eventSource + ", enable: "
+                        + enable + ", internal: " + internal
+                        + ", mBluetoothA2dpSuspendedInt: " + mBluetoothA2dpSuspendedInt
+                        + ", mBluetoothA2dpSuspendedExt: " + mBluetoothA2dpSuspendedExt);
+            }
+            if (internal) {
+                mBluetoothA2dpSuspendedInt = enable;
+            } else {
+                mBluetoothA2dpSuspendedExt = enable;
+            }
+            updateAudioHalBluetoothState();
+        }
+    }
+
+    /*package*/ void clearA2dpSuspended() {
+        if (AudioService.DEBUG_COMM_RTE) {
+            Log.v(TAG, "clearA2dpSuspended");
+        }
+        synchronized (mBluetoothAudioStateLock) {
+            mBluetoothA2dpSuspendedInt = false;
+            mBluetoothA2dpSuspendedExt = false;
+            updateAudioHalBluetoothState();
+        }
+    }
+
+    /*package*/ void setLeAudioSuspended(boolean enable, boolean internal, String eventSource) {
+        synchronized (mBluetoothAudioStateLock) {
+            if (AudioService.DEBUG_COMM_RTE) {
+                Log.v(TAG, "setLeAudioSuspended source: " + eventSource + ", enable: "
+                        + enable + ", internal: " + internal
+                        + ", mBluetoothLeSuspendedInt: " + mBluetoothA2dpSuspendedInt
+                        + ", mBluetoothLeSuspendedExt: " + mBluetoothA2dpSuspendedExt);
+            }
+            if (internal) {
+                mBluetoothLeSuspendedInt = enable;
+            } else {
+                mBluetoothLeSuspendedExt = enable;
+            }
+            updateAudioHalBluetoothState();
+        }
+    }
+
+    /*package*/ void clearLeAudioSuspended() {
+        if (AudioService.DEBUG_COMM_RTE) {
+            Log.v(TAG, "clearLeAudioSuspended");
+        }
+        synchronized (mBluetoothAudioStateLock) {
+            mBluetoothLeSuspendedInt = false;
+            mBluetoothLeSuspendedExt = false;
+            updateAudioHalBluetoothState();
+        }
+    }
+
     /*package*/ AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
         synchronized (mDeviceStateLock) {
             return mDeviceInventory.startWatchingRoutes(observer);
@@ -1985,7 +2163,11 @@
      */
     @GuardedBy("mDeviceStateLock")
     @Nullable private AudioDeviceAttributes preferredCommunicationDevice() {
-        boolean btSCoOn = mBluetoothScoOn && mBtHelper.isBluetoothScoOn();
+        boolean btSCoOn = mBtHelper.isBluetoothScoOn();
+        synchronized (mBluetoothAudioStateLock) {
+            btSCoOn = btSCoOn && mBluetoothScoOn;
+        }
+
         if (btSCoOn) {
             // Use the SCO device known to BtHelper so that it matches exactly
             // what has been communicated to audio policy manager. The device
@@ -2020,12 +2202,6 @@
                 "updateCommunicationRoute, preferredCommunicationDevice: "
                 + preferredCommunicationDevice + " eventSource: " + eventSource)));
 
-        if (preferredCommunicationDevice == null
-                || preferredCommunicationDevice.getType() != AudioDeviceInfo.TYPE_BLUETOOTH_SCO) {
-            AudioSystem.setParameters("BT_SCO=off");
-        } else {
-            AudioSystem.setParameters("BT_SCO=on");
-        }
         if (preferredCommunicationDevice == null) {
             AudioDeviceAttributes defaultDevice = getDefaultCommunicationDevice();
             if (defaultDevice != null) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index b70c3e4..a561612 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -1100,7 +1100,8 @@
         synchronized (rolesMap) {
             Pair<Integer, Integer> key = new Pair<>(useCase, role);
             if (!rolesMap.containsKey(key)) {
-                return AudioSystem.SUCCESS;
+                // trying to clear a role for a device that wasn't set
+                return AudioSystem.BAD_VALUE;
             }
             final int status = asi.deviceRoleAction(useCase, role, null);
             if (status == AudioSystem.SUCCESS) {
@@ -1478,7 +1479,7 @@
         }
 
         // Reset A2DP suspend state each time a new sink is connected
-        mAudioSystem.setParameters("A2dpSuspended=false");
+        mDeviceBroker.clearA2dpSuspended();
 
         // The convention for head tracking sensors associated with A2DP devices is to
         // use a UUID derived from the MAC address as follows:
@@ -1751,7 +1752,8 @@
     private void makeA2dpDeviceUnavailableLater(String address, int delayMs) {
         // prevent any activity on the A2DP audio output to avoid unwanted
         // reconnection of the sink.
-        mAudioSystem.setParameters("A2dpSuspended=true");
+        mDeviceBroker.setA2dpSuspended(
+                true /*enable*/, true /*internal*/, "makeA2dpDeviceUnavailableLater");
         // retrieve DeviceInfo before removing device
         final String deviceKey =
                 DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address);
@@ -1898,7 +1900,7 @@
                         "LE Audio device addr=" + address + " now available").printLog(TAG));
             }
             // Reset LEA suspend state each time a new sink is connected
-            mAudioSystem.setParameters("LeAudioSuspended=false");
+            mDeviceBroker.clearLeAudioSuspended();
 
             UUID sensorUuid = UuidUtils.uuidFromAudioDeviceAttributes(ada);
             mConnectedDevices.put(DeviceInfo.makeDeviceListKey(device, address),
@@ -1953,7 +1955,8 @@
     private void makeLeAudioDeviceUnavailableLater(String address, int device, int delayMs) {
         // prevent any activity on the LEA output to avoid unwanted
         // reconnection of the sink.
-        mAudioSystem.setParameters("LeAudioSuspended=true");
+        mDeviceBroker.setLeAudioSuspended(
+                true /*enable*/, true /*internal*/, "makeLeAudioDeviceUnavailableLater");
         // the device will be made unavailable later, so consider it disconnected right away
         mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address));
         // send the delayed message to make the device unavailable later
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 24eba76..d0b6cdc 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -45,7 +45,6 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.BroadcastOptions;
@@ -167,7 +166,6 @@
 import android.os.VibrationEffect;
 import android.os.Vibrator;
 import android.os.VibratorManager;
-import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.provider.Settings.System;
 import android.service.notification.ZenModeConfig;
@@ -187,10 +185,8 @@
 import android.view.accessibility.AccessibilityManager;
 import android.widget.Toast;
 
-
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.Preconditions;
@@ -252,7 +248,6 @@
             AudioSystemAdapter.OnVolRangeInitRequestListener {
 
     private static final String TAG = "AS.AudioService";
-    private static final boolean CONFIG_DEFAULT_VAL = false;
 
     private final AudioSystemAdapter mAudioSystem;
     private final SystemServerAdapter mSystemServer;
@@ -309,7 +304,7 @@
      * indicates whether STREAM_NOTIFICATION is aliased to STREAM_RING
      *     not final due to test method, see {@link #setNotifAliasRingForTest(boolean)}.
      */
-    private boolean mNotifAliasRing;
+    private boolean mNotifAliasRing = false;
 
     /**
      * Test method to temporarily override whether STREAM_NOTIFICATION is aliased to STREAM_RING,
@@ -1057,13 +1052,6 @@
         mUseVolumeGroupAliases = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups);
 
-        mNotifAliasRing = !DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, false);
-
-        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
-                ActivityThread.currentApplication().getMainExecutor(),
-                this::onDeviceConfigChange);
-
         // Initialize volume
         // Priority 1 - Android Property
         // Priority 2 - Audio Policy Service
@@ -1157,6 +1145,11 @@
                         MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM];
         }
 
+        int minAssistantVolume = SystemProperties.getInt("ro.config.assistant_vol_min", -1);
+        if (minAssistantVolume != -1) {
+            MIN_STREAM_VOLUME[AudioSystem.STREAM_ASSISTANT] = minAssistantVolume;
+        }
+
         // Read following properties to configure max volume (number of steps) and default volume
         //   for STREAM_NOTIFICATION and STREAM_RING:
         //      config_audio_notif_vol_default
@@ -1277,22 +1270,6 @@
     }
 
     /**
-     * Separating notification volume from ring is NOT of aliasing the corresponding streams
-     * @param properties
-     */
-    private void onDeviceConfigChange(DeviceConfig.Properties properties) {
-        Set<String> changeSet = properties.getKeyset();
-        if (changeSet.contains(SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION)) {
-            boolean newNotifAliasRing = !properties.getBoolean(
-                    SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, CONFIG_DEFAULT_VAL);
-            if (mNotifAliasRing != newNotifAliasRing) {
-                mNotifAliasRing = newNotifAliasRing;
-                updateStreamVolumeAlias(true, TAG);
-            }
-        }
-    }
-
-    /**
      * Called by handling of MSG_INIT_STREAMS_VOLUMES
      */
     private void onInitStreamsAndVolumes() {
@@ -3373,8 +3350,13 @@
             return;
         }
 
-        sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType,
-                direction/*val1*/, flags/*val2*/, callingPackage));
+        final VolumeEvent evt = new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType,
+                direction/*val1*/, flags/*val2*/, callingPackage);
+        sVolumeLogger.enqueue(evt);
+        // also logging mute/unmute calls to the dedicated logger
+        if (isMuteAdjust(direction)) {
+            sMuteLogger.enqueue(evt);
+        }
         adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage,
                 Binder.getCallingUid(), Binder.getCallingPid(), attributionTag,
                 callingHasAudioSettingsPermission(), AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
@@ -3475,7 +3457,7 @@
         }
 
         // If either the client forces allowing ringer modes for this adjustment,
-        // or the stream type is one that is affected by ringer modes
+        // or stream is used for UI sonification
         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
                 (isUiSoundsStreamType(streamTypeAlias))) {
             int ringerMode = getRingerModeInternal();
@@ -3496,6 +3478,13 @@
             if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {
                 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
             }
+        } else if (isStreamMutedByRingerOrZenMode(streamTypeAlias) && streamState.mIsMuted) {
+            // if the stream is currently muted streams by ringer/zen mode
+            // then it cannot be unmuted (without FLAG_ALLOW_RINGER_MODES)
+            if (direction == AudioManager.ADJUST_TOGGLE_MUTE
+                    || direction == AudioManager.ADJUST_UNMUTE) {
+                adjustVolume = false;
+            }
         }
 
         // If the ringer mode or zen is muting the stream, do not change stream unless
@@ -6412,6 +6401,26 @@
         mDeviceBroker.setBluetoothScoOn(on, eventSource);
     }
 
+    /** @see AudioManager#setA2dpSuspended(boolean) */
+    @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK)
+    public void setA2dpSuspended(boolean enable) {
+        super.setA2dpSuspended_enforcePermission();
+        final String eventSource = new StringBuilder("setA2dpSuspended(").append(enable)
+                .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
+                .append(Binder.getCallingPid()).toString();
+        mDeviceBroker.setA2dpSuspended(enable, false /*internal*/, eventSource);
+    }
+
+    /** @see AudioManager#setA2dpSuspended(boolean) */
+    @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK)
+    public void setLeAudioSuspended(boolean enable) {
+        super.setLeAudioSuspended_enforcePermission();
+        final String eventSource = new StringBuilder("setLeAudioSuspended(").append(enable)
+                .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
+                .append(Binder.getCallingPid()).toString();
+        mDeviceBroker.setLeAudioSuspended(enable, false /*internal*/, eventSource);
+    }
+
     /** @see AudioManager#isBluetoothScoOn()
      * Note that it doesn't report internal state, but state seen by apps (which may have
      * called setBluetoothScoOn() */
@@ -11021,6 +11030,11 @@
         dumpAccessibilityServiceUids(pw);
         dumpAssistantServicesUids(pw);
 
+        pw.print("  supportsBluetoothVariableLatency=");
+        pw.println(AudioSystem.supportsBluetoothVariableLatency());
+        pw.print("  isBluetoothVariableLatencyEnabled=");
+        pw.println(AudioSystem.isBluetoothVariableLatencyEnabled());
+
         dumpAudioPolicies(pw);
         mDynPolicyLogger.dump(pw);
         mPlaybackMonitor.dump(pw);
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index 6ad9390..6ebb42e 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -609,7 +609,7 @@
                     (mStreamType <= AudioSystem.getNumStreamTypes() && mStreamType >= 0)
                             ? AudioSystem.STREAM_NAMES[mStreamType]
                             : ("stream " + mStreamType);
-            return new StringBuilder("Error trying to unmute ")
+            return new StringBuilder("Invalid call to unmute ")
                     .append(streamName)
                     .append(" despite muted streams 0x")
                     .append(Integer.toHexString(mRingerZenMutedStreams))
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index bfa6c36e..e46c3cc 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -445,8 +445,8 @@
     /*package*/ synchronized void resetBluetoothSco() {
         mScoAudioState = SCO_STATE_INACTIVE;
         broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
-        AudioSystem.setParameters("A2dpSuspended=false");
-        AudioSystem.setParameters("LeAudioSuspended=false");
+        mDeviceBroker.clearA2dpSuspended();
+        mDeviceBroker.clearLeAudioSuspended();
         mDeviceBroker.setBluetoothScoOn(false, "resetBluetoothSco");
     }
 
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index f8cb9e9..4538cad 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -70,6 +70,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 import com.android.server.SystemService;
+import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -262,6 +263,11 @@
 
             final long identity = Binder.clearCallingIdentity();
             try {
+                VirtualDeviceManagerInternal vdm = getLocalService(
+                        VirtualDeviceManagerInternal.class);
+                if (vdm != null) {
+                    vdm.onAuthenticationPrompt(callingUid);
+                }
                 return mBiometricService.authenticate(
                         token, sessionId, userId, receiver, opPackageName, promptInfo);
             } finally {
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index bf5e8ee..1989bc7 100644
--- a/services/core/java/com/android/server/biometrics/AuthSession.java
+++ b/services/core/java/com/android/server/biometrics/AuthSession.java
@@ -21,8 +21,6 @@
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_NONE;
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR;
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR_BASE;
-import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_DEFAULT;
-import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE;
 
 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTHENTICATED_PENDING_SYSUI;
 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_CALLED;
@@ -44,7 +42,6 @@
 import android.hardware.biometrics.BiometricAuthenticator.Modality;
 import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricManager;
-import android.hardware.biometrics.BiometricManager.BiometricMultiSensorMode;
 import android.hardware.biometrics.BiometricPrompt;
 import android.hardware.biometrics.BiometricsProtoEnums;
 import android.hardware.biometrics.IBiometricSensorReceiver;
@@ -68,7 +65,6 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.Collection;
 import java.util.List;
 import java.util.Random;
 import java.util.function.Function;
@@ -134,7 +130,6 @@
 
     // The current state, which can be either idle, called, or started
     private @SessionState int mState = STATE_AUTH_IDLE;
-    private @BiometricMultiSensorMode int mMultiSensorMode;
     private int[] mSensors;
     // TODO(b/197265902): merge into state
     private boolean mCancelled;
@@ -255,7 +250,6 @@
             // SystemUI invokes that path.
             mState = STATE_SHOWING_DEVICE_CREDENTIAL;
             mSensors = new int[0];
-            mMultiSensorMode = BIOMETRIC_MULTI_SENSOR_DEFAULT;
 
             mStatusBarService.showAuthenticationDialog(
                     mPromptInfo,
@@ -266,8 +260,7 @@
                     mUserId,
                     mOperationId,
                     mOpPackageName,
-                    mRequestId,
-                    mMultiSensorMode);
+                    mRequestId);
         } else if (!mPreAuthInfo.eligibleSensors.isEmpty()) {
             // Some combination of biometric or biometric|credential is requested
             setSensorsToStateWaitingForCookie(false /* isTryAgain */);
@@ -310,8 +303,6 @@
                     for (int i = 0; i < mPreAuthInfo.eligibleSensors.size(); i++) {
                         mSensors[i] = mPreAuthInfo.eligibleSensors.get(i).id;
                     }
-                    mMultiSensorMode = getMultiSensorModeForNewSession(
-                            mPreAuthInfo.eligibleSensors);
 
                     mStatusBarService.showAuthenticationDialog(mPromptInfo,
                             mSysuiReceiver,
@@ -321,8 +312,7 @@
                             mUserId,
                             mOperationId,
                             mOpPackageName,
-                            mRequestId,
-                            mMultiSensorMode);
+                            mRequestId);
                     mState = STATE_AUTH_STARTED;
                 } catch (RemoteException e) {
                     Slog.e(TAG, "Remote exception", e);
@@ -438,7 +428,6 @@
                     mPromptInfo.setAuthenticators(authenticators);
 
                     mState = STATE_SHOWING_DEVICE_CREDENTIAL;
-                    mMultiSensorMode = BIOMETRIC_MULTI_SENSOR_DEFAULT;
                     mSensors = new int[0];
 
                     mStatusBarService.showAuthenticationDialog(
@@ -450,8 +439,7 @@
                             mUserId,
                             mOperationId,
                             mOpPackageName,
-                            mRequestId,
-                            mMultiSensorMode);
+                            mRequestId);
                 } else {
                     mClientReceiver.onError(modality, error, vendorCode);
                     return true;
@@ -545,13 +533,30 @@
         }
     }
 
-    void onDialogAnimatedIn() {
+    void onDialogAnimatedIn(boolean startFingerprintNow) {
         if (mState != STATE_AUTH_STARTED) {
             Slog.e(TAG, "onDialogAnimatedIn, unexpected state: " + mState);
             return;
         }
 
         mState = STATE_AUTH_STARTED_UI_SHOWING;
+        if (startFingerprintNow) {
+            startAllPreparedFingerprintSensors();
+        } else {
+            Slog.d(TAG, "delaying fingerprint sensor start");
+        }
+    }
+
+    // call once anytime after onDialogAnimatedIn() to indicate it's appropriate to start the
+    // fingerprint sensor (i.e. face auth has failed or is not available)
+    void onStartFingerprint() {
+        if (mState != STATE_AUTH_STARTED
+                && mState != STATE_AUTH_STARTED_UI_SHOWING
+                && mState != STATE_AUTH_PAUSED
+                && mState != STATE_ERROR_PENDING_SYSUI) {
+            Slog.w(TAG, "onStartFingerprint, started from unexpected state: " + mState);
+        }
+
         startAllPreparedFingerprintSensors();
     }
 
@@ -919,25 +924,6 @@
         }
     }
 
-    @BiometricMultiSensorMode
-    private static int getMultiSensorModeForNewSession(Collection<BiometricSensor> sensors) {
-        boolean hasFace = false;
-        boolean hasFingerprint = false;
-
-        for (BiometricSensor sensor: sensors) {
-            if (sensor.modality == TYPE_FACE) {
-                hasFace = true;
-            } else if (sensor.modality == TYPE_FINGERPRINT) {
-                hasFingerprint = true;
-            }
-        }
-
-        if (hasFace && hasFingerprint) {
-            return BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE;
-        }
-        return BIOMETRIC_MULTI_SENSOR_DEFAULT;
-    }
-
     @Override
     public String toString() {
         return "State: " + mState
diff --git a/services/core/java/com/android/server/biometrics/BiometricSensor.java b/services/core/java/com/android/server/biometrics/BiometricSensor.java
index bac4480..937e3f8 100644
--- a/services/core/java/com/android/server/biometrics/BiometricSensor.java
+++ b/services/core/java/com/android/server/biometrics/BiometricSensor.java
@@ -22,20 +22,14 @@
 import android.annotation.NonNull;
 import android.content.Context;
 import android.hardware.biometrics.BiometricConstants;
-import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.IBiometricAuthenticator;
 import android.hardware.biometrics.IBiometricSensorReceiver;
-import android.hardware.biometrics.SensorPropertiesInternal;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.text.TextUtils;
-import android.util.IndentingPrintWriter;
 import android.util.Slog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.Collections;
-import java.util.List;
 
 /**
  * Wraps IBiometricAuthenticator implementation and stores information about the authenticator,
@@ -73,7 +67,6 @@
     public final int id;
     public final @Authenticators.Types int oemStrength; // strength as configured by the OEM
     public final int modality;
-    @NonNull public final List<ComponentInfoInternal> componentInfo;
     public final IBiometricAuthenticator impl;
 
     private @Authenticators.Types int mUpdatedStrength; // updated by BiometricStrengthController
@@ -93,16 +86,15 @@
      */
     abstract boolean confirmationSupported();
 
-    BiometricSensor(@NonNull Context context, int modality, @NonNull SensorPropertiesInternal props,
-            IBiometricAuthenticator impl) {
+    BiometricSensor(@NonNull Context context, int id, int modality,
+            @Authenticators.Types int strength, IBiometricAuthenticator impl) {
         this.mContext = context;
-        this.id = props.sensorId;
+        this.id = id;
         this.modality = modality;
-        this.oemStrength = Utils.propertyStrengthToAuthenticatorStrength(props.sensorStrength);
-        this.componentInfo = Collections.unmodifiableList(props.componentInfo);
+        this.oemStrength = strength;
         this.impl = impl;
 
-        mUpdatedStrength = oemStrength;
+        mUpdatedStrength = strength;
         goToStateUnknown();
     }
 
@@ -186,25 +178,8 @@
         return "ID(" + id + ")"
                 + ", oemStrength: " + oemStrength
                 + ", updatedStrength: " + mUpdatedStrength
-                + ", modality: " + modality
+                + ", modality " + modality
                 + ", state: " + mSensorState
                 + ", cookie: " + mCookie;
     }
-
-    protected void dump(@NonNull IndentingPrintWriter pw) {
-        pw.println(TextUtils.formatSimple("ID: %d", id));
-        pw.increaseIndent();
-        pw.println(TextUtils.formatSimple("oemStrength: %d", oemStrength));
-        pw.println(TextUtils.formatSimple("updatedStrength: %d", mUpdatedStrength));
-        pw.println(TextUtils.formatSimple("modality: %d", modality));
-        pw.println("componentInfo:");
-        for (ComponentInfoInternal info : componentInfo) {
-            pw.increaseIndent();
-            info.dump(pw);
-            pw.decreaseIndent();
-        }
-        pw.println(TextUtils.formatSimple("state: %d", mSensorState));
-        pw.println(TextUtils.formatSimple("cookie: %d", mCookie));
-        pw.decreaseIndent();
-    }
 }
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 0ab74b8..0942d85 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -64,7 +64,6 @@
 import android.security.KeyStore;
 import android.text.TextUtils;
 import android.util.ArraySet;
-import android.util.IndentingPrintWriter;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
@@ -481,8 +480,13 @@
             }
 
             @Override
-            public void onDialogAnimatedIn() {
-                mHandler.post(() -> handleOnDialogAnimatedIn(requestId));
+            public void onDialogAnimatedIn(boolean startFingerprintNow) {
+                mHandler.post(() -> handleOnDialogAnimatedIn(requestId, startFingerprintNow));
+            }
+
+            @Override
+            public void onStartFingerprintNow() {
+                mHandler.post(() -> handleOnStartFingerprintNow(requestId));
             }
         };
     }
@@ -642,16 +646,13 @@
 
         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
-        public synchronized void registerAuthenticator(int modality,
-                @NonNull SensorPropertiesInternal props,
+        public synchronized void registerAuthenticator(int id, int modality,
+                @Authenticators.Types int strength,
                 @NonNull IBiometricAuthenticator authenticator) {
 
             super.registerAuthenticator_enforcePermission();
 
-            @Authenticators.Types final int strength =
-                    Utils.propertyStrengthToAuthenticatorStrength(props.sensorStrength);
-
-            Slog.d(TAG, "Registering ID: " + props.sensorId
+            Slog.d(TAG, "Registering ID: " + id
                     + " Modality: " + modality
                     + " Strength: " + strength);
 
@@ -672,12 +673,12 @@
             }
 
             for (BiometricSensor sensor : mSensors) {
-                if (sensor.id == props.sensorId) {
+                if (sensor.id == id) {
                     throw new IllegalStateException("Cannot register duplicate authenticator");
                 }
             }
 
-            mSensors.add(new BiometricSensor(getContext(), modality, props, authenticator) {
+            mSensors.add(new BiometricSensor(getContext(), id, modality, strength, authenticator) {
                 @Override
                 boolean confirmationAlwaysRequired(int userId) {
                     return mSettingObserver.getConfirmationAlwaysRequired(modality, userId);
@@ -1241,7 +1242,7 @@
         }
     }
 
-    private void handleOnDialogAnimatedIn(long requestId) {
+    private void handleOnDialogAnimatedIn(long requestId, boolean startFingerprintNow) {
         Slog.d(TAG, "handleOnDialogAnimatedIn");
 
         final AuthSession session = getAuthSessionIfCurrent(requestId);
@@ -1250,7 +1251,19 @@
             return;
         }
 
-        session.onDialogAnimatedIn();
+        session.onDialogAnimatedIn(startFingerprintNow);
+    }
+
+    private void handleOnStartFingerprintNow(long requestId) {
+        Slog.d(TAG, "handleOnStartFingerprintNow");
+
+        final AuthSession session = getAuthSessionIfCurrent(requestId);
+        if (session == null) {
+            Slog.w(TAG, "handleOnStartFingerprintNow: AuthSession is not current");
+            return;
+        }
+
+        session.onStartFingerprint();
     }
 
     /**
@@ -1376,17 +1389,13 @@
         return null;
     }
 
-    private void dumpInternal(PrintWriter printWriter) {
-        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter);
-
+    private void dumpInternal(PrintWriter pw) {
         pw.println("Legacy Settings: " + mSettingObserver.mUseLegacyFaceOnlySettings);
         pw.println();
 
         pw.println("Sensors:");
         for (BiometricSensor sensor : mSensors) {
-            pw.increaseIndent();
-            sensor.dump(pw);
-            pw.decreaseIndent();
+            pw.println(" " + sensor);
         }
         pw.println();
         pw.println("CurrentSession: " + mAuthSession);
diff --git a/services/core/java/com/android/server/biometrics/TEST_MAPPING b/services/core/java/com/android/server/biometrics/TEST_MAPPING
index daca00b..9e60ba8 100644
--- a/services/core/java/com/android/server/biometrics/TEST_MAPPING
+++ b/services/core/java/com/android/server/biometrics/TEST_MAPPING
@@ -6,24 +6,5 @@
         {
             "name": "CtsBiometricsHostTestCases"
         }
-    ],
-    "ironwood-postsubmit": [
-     {
-      "name": "BiometricsE2eTests",
-      "options": [
-        {
-            "include-annotation": "android.platform.test.annotations.IwTest"
-        },
-        {
-            "exclude-annotation": "org.junit.Ignore"
-        },
-        {
-            "include-filter": "android.platform.test.scenario.biometrics"
-        },
-        {
-            "exclude-annotation": "android.platform.test.annotations.FlakyTest"
-        }
-      ]
-    }
-   ]
+    ]
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
index 055c63d..46c77e8 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
@@ -206,17 +206,6 @@
         }
     }
 
-    protected final void vibrateError() {
-        Vibrator vibrator = getContext().getSystemService(Vibrator.class);
-        if (vibrator != null && mShouldVibrate) {
-            vibrator.vibrate(Process.myUid(),
-                    getContext().getOpPackageName(),
-                    ERROR_VIBRATION_EFFECT,
-                    getClass().getSimpleName() + "::error",
-                    HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
-        }
-    }
-
     @Override
     public boolean isInterruptable() {
         return true;
diff --git a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
index a486d16..694dfd2 100644
--- a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
@@ -70,9 +70,11 @@
 
                 // Set mStopUserClient to null when StopUserClient fails. Otherwise it's possible
                 // for that the queue will wait indefinitely until the field is cleared.
-                if (clientMonitor instanceof StopUserClient<?> && !success) {
-                    Slog.w(getTag(),
-                            "StopUserClient failed(), is the HAL stuck? Clearing mStopUserClient");
+                if (clientMonitor instanceof StopUserClient<?>) {
+                    if (!success) {
+                        Slog.w(getTag(), "StopUserClient failed(), is the HAL stuck? "
+                                + "Clearing mStopUserClient");
+                    }
                     mStopUserClient = null;
                 }
                 if (mCurrentOperation != null && mCurrentOperation.isFor(mOwner)) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceServiceRegistry.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceServiceRegistry.java
index d43045b..0f0a81d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceServiceRegistry.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceServiceRegistry.java
@@ -20,6 +20,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.IBiometricService;
 import android.hardware.face.FaceSensorPropertiesInternal;
 import android.hardware.face.IFaceAuthenticatorsRegisteredCallback;
@@ -27,6 +28,7 @@
 import android.os.RemoteException;
 import android.util.Slog;
 
+import com.android.server.biometrics.Utils;
 import com.android.server.biometrics.sensors.BiometricServiceRegistry;
 
 import java.util.List;
@@ -51,8 +53,10 @@
     @Override
     protected void registerService(@NonNull IBiometricService service,
             @NonNull FaceSensorPropertiesInternal props) {
+        @BiometricManager.Authenticators.Types final int strength =
+                Utils.propertyStrengthToAuthenticatorStrength(props.sensorStrength);
         try {
-            service.registerAuthenticator(TYPE_FACE, props,
+            service.registerAuthenticator(props.sensorId, TYPE_FACE, strength,
                     new FaceAuthenticator(mService, props.sensorId));
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception when registering sensorId: " + props.sensorId);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
index 9dc1782..a529fb9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
@@ -72,7 +72,7 @@
             boolean isStrongBiometric, SensorPrivacyManager sensorPrivacyManager) {
         super(context, lazyDaemon, token, listener, options.getUserId(),
                 options.getOpPackageName(), 0 /* cookie */, options.getSensorId(),
-                true /* shouldVibrate */, logger, biometricContext);
+                false /* shouldVibrate */, logger, biometricContext);
         setRequestId(requestId);
         mIsStrongBiometric = isStrongBiometric;
         mSensorPrivacyManager = sensorPrivacyManager;
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 ffbf4e1..2ad41c2 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
@@ -89,7 +89,7 @@
     @NonNull private final Map<Integer, Long> mAuthenticatorIds;
 
     @NonNull private final Supplier<AidlSession> mLazySession;
-    @Nullable private AidlSession mCurrentSession;
+    @Nullable AidlSession mCurrentSession;
 
     @VisibleForTesting
     public static class HalSessionCallback extends ISessionCallback.Stub {
@@ -486,7 +486,7 @@
     Sensor(@NonNull String tag, @NonNull FaceProvider provider, @NonNull Context context,
             @NonNull Handler handler, @NonNull FaceSensorPropertiesInternal sensorProperties,
             @NonNull LockoutResetDispatcher lockoutResetDispatcher,
-            @NonNull BiometricContext biometricContext) {
+            @NonNull BiometricContext biometricContext, AidlSession session) {
         mTag = tag;
         mProvider = provider;
         mContext = context;
@@ -549,6 +549,14 @@
         mLazySession = () -> mCurrentSession != null ? mCurrentSession : null;
     }
 
+    Sensor(@NonNull String tag, @NonNull FaceProvider provider, @NonNull Context context,
+            @NonNull Handler handler, @NonNull FaceSensorPropertiesInternal sensorProperties,
+            @NonNull LockoutResetDispatcher lockoutResetDispatcher,
+            @NonNull BiometricContext biometricContext) {
+        this(tag, provider, context, handler, sensorProperties, lockoutResetDispatcher,
+                biometricContext, null);
+    }
+
     @NonNull Supplier<AidlSession> getLazySession() {
         return mLazySession;
     }
@@ -557,7 +565,7 @@
         return mSensorProperties;
     }
 
-    @Nullable AidlSession getSessionForUser(int userId) {
+    @VisibleForTesting @Nullable AidlSession getSessionForUser(int userId) {
         if (mCurrentSession != null && mCurrentSession.getUserId() == userId) {
             return mCurrentSession;
         } else {
@@ -641,6 +649,8 @@
                     BiometricsProtoEnums.MODALITY_FACE,
                     BiometricsProtoEnums.ISSUE_HAL_DEATH,
                     -1 /* sensorId */);
+        } else if (client != null) {
+            client.cancel();
         }
 
         mScheduler.recordCrashState();
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 6c26e2b..ece35c5 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -91,6 +91,7 @@
 import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
 import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21;
 import com.android.server.biometrics.sensors.fingerprint.hidl.Fingerprint21UdfpsMock;
+import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
 
 import com.google.android.collect.Lists;
 
@@ -329,6 +330,16 @@
                     return -1;
                 }
             }
+            final long identity2 = Binder.clearCallingIdentity();
+            try {
+                VirtualDeviceManagerInternal vdm = getLocalService(
+                        VirtualDeviceManagerInternal.class);
+                if (vdm != null) {
+                    vdm.onAuthenticationPrompt(callingUid);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity2);
+            }
             return provider.second.scheduleAuthenticate(token, operationId,
                     0 /* cookie */, new ClientMonitorCallbackConverter(receiver), options,
                     restricted, statsClient, isKeyguard);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistry.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistry.java
index 6d210ea..33810b7 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistry.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistry.java
@@ -20,6 +20,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.IBiometricService;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
@@ -27,6 +28,7 @@
 import android.os.RemoteException;
 import android.util.Slog;
 
+import com.android.server.biometrics.Utils;
 import com.android.server.biometrics.sensors.BiometricServiceRegistry;
 
 import java.util.List;
@@ -51,8 +53,10 @@
     @Override
     protected void registerService(@NonNull IBiometricService service,
             @NonNull FingerprintSensorPropertiesInternal props) {
+        @BiometricManager.Authenticators.Types final int strength =
+                Utils.propertyStrengthToAuthenticatorStrength(props.sensorStrength);
         try {
-            service.registerAuthenticator(TYPE_FINGERPRINT, props,
+            service.registerAuthenticator(props.sensorId, TYPE_FINGERPRINT, strength,
                     new FingerprintAuthenticator(mService, props.sensorId));
         } catch (RemoteException e) {
             Slog.e(TAG, "Remote exception when registering sensorId: " + props.sensorId);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
index c0dde72..56b85ce 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
@@ -90,7 +90,7 @@
     @NonNull private final LockoutCache mLockoutCache;
     @NonNull private final Map<Integer, Long> mAuthenticatorIds;
 
-    @Nullable private AidlSession mCurrentSession;
+    @Nullable AidlSession mCurrentSession;
     @NonNull private final Supplier<AidlSession> mLazySession;
 
     @VisibleForTesting
@@ -439,7 +439,7 @@
             @NonNull Handler handler, @NonNull FingerprintSensorPropertiesInternal sensorProperties,
             @NonNull LockoutResetDispatcher lockoutResetDispatcher,
             @NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
-            @NonNull BiometricContext biometricContext) {
+            @NonNull BiometricContext biometricContext, AidlSession session) {
         mTag = tag;
         mProvider = provider;
         mContext = context;
@@ -501,6 +501,16 @@
                 });
         mAuthenticatorIds = new HashMap<>();
         mLazySession = () -> mCurrentSession != null ? mCurrentSession : null;
+        mCurrentSession = session;
+    }
+
+    Sensor(@NonNull String tag, @NonNull FingerprintProvider provider, @NonNull Context context,
+            @NonNull Handler handler, @NonNull FingerprintSensorPropertiesInternal sensorProperties,
+            @NonNull LockoutResetDispatcher lockoutResetDispatcher,
+            @NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
+            @NonNull BiometricContext biometricContext) {
+        this(tag, provider, context, handler, sensorProperties, lockoutResetDispatcher,
+                gestureAvailabilityDispatcher, biometricContext, null);
     }
 
     @NonNull Supplier<AidlSession> getLazySession() {
@@ -599,6 +609,8 @@
                     BiometricsProtoEnums.MODALITY_FINGERPRINT,
                     BiometricsProtoEnums.ISSUE_HAL_DEATH,
                     -1 /* sensorId */);
+        } else if (client != null) {
+            client.cancel();
         }
 
         mScheduler.recordCrashState();
diff --git a/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
index f27761f..35ea36c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
@@ -16,10 +16,12 @@
 
 package com.android.server.biometrics.sensors.iris;
 
+import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS;
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.IBiometricService;
 import android.hardware.biometrics.SensorPropertiesInternal;
 import android.hardware.iris.IIrisService;
@@ -31,6 +33,7 @@
 
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
+import com.android.server.biometrics.Utils;
 
 import java.util.List;
 
@@ -72,12 +75,17 @@
                         ServiceManager.getService(Context.BIOMETRIC_SERVICE));
 
                 for (SensorPropertiesInternal hidlSensor : hidlSensors) {
+                    final int sensorId = hidlSensor.sensorId;
+                    final @BiometricManager.Authenticators.Types int strength =
+                            Utils.propertyStrengthToAuthenticatorStrength(
+                                    hidlSensor.sensorStrength);
+                    final IrisAuthenticator authenticator = new IrisAuthenticator(mServiceWrapper,
+                            sensorId);
                     try {
-                        biometricService.registerAuthenticator(TYPE_IRIS, hidlSensor,
-                                new IrisAuthenticator(mServiceWrapper, hidlSensor.sensorId));
+                        biometricService.registerAuthenticator(sensorId, TYPE_IRIS, strength,
+                                authenticator);
                     } catch (RemoteException e) {
-                        Slog.e(TAG, "Remote exception when registering sensorId: "
-                                + hidlSensor.sensorId);
+                        Slog.e(TAG, "Remote exception when registering sensorId: " + sensorId);
                     }
                 }
             });
diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
index 6a01042..42b2682 100644
--- a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
@@ -16,6 +16,8 @@
 
 package com.android.server.broadcastradio;
 
+import android.Manifest;
+import android.content.pm.PackageManager;
 import android.hardware.broadcastradio.IBroadcastRadio;
 import android.hardware.radio.IAnnouncementListener;
 import android.hardware.radio.ICloseHandle;
@@ -23,6 +25,7 @@
 import android.hardware.radio.ITuner;
 import android.hardware.radio.ITunerCallback;
 import android.hardware.radio.RadioManager;
+import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -112,6 +115,13 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        if (mService.getContext().checkCallingOrSelfPermission(Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            printWriter.println("Permission Denial: can't dump AIDL BroadcastRadioService from "
+                    + "from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+                    + " without permission " + Manifest.permission.DUMP);
+            return;
+        }
         IndentingPrintWriter radioPrintWriter = new IndentingPrintWriter(printWriter);
         radioPrintWriter.printf("BroadcastRadioService\n");
 
diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
index 408fba1..bc72a4b 100644
--- a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
@@ -16,12 +16,15 @@
 
 package com.android.server.broadcastradio;
 
+import android.Manifest;
+import android.content.pm.PackageManager;
 import android.hardware.radio.IAnnouncementListener;
 import android.hardware.radio.ICloseHandle;
 import android.hardware.radio.IRadioService;
 import android.hardware.radio.ITuner;
 import android.hardware.radio.ITunerCallback;
 import android.hardware.radio.RadioManager;
+import android.os.Binder;
 import android.os.RemoteException;
 import android.util.IndentingPrintWriter;
 import android.util.Log;
@@ -129,6 +132,13 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mService.getContext().checkCallingOrSelfPermission(Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump HIDL BroadcastRadioService from "
+                    + "from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+                    + " without permission " + Manifest.permission.DUMP);
+            return;
+        }
         IndentingPrintWriter radioPw = new IndentingPrintWriter(pw);
         radioPw.printf("BroadcastRadioService\n");
 
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index 0315352..0b04159 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -38,6 +38,7 @@
 import android.content.pm.ParceledListSlice;
 import android.content.res.Configuration;
 import android.graphics.Rect;
+import android.hardware.CameraExtensionSessionStats;
 import android.hardware.CameraSessionStats;
 import android.hardware.CameraStreamStats;
 import android.hardware.ICameraService;
@@ -247,6 +248,7 @@
         public final int mSessionIndex;
 
         private long mDurationOrStartTimeMs;  // Either start time, or duration once completed
+        public CameraExtensionSessionStats mExtSessionStats = null;
 
         CameraUsageEvent(String cameraId, int facing, String clientName, int apiLevel,
                 boolean isNdk, int action, int latencyMs, int operatingMode, boolean deviceError,
@@ -269,7 +271,7 @@
         public void markCompleted(int internalReconfigure, long requestCount,
                 long resultErrorCount, boolean deviceError,
                 List<CameraStreamStats>  streamStats, String userTag,
-                int videoStabilizationMode) {
+                int videoStabilizationMode, CameraExtensionSessionStats extStats) {
             if (mCompleted) {
                 return;
             }
@@ -282,6 +284,7 @@
             mStreamStats = streamStats;
             mUserTag = userTag;
             mVideoStabilizationMode = videoStabilizationMode;
+            mExtSessionStats = extStats;
             if (CameraServiceProxy.DEBUG) {
                 Slog.v(TAG, "A camera facing " + cameraFacingToString(mCameraFacing) +
                         " was in use by " + mClientName + " for " +
@@ -825,6 +828,36 @@
                     Slog.w(TAG, "Unknown camera facing: " + e.mCameraFacing);
             }
 
+            int extensionType = FrameworkStatsLog.CAMERA_ACTION_EVENT__EXT_TYPE__EXTENSION_NONE;
+            boolean extensionIsAdvanced = false;
+            if (e.mExtSessionStats != null) {
+                switch (e.mExtSessionStats.type) {
+                    case CameraExtensionSessionStats.Type.EXTENSION_AUTOMATIC:
+                        extensionType = FrameworkStatsLog
+                                .CAMERA_ACTION_EVENT__EXT_TYPE__EXTENSION_AUTOMATIC;
+                        break;
+                    case CameraExtensionSessionStats.Type.EXTENSION_FACE_RETOUCH:
+                        extensionType = FrameworkStatsLog
+                                .CAMERA_ACTION_EVENT__EXT_TYPE__EXTENSION_FACE_RETOUCH;
+                        break;
+                    case CameraExtensionSessionStats.Type.EXTENSION_BOKEH:
+                        extensionType =
+                                FrameworkStatsLog.CAMERA_ACTION_EVENT__EXT_TYPE__EXTENSION_BOKEH;
+                        break;
+                    case CameraExtensionSessionStats.Type.EXTENSION_HDR:
+                        extensionType =
+                                FrameworkStatsLog.CAMERA_ACTION_EVENT__EXT_TYPE__EXTENSION_HDR;
+                        break;
+                    case CameraExtensionSessionStats.Type.EXTENSION_NIGHT:
+                        extensionType =
+                                FrameworkStatsLog.CAMERA_ACTION_EVENT__EXT_TYPE__EXTENSION_NIGHT;
+                        break;
+                    default:
+                        Slog.w(TAG, "Unknown extension type: " + e.mExtSessionStats.type);
+                }
+                extensionIsAdvanced = e.mExtSessionStats.isAdvanced;
+            }
+
             int streamCount = 0;
             if (e.mStreamStats != null) {
                 streamCount = e.mStreamStats.size();
@@ -847,7 +880,9 @@
                         + ", userTag is " + e.mUserTag
                         + ", videoStabilizationMode " + e.mVideoStabilizationMode
                         + ", logId " + e.mLogId
-                        + ", sessionIndex " + e.mSessionIndex);
+                        + ", sessionIndex " + e.mSessionIndex
+                        + ", mExtSessionStats {type " + extensionType
+                        + " isAdvanced " + extensionIsAdvanced + "}");
             }
             // Convert from CameraStreamStats to CameraStreamProto
             CameraStreamProto[] streamProtos = new CameraStreamProto[MAX_STREAM_STATISTICS];
@@ -907,7 +942,8 @@
                     MessageNano.toByteArray(streamProtos[2]),
                     MessageNano.toByteArray(streamProtos[3]),
                     MessageNano.toByteArray(streamProtos[4]),
-                    e.mUserTag, e.mVideoStabilizationMode, e.mLogId, e.mSessionIndex);
+                    e.mUserTag, e.mVideoStabilizationMode, e.mLogId, e.mSessionIndex,
+                    extensionType, extensionIsAdvanced);
         }
     }
 
@@ -1098,6 +1134,7 @@
         int videoStabilizationMode = cameraState.getVideoStabilizationMode();
         long logId = cameraState.getLogId();
         int sessionIdx = cameraState.getSessionIndex();
+        CameraExtensionSessionStats extSessionStats = cameraState.getExtensionSessionStats();
         synchronized(mLock) {
             // Update active camera list and notify NFC if necessary
             boolean wasEmpty = mActiveCameraUsage.isEmpty();
@@ -1152,7 +1189,8 @@
                         Slog.w(TAG, "Camera " + cameraId + " was already marked as active");
                         oldEvent.markCompleted(/*internalReconfigure*/0, /*requestCount*/0,
                                 /*resultErrorCount*/0, /*deviceError*/false, streamStats,
-                                /*userTag*/"", /*videoStabilizationMode*/-1);
+                                /*userTag*/"", /*videoStabilizationMode*/-1,
+                                new CameraExtensionSessionStats());
                         mCameraUsageHistory.add(oldEvent);
                     }
                     break;
@@ -1163,7 +1201,7 @@
 
                         doneEvent.markCompleted(internalReconfigureCount, requestCount,
                                 resultErrorCount, deviceError, streamStats, userTag,
-                                videoStabilizationMode);
+                                videoStabilizationMode, extSessionStats);
                         mCameraUsageHistory.add(doneEvent);
                         // Do not double count device error
                         deviceError = false;
diff --git a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
index a335338..4d12574 100644
--- a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
+++ b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
@@ -70,6 +70,11 @@
     public abstract void onAppsOnVirtualDeviceChanged();
 
     /**
+     * Notifies that an authentication prompt is about to be shown for an app with the given uid.
+     */
+    public abstract void onAuthenticationPrompt(int uid);
+
+    /**
      * Gets the owner uid for a deviceId.
      *
      * @param deviceId which device we're asking about
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 4208a12..d4bb445 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -3828,10 +3828,27 @@
                     }, retryDelayMs, TimeUnit.MILLISECONDS);
         }
 
+        private boolean significantCapsChange(@Nullable final NetworkCapabilities left,
+                @Nullable final NetworkCapabilities right) {
+            if (left == right) return false;
+            return null == left
+                    || null == right
+                    || !Arrays.equals(left.getTransportTypes(), right.getTransportTypes())
+                    || !Arrays.equals(left.getCapabilities(), right.getCapabilities())
+                    || !Arrays.equals(left.getEnterpriseIds(), right.getEnterpriseIds())
+                    || !Objects.equals(left.getTransportInfo(), right.getTransportInfo())
+                    || !Objects.equals(left.getAllowedUids(), right.getAllowedUids())
+                    || !Objects.equals(left.getUnderlyingNetworks(), right.getUnderlyingNetworks())
+                    || !Objects.equals(left.getNetworkSpecifier(), right.getNetworkSpecifier());
+        }
+
         /** Called when the NetworkCapabilities of underlying network is changed */
         public void onDefaultNetworkCapabilitiesChanged(@NonNull NetworkCapabilities nc) {
-            mEventChanges.log("[UnderlyingNW] Cap changed from "
-                    + mUnderlyingNetworkCapabilities + " to " + nc);
+            if (significantCapsChange(mUnderlyingNetworkCapabilities, nc)) {
+                // TODO : make this log terser
+                mEventChanges.log("[UnderlyingNW] Cap changed from "
+                        + mUnderlyingNetworkCapabilities + " to " + nc);
+            }
             final NetworkCapabilities oldNc = mUnderlyingNetworkCapabilities;
             mUnderlyingNetworkCapabilities = nc;
             if (oldNc == null || !nc.getSubscriptionIds().equals(oldNc.getSubscriptionIds())) {
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index 9645690..eb7fa10 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -17,6 +17,7 @@
 package com.android.server.devicestate;
 
 import static android.Manifest.permission.CONTROL_DEVICE_STATE;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
 import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE;
@@ -73,6 +74,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import java.util.WeakHashMap;
@@ -162,7 +164,7 @@
     @GuardedBy("mLock")
     private final SparseArray<ProcessRecord> mProcessRecords = new SparseArray<>();
 
-    private Set<Integer> mDeviceStatesAvailableForAppRequests;
+    private Set<Integer> mDeviceStatesAvailableForAppRequests = new HashSet<>();
 
     private Set<Integer> mFoldedDeviceStates;
 
@@ -203,7 +205,7 @@
 
     @VisibleForTesting
     DeviceStateManagerService(@NonNull Context context, @NonNull DeviceStatePolicy policy,
-                @NonNull SystemPropertySetter systemPropertySetter) {
+            @NonNull SystemPropertySetter systemPropertySetter) {
         super(context);
         mSystemPropertySetter = systemPropertySetter;
         // We use the DisplayThread because this service indirectly drives
@@ -340,16 +342,20 @@
         return supportedStates;
     }
 
+    /**
+     * Returns the current {@link DeviceStateInfo} of the device. If there has been no base state
+     * or committed state provided, {@link DeviceStateManager#INVALID_DEVICE_STATE} will be returned
+     * respectively. The supported states will always be included.
+     *
+     */
+    @GuardedBy("mLock")
     @NonNull
     private DeviceStateInfo getDeviceStateInfoLocked() {
-        if (!mBaseState.isPresent() || !mCommittedState.isPresent()) {
-            throw new IllegalStateException("Trying to get the current DeviceStateInfo before the"
-                    + " initial state has been committed.");
-        }
-
         final int[] supportedStates = getSupportedStateIdentifiersLocked();
-        final int baseState = mBaseState.get().getIdentifier();
-        final int currentState = mCommittedState.get().getIdentifier();
+        final int baseState =
+                mBaseState.isPresent() ? mBaseState.get().getIdentifier() : INVALID_DEVICE_STATE;
+        final int currentState = mCommittedState.isPresent() ? mCommittedState.get().getIdentifier()
+                : INVALID_DEVICE_STATE;
 
         return new DeviceStateInfo(supportedStates, baseState, currentState);
     }
@@ -389,12 +395,7 @@
 
             setRearDisplayStateLocked();
 
-            if (!mPendingState.isPresent()) {
-                // If the change in the supported states didn't result in a change of the pending
-                // state commitPendingState() will never be called and the callbacks will never be
-                // notified of the change.
-                notifyDeviceStateInfoChangedAsync();
-            }
+            notifyDeviceStateInfoChangedAsync();
 
             mHandler.post(this::notifyPolicyIfNeeded);
         }
@@ -458,12 +459,7 @@
             mOverrideRequestController.handleBaseStateChanged(identifier);
             updatePendingStateLocked();
 
-            if (!mPendingState.isPresent()) {
-                // If the change in base state didn't result in a change of the pending state
-                // commitPendingState() will never be called and the callbacks will never be
-                // notified of the change.
-                notifyDeviceStateInfoChangedAsync();
-            }
+            notifyDeviceStateInfoChangedAsync();
 
             mHandler.post(this::notifyPolicyIfNeeded);
         }
@@ -591,6 +587,18 @@
 
     private void notifyDeviceStateInfoChangedAsync() {
         synchronized (mLock) {
+            if (mPendingState.isPresent()) {
+                Slog.i(TAG,
+                        "Cannot notify device state info change when pending state is present.");
+                return;
+            }
+
+            if (!mBaseState.isPresent() || !mCommittedState.isPresent()) {
+                Slog.e(TAG, "Cannot notify device state info change before the initial state has"
+                        + " been committed.");
+                return;
+            }
+
             if (mProcessRecords.size() == 0) {
                 return;
             }
@@ -656,7 +664,7 @@
             }
         } else {
             throw new IllegalArgumentException(
-                        "Unknown OverrideRest type: " + request.getRequestType());
+                    "Unknown OverrideRest type: " + request.getRequestType());
         }
 
         boolean updatedPendingState = updatePendingStateLocked();
@@ -711,6 +719,9 @@
             }
             mProcessRecords.put(pid, record);
 
+            // Callback clients should not be notified of invalid device states, so calls to
+            // #getDeviceStateInfoLocked should be gated on checks if a committed state is present
+            // before getting the device state info.
             DeviceStateInfo currentInfo = mCommittedState.isPresent()
                     ? getDeviceStateInfoLocked() : null;
             if (currentInfo != null) {
@@ -879,8 +890,16 @@
      * @param callingPid Process ID that is requesting this state change
      * @param state state that is being requested.
      */
-    private void assertCanRequestDeviceState(int callingPid, int state) {
-        if (!isTopApp(callingPid) || !isStateAvailableForAppRequests(state)) {
+    private void assertCanRequestDeviceState(int callingPid, int callingUid, int state) {
+        final boolean isTopApp = isTopApp(callingPid);
+        final boolean isForegroundApp = isForegroundApp(callingPid, callingUid);
+        final boolean isStateAvailableForAppRequests = isStateAvailableForAppRequests(state);
+
+        final boolean canRequestState = isTopApp
+                && isForegroundApp
+                && isStateAvailableForAppRequests;
+
+        if (!canRequestState) {
             getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE,
                     "Permission required to request device state, "
                             + "or the call must come from the top app "
@@ -893,15 +912,43 @@
      * not the top app, then check if this process holds the CONTROL_DEVICE_STATE permission.
      *
      * @param callingPid Process ID that is requesting this state change
+     * @param callingUid UID that is requesting this state change
      */
-    private void assertCanControlDeviceState(int callingPid) {
-        if (!isTopApp(callingPid)) {
+    private void assertCanControlDeviceState(int callingPid, int callingUid) {
+        final boolean isTopApp = isTopApp(callingPid);
+        final boolean isForegroundApp = isForegroundApp(callingPid, callingUid);
+
+        final boolean canControlState = isTopApp && isForegroundApp;
+
+        if (!canControlState) {
             getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE,
                     "Permission required to request device state, "
                             + "or the call must come from the top app.");
         }
     }
 
+    /**
+     * Checks if the caller is in the foreground. Note that callers may be the top app as returned
+     * from {@link #isTopApp(int)}, but not be in the foreground. For example, keyguard may be on
+     * top of the top app.
+     */
+    private boolean isForegroundApp(int callingPid, int callingUid) {
+        try {
+            final List<ActivityManager.RunningAppProcessInfo> procs =
+                    ActivityManager.getService().getRunningAppProcesses();
+            for (int i = 0; i < procs.size(); i++) {
+                ActivityManager.RunningAppProcessInfo proc = procs.get(i);
+                if (proc.pid == callingPid && proc.uid == callingUid
+                        && proc.importance <= IMPORTANCE_FOREGROUND) {
+                    return true;
+                }
+            }
+        } catch (RemoteException e) {
+            Slog.w(TAG, "am.getRunningAppProcesses() failed", e);
+        }
+        return false;
+    }
+
     private boolean isTopApp(int callingPid) {
         final WindowProcessController topApp = mActivityTaskManagerInternal.getTopApp();
         return topApp != null && topApp.getPid() == callingPid;
@@ -918,7 +965,6 @@
      */
     @GuardedBy("mLock")
     private void readStatesAvailableForRequestFromApps() {
-        mDeviceStatesAvailableForAppRequests = new HashSet<>();
         String[] availableAppStatesConfigIdentifiers = getContext().getResources()
                 .getStringArray(R.array.config_deviceStatesAvailableForAppRequests);
         for (int i = 0; i < availableAppStatesConfigIdentifiers.length; i++) {
@@ -1089,6 +1135,7 @@
 
     /** Implementation of {@link IDeviceStateManager} published as a binder service. */
     private final class BinderService extends IDeviceStateManager.Stub {
+
         @Override // Binder call
         public DeviceStateInfo getDeviceStateInfo() {
             synchronized (mLock) {
@@ -1118,7 +1165,7 @@
             // Allow top processes to request a device state change
             // If the calling process ID is not the top app, then we check if this process
             // holds a permission to CONTROL_DEVICE_STATE
-            assertCanRequestDeviceState(callingPid, state);
+            assertCanRequestDeviceState(callingPid, callingUid, state);
 
             if (token == null) {
                 throw new IllegalArgumentException("Request token must not be null.");
@@ -1139,10 +1186,11 @@
         @Override // Binder call
         public void cancelStateRequest() {
             final int callingPid = Binder.getCallingPid();
+            final int callingUid = Binder.getCallingUid();
             // Allow top processes to cancel a device state change
             // If the calling process ID is not the top app, then we check if this process
             // holds a permission to CONTROL_DEVICE_STATE
-            assertCanControlDeviceState(callingPid);
+            assertCanControlDeviceState(callingPid, callingUid);
 
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index 22b6a53..d550650 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -316,7 +316,9 @@
     }
 
     /**
-     * Notify the BrightnessTracker that the user has changed the brightness of the display.
+     * Notify the BrightnessTracker that the brightness of the display has changed.
+     * We pass both the user change and system changes, so that we know the starting point
+     * of the next user interaction. Only user interactions are then sent as BrightnessChangeEvents.
      */
     public void notifyBrightnessChanged(float brightness, boolean userInitiated,
             float powerBrightnessFactor, boolean wasShortTermModelActive,
@@ -352,10 +354,8 @@
                 // Not currently gathering brightness change information
                 return;
             }
-
             float previousBrightness = mLastBrightness;
             mLastBrightness = brightness;
-
             if (!userInitiated) {
                 // We want to record what current brightness is so that we know what the user
                 // changed it from, but if it wasn't user initiated then we don't want to record it
@@ -429,7 +429,7 @@
 
         BrightnessChangeEvent event = builder.build();
         if (DEBUG) {
-            Slog.d(TAG, "Event " + event.brightness + " " + event.packageName);
+            Slog.d(TAG, "Event: " + event.toString());
         }
         synchronized (mEventsLock) {
             mEventsDirty = true;
@@ -796,6 +796,7 @@
                 pw.print(", isUserSetBrightness=" + events[i].isUserSetBrightness);
                 pw.print(", powerBrightnessFactor=" + events[i].powerBrightnessFactor);
                 pw.print(", isDefaultBrightnessConfig=" + events[i].isDefaultBrightnessConfig);
+                pw.print(", recent lux values=");
                 pw.print(" {");
                 for (int j = 0; j < events[i].luxValues.length; ++j){
                     if (j != 0) {
diff --git a/services/core/java/com/android/server/display/DisplayControl.java b/services/core/java/com/android/server/display/DisplayControl.java
index b30c05c..22f3bbd 100644
--- a/services/core/java/com/android/server/display/DisplayControl.java
+++ b/services/core/java/com/android/server/display/DisplayControl.java
@@ -37,6 +37,7 @@
     private static native int nativeSetHdrConversionMode(int conversionMode,
             int preferredHdrOutputType, int[] autoHdrTypes, int autoHdrTypesLength);
     private static native int[] nativeGetSupportedHdrOutputTypes();
+    private static native int[] nativeGetHdrOutputTypesWithLatency();
     private static native boolean nativeGetHdrOutputConversionSupport();
 
     /**
@@ -128,6 +129,14 @@
     }
 
     /**
+     * Returns the HDR output types which introduces latency on conversion to them.
+     * @hide
+     */
+    public static @Display.HdrCapabilities.HdrType int[] getHdrOutputTypesWithLatency() {
+        return nativeGetHdrOutputTypesWithLatency();
+    }
+
+    /**
      * Returns whether the HDR output conversion is supported by the device.
      * @hide
      */
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 5771a04..3844529 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -141,6 +141,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.display.BrightnessSynchronizer;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.IndentingPrintWriter;
@@ -737,6 +738,20 @@
         return mDisplayDeviceRepo;
     }
 
+    @VisibleForTesting
+    boolean isMinimalPostProcessingAllowed() {
+        synchronized (mSyncRoot) {
+            return mMinimalPostProcessingAllowed;
+        }
+    }
+
+    @VisibleForTesting
+    void setMinimalPostProcessingAllowed(boolean allowed) {
+        synchronized (mSyncRoot) {
+            mMinimalPostProcessingAllowed = allowed;
+        }
+    }
+
     private void loadStableDisplayValuesLocked() {
         final Point size = mPersistentDataStore.getStableDisplaySize();
         if (size.x > 0 && size.y > 0) {
@@ -937,8 +952,9 @@
     }
 
     private void updateSettingsLocked() {
-        mMinimalPostProcessingAllowed = Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED, 1, UserHandle.USER_CURRENT) != 0;
+        setMinimalPostProcessingAllowed(Settings.Secure.getIntForUser(
+                mContext.getContentResolver(), Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED,
+                1, UserHandle.USER_CURRENT) != 0);
     }
 
     private void updateUserDisabledHdrTypesFromSettingsLocked() {
@@ -1560,7 +1576,7 @@
                 // VirtualDisplay has been successfully constructed.
                 session.setVirtualDisplayId(displayId);
                 // Don't start mirroring until user re-grants consent.
-                session.setWaitingToRecord(waitForPermissionConsent);
+                session.setWaitingForConsent(waitForPermissionConsent);
 
                 // We set the content recording session here on the server side instead of using
                 // a second AIDL call in MediaProjection. By ensuring that a virtual display has
@@ -2166,6 +2182,17 @@
         return autoHdrOutputTypesArray.toArray();
     }
 
+    @GuardedBy("mSyncRoot")
+    private boolean hdrConversionIntroducesLatencyLocked() {
+        final int preferredHdrOutputType =
+                getHdrConversionModeSettingInternal().getPreferredHdrOutputType();
+        if (preferredHdrOutputType != Display.HdrCapabilities.HDR_TYPE_INVALID) {
+            int[] hdrTypesWithLatency = mInjector.getHdrOutputTypesWithLatency();
+            return ArrayUtils.contains(hdrTypesWithLatency, preferredHdrOutputType);
+        }
+        return false;
+    }
+
     Display.Mode getUserPreferredDisplayModeInternal(int displayId) {
         synchronized (mSyncRoot) {
             if (displayId == Display.INVALID_DISPLAY) {
@@ -2243,7 +2270,7 @@
         return new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM);
     }
 
-    private HdrConversionMode getHdrConversionModeInternal() {
+    HdrConversionMode getHdrConversionModeInternal() {
         if (!mInjector.getHdrOutputConversionSupport()) {
             return HDR_CONVERSION_MODE_UNSUPPORTED;
         }
@@ -2400,7 +2427,7 @@
         }
     }
 
-    private void setDisplayPropertiesInternal(int displayId, boolean hasContent,
+    void setDisplayPropertiesInternal(int displayId, boolean hasContent,
             float requestedRefreshRate, int requestedModeId, float requestedMinRefreshRate,
             float requestedMaxRefreshRate, boolean preferMinimalPostProcessing,
             boolean disableHdrConversion, boolean inTraversal) {
@@ -2438,11 +2465,17 @@
 
             // TODO(b/202378408) set minimal post-processing only if it's supported once we have a
             // separate API for disabling on-device processing.
-            boolean mppRequest = mMinimalPostProcessingAllowed && preferMinimalPostProcessing;
+            boolean mppRequest = isMinimalPostProcessingAllowed() && preferMinimalPostProcessing;
+            boolean disableHdrConversionForLatency = false;
 
             if (display.getRequestedMinimalPostProcessingLocked() != mppRequest) {
                 display.setRequestedMinimalPostProcessingLocked(mppRequest);
                 shouldScheduleTraversal = true;
+                // If HDR conversion introduces latency, disable that in case minimal
+                // post-processing is requested
+                if (mppRequest) {
+                    disableHdrConversionForLatency = hdrConversionIntroducesLatencyLocked();
+                }
             }
 
             if (shouldScheduleTraversal) {
@@ -2452,12 +2485,17 @@
             if (mHdrConversionMode == null) {
                 return;
             }
-            if (mOverrideHdrConversionMode == null && disableHdrConversion) {
+            // HDR conversion is disabled in two cases:
+            // - HDR conversion introduces latency and minimal post-processing is requested
+            // - app requests to disable HDR conversion
+            if (mOverrideHdrConversionMode == null && (disableHdrConversion
+                    || disableHdrConversionForLatency)) {
                 mOverrideHdrConversionMode =
                             new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_PASSTHROUGH);
                 setHdrConversionModeInternal(mHdrConversionMode);
                 handleLogicalDisplayChangedLocked(display);
-            } else if (mOverrideHdrConversionMode != null && !disableHdrConversion) {
+            } else if (mOverrideHdrConversionMode != null && !disableHdrConversion
+                    && !disableHdrConversionForLatency) {
                 mOverrideHdrConversionMode = null;
                 setHdrConversionModeInternal(mHdrConversionMode);
                 handleLogicalDisplayChangedLocked(display);
@@ -3044,6 +3082,10 @@
             return DisplayControl.getSupportedHdrOutputTypes();
         }
 
+        int[] getHdrOutputTypesWithLatency() {
+            return DisplayControl.getHdrOutputTypesWithLatency();
+        }
+
         boolean getHdrOutputConversionSupport() {
             return DisplayControl.getHdrOutputConversionSupport();
         }
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 0861cb5..9d31572 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1908,21 +1908,8 @@
                 }
             }
 
-            // Report brightness to brightnesstracker:
-            // If brightness is not temporary (ie the slider has been released)
-            // AND if we are not in idle screen brightness mode.
-            if (!brightnessIsTemporary
-                    && (mAutomaticBrightnessController != null
-                    && !mAutomaticBrightnessController.isInIdleMode())) {
-                if (userInitiatedChange && (mAutomaticBrightnessController == null
-                        || !mAutomaticBrightnessController.hasValidAmbientLux())) {
-                    // If we don't have a valid lux reading we can't report a valid
-                    // slider event so notify as if the system changed the brightness.
-                    userInitiatedChange = false;
-                }
-                notifyBrightnessTrackerChanged(brightnessState, userInitiatedChange,
-                        wasShortTermModelActive);
-            }
+            notifyBrightnessTrackerChanged(brightnessState, userInitiatedChange,
+                    wasShortTermModelActive, autoBrightnessEnabled, brightnessIsTemporary);
 
             // We save the brightness info *after* the brightness setting has been changed and
             // adjustments made so that the brightness info reflects the latest value.
@@ -2758,22 +2745,43 @@
     }
 
     private void notifyBrightnessTrackerChanged(float brightness, boolean userInitiated,
-            boolean wasShortTermModelActive) {
+            boolean wasShortTermModelActive, boolean autobrightnessEnabled,
+            boolean brightnessIsTemporary) {
         final float brightnessInNits = convertToAdjustedNits(brightness);
-        if (mUseAutoBrightness && brightnessInNits >= 0.0f
-                && mAutomaticBrightnessController != null && mBrightnessTracker != null) {
-            // We only want to track changes on devices that can actually map the display backlight
-            // values into a physical brightness unit since the value provided by the API is in
-            // nits and not using the arbitrary backlight units.
-            final float powerFactor = mPowerRequest.lowPowerMode
-                    ? mPowerRequest.screenLowPowerBrightnessFactor
-                    : 1.0f;
-            mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiated,
-                    powerFactor, wasShortTermModelActive,
-                    mAutomaticBrightnessController.isDefaultConfig(), mUniqueDisplayId,
-                    mAutomaticBrightnessController.getLastSensorValues(),
-                    mAutomaticBrightnessController.getLastSensorTimestamps());
+
+        // Don't report brightness to brightnessTracker:
+        // If brightness is temporary (ie the slider has not been released)
+        // or if we are in idle screen brightness mode.
+        // or display is not on
+        // or we shouldn't be using autobrightness
+        // or the nits is invalid.
+        if (brightnessIsTemporary
+                || mAutomaticBrightnessController == null
+                || mAutomaticBrightnessController.isInIdleMode()
+                || !autobrightnessEnabled
+                || mBrightnessTracker == null
+                || !mUseAutoBrightness
+                || brightnessInNits < 0.0f) {
+            return;
         }
+
+        if (userInitiated && !mAutomaticBrightnessController.hasValidAmbientLux()) {
+            // If we don't have a valid lux reading we can't report a valid
+            // slider event so notify as if the system changed the brightness.
+            userInitiated = false;
+        }
+
+        // We only want to track changes on devices that can actually map the display backlight
+        // values into a physical brightness unit since the value provided by the API is in
+        // nits and not using the arbitrary backlight units.
+        final float powerFactor = mPowerRequest.lowPowerMode
+                ? mPowerRequest.screenLowPowerBrightnessFactor
+                : 1.0f;
+        mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiated,
+                powerFactor, wasShortTermModelActive,
+                mAutomaticBrightnessController.isDefaultConfig(), mUniqueDisplayId,
+                mAutomaticBrightnessController.getLastSensorValues(),
+                mAutomaticBrightnessController.getLastSensorTimestamps());
     }
 
     private float convertToNits(float brightness) {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index 3b3d5da..41e4671d 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -157,6 +157,7 @@
     private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3;
 
     private static final int RINGBUFFER_MAX = 100;
+    private static final int RINGBUFFER_RBC_MAX = 20;
 
     private static final float[] BRIGHTNESS_RANGE_BOUNDARIES = {
         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80,
@@ -390,6 +391,10 @@
     // Keeps a record of brightness changes for dumpsys.
     private RingBuffer<BrightnessEvent> mBrightnessEventRingBuffer;
 
+    // Keeps a record of rbc changes for dumpsys.
+    private final RingBuffer<BrightnessEvent> mRbcEventRingBuffer =
+            new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_RBC_MAX);
+
     // Controls and tracks all the wakelocks that are acquired/released by the system. Also acts as
     // a medium of communication between this class and the PowerManagerService.
     private final WakelockController mWakelockController;
@@ -1454,7 +1459,7 @@
         // Skip the animation when the screen is off or suspended.
         boolean brightnessAdjusted = false;
         final boolean brightnessIsTemporary =
-                (mBrightnessReason.getReason() == BrightnessReason.REASON_TEMPORARY)
+                (mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_TEMPORARY)
                         || mAutomaticBrightnessStrategy
                         .isTemporaryAutoBrightnessAdjustmentApplied();
         if (!mPendingScreenOff) {
@@ -1539,21 +1544,9 @@
                 }
             }
 
-            // Report brightness to brightnesstracker:
-            // If brightness is not temporary (ie the slider has been released)
-            // AND if we are not in idle screen brightness mode.
-            if (!brightnessIsTemporary
-                    && (mAutomaticBrightnessController != null
-                    && !mAutomaticBrightnessController.isInIdleMode())) {
-                if (userInitiatedChange && (mAutomaticBrightnessController == null
-                        || !mAutomaticBrightnessController.hasValidAmbientLux())) {
-                    // If we don't have a valid lux reading we can't report a valid
-                    // slider event so notify as if the system changed the brightness.
-                    userInitiatedChange = false;
-                }
-                notifyBrightnessTrackerChanged(brightnessState, userInitiatedChange,
-                        wasShortTermModelActive);
-            }
+            notifyBrightnessTrackerChanged(brightnessState, userInitiatedChange,
+                    wasShortTermModelActive, mAutomaticBrightnessStrategy.isAutoBrightnessEnabled(),
+                    brightnessIsTemporary);
 
             // We save the brightness info *after* the brightness setting has been changed and
             // adjustments made so that the brightness info reflects the latest value.
@@ -1605,6 +1598,10 @@
                 mTempBrightnessEvent.getReason().getReason() == BrightnessReason.REASON_TEMPORARY
                         && mLastBrightnessEvent.getReason().getReason()
                         == BrightnessReason.REASON_TEMPORARY;
+        // Purely for dumpsys;
+        final boolean isRbcEvent =
+                mLastBrightnessEvent.isRbcEnabled() != mTempBrightnessEvent.isRbcEnabled();
+
         if ((!mTempBrightnessEvent.equalsMainData(mLastBrightnessEvent) && !tempToTempTransition)
                 || brightnessAdjustmentFlags != 0) {
             mTempBrightnessEvent.setInitialBrightness(mLastBrightnessEvent.getBrightness());
@@ -1624,6 +1621,10 @@
             if (mBrightnessEventRingBuffer != null) {
                 mBrightnessEventRingBuffer.append(newEvent);
             }
+            if (isRbcEvent) {
+                mRbcEventRingBuffer.append(newEvent);
+            }
+
         }
 
         // Update display white-balance.
@@ -2171,11 +2172,6 @@
         }, mClock.uptimeMillis());
     }
 
-    private float getAutoBrightnessAdjustmentSetting() {
-        final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(),
-                Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);
-        return Float.isNaN(adj) ? 0.0f : clampAutoBrightnessAdjustment(adj);
-    }
 
     @Override
     public float getScreenBrightnessSetting() {
@@ -2215,23 +2211,45 @@
     }
 
     private void notifyBrightnessTrackerChanged(float brightness, boolean userInitiated,
-            boolean wasShortTermModelActive) {
+            boolean wasShortTermModelActive, boolean autobrightnessEnabled,
+            boolean brightnessIsTemporary) {
+
         final float brightnessInNits =
                 mDisplayBrightnessController.convertToAdjustedNits(brightness);
-        if (mAutomaticBrightnessStrategy.shouldUseAutoBrightness() && brightnessInNits >= 0.0f
-                && mAutomaticBrightnessController != null && mBrightnessTracker != null) {
-            // We only want to track changes on devices that can actually map the display backlight
-            // values into a physical brightness unit since the value provided by the API is in
-            // nits and not using the arbitrary backlight units.
-            final float powerFactor = mPowerRequest.lowPowerMode
-                    ? mPowerRequest.screenLowPowerBrightnessFactor
-                    : 1.0f;
-            mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiated,
-                    powerFactor, wasShortTermModelActive,
-                    mAutomaticBrightnessController.isDefaultConfig(), mUniqueDisplayId,
-                    mAutomaticBrightnessController.getLastSensorValues(),
-                    mAutomaticBrightnessController.getLastSensorTimestamps());
+        // Don't report brightness to brightnessTracker:
+        // If brightness is temporary (ie the slider has not been released)
+        // or if we are in idle screen brightness mode.
+        // or display is not on
+        // or we shouldn't be using autobrightness
+        // or the nits is invalid.
+        if (brightnessIsTemporary
+                || mAutomaticBrightnessController == null
+                || mAutomaticBrightnessController.isInIdleMode()
+                || !autobrightnessEnabled
+                || mBrightnessTracker == null
+                || !mAutomaticBrightnessStrategy.shouldUseAutoBrightness()
+                || brightnessInNits < 0.0f) {
+            return;
         }
+
+        if (userInitiated && (mAutomaticBrightnessController == null
+                || !mAutomaticBrightnessController.hasValidAmbientLux())) {
+            // If we don't have a valid lux reading we can't report a valid
+            // slider event so notify as if the system changed the brightness.
+            userInitiated = false;
+        }
+
+        // We only want to track changes on devices that can actually map the display backlight
+        // values into a physical brightness unit since the value provided by the API is in
+        // nits and not using the arbitrary backlight units.
+        final float powerFactor = mPowerRequest.lowPowerMode
+                ? mPowerRequest.screenLowPowerBrightnessFactor
+                : 1.0f;
+        mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiated,
+                powerFactor, wasShortTermModelActive,
+                mAutomaticBrightnessController.isDefaultConfig(), mUniqueDisplayId,
+                mAutomaticBrightnessController.getLastSensorValues(),
+                mAutomaticBrightnessController.getLastSensorTimestamps());
     }
 
     @Override
@@ -2354,6 +2372,8 @@
             dumpBrightnessEvents(pw);
         }
 
+        dumpRbcEvents(pw);
+
         if (mHbmController != null) {
             mHbmController.dump(pw);
         }
@@ -2426,10 +2446,21 @@
         }
     }
 
-    private static float clampAutoBrightnessAdjustment(float value) {
-        return MathUtils.constrain(value, -1.0f, 1.0f);
+    private void dumpRbcEvents(PrintWriter pw) {
+        int size = mRbcEventRingBuffer.size();
+        if (size < 1) {
+            pw.println("No Reduce Bright Colors Adjustments");
+            return;
+        }
+
+        pw.println("Reduce Bright Colors Adjustments Last " + size + " Events: ");
+        BrightnessEvent[] eventArray = mRbcEventRingBuffer.toArray();
+        for (int i = 0; i < mRbcEventRingBuffer.size(); i++) {
+            pw.println("  " + eventArray[i]);
+        }
     }
 
+
     private void noteScreenState(int screenState) {
         // Log screen state change with display id
         FrameworkStatsLog.write(FrameworkStatsLog.SCREEN_STATE_CHANGED_V2,
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index e5c50e6..4edc8bc 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -23,7 +23,6 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.hardware.display.DisplayManagerInternal;
-import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.SparseArray;
 import android.view.Display;
@@ -333,6 +332,10 @@
         return mPrimaryDisplayDevice != null;
     }
 
+    boolean isDirtyLocked() {
+        return mDirty;
+    }
+
     /**
      * Updates the {@link DisplayGroup} to which the logical display belongs.
      *
@@ -341,8 +344,7 @@
     public void updateDisplayGroupIdLocked(int groupId) {
         if (groupId != mDisplayGroupId) {
             mDisplayGroupId = groupId;
-            mBaseDisplayInfo.displayGroupId = groupId;
-            mInfo.set(null);
+            mDirty = true;
         }
     }
 
@@ -932,18 +934,6 @@
         return mDisplayGroupName;
     }
 
-    /**
-     * Returns whether a display group other than the default display group needs to be assigned.
-     *
-     * <p>If display group name is empty or {@code Display.FLAG_OWN_DISPLAY_GROUP} is set, the
-     * display is assigned to the default display group.
-     */
-    public boolean needsOwnDisplayGroupLocked() {
-        DisplayInfo info = getDisplayInfoLocked();
-        return (info.flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0
-                || !TextUtils.isEmpty(mDisplayGroupName);
-    }
-
     public void dumpLocked(PrintWriter pw) {
         pw.println("mDisplayId=" + mDisplayId);
         pw.println("mIsEnabled=" + mIsEnabled);
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index 254441c2..d01b03f 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -679,7 +679,9 @@
         for (int i = mLogicalDisplays.size() - 1; i >= 0; i--) {
             final int displayId = mLogicalDisplays.keyAt(i);
             LogicalDisplay display = mLogicalDisplays.valueAt(i);
+            assignDisplayGroupLocked(display);
 
+            boolean wasDirty = display.isDirtyLocked();
             mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
             display.getNonOverrideDisplayInfoLocked(mTempNonOverrideDisplayInfo);
 
@@ -713,19 +715,14 @@
             // The display is new.
             } else if (!wasPreviouslyUpdated) {
                 Slog.i(TAG, "Adding new display: " + displayId + ": " + newDisplayInfo);
-                assignDisplayGroupLocked(display);
                 mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_ADDED);
 
             // Underlying displays device has changed to a different one.
             } else if (!TextUtils.equals(mTempDisplayInfo.uniqueId, newDisplayInfo.uniqueId)) {
-                // FLAG_OWN_DISPLAY_GROUP could have changed, recalculate just in case
-                assignDisplayGroupLocked(display);
                 mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_SWAPPED);
 
             // Something about the display device has changed.
-            } else if (!mTempDisplayInfo.equals(newDisplayInfo)) {
-                // FLAG_OWN_DISPLAY_GROUP could have changed, recalculate just in case
-                assignDisplayGroupLocked(display);
+            } else if (wasDirty || !mTempDisplayInfo.equals(newDisplayInfo)) {
                 // If only the hdr/sdr ratio changed, then send just the event for that case
                 if ((diff == DisplayDeviceInfo.DIFF_HDR_SDR_RATIO)) {
                     mLogicalDisplaysToUpdate.put(displayId,
@@ -851,9 +848,18 @@
         }
     }
 
+    /** This method should be called before LogicalDisplay.updateLocked,
+     * DisplayInfo in LogicalDisplay (display.getDisplayInfoLocked()) is not updated yet,
+     * and should not be used directly or indirectly in this method */
     private void assignDisplayGroupLocked(LogicalDisplay display) {
+        if (!display.isValidLocked()) { // null check for display.mPrimaryDisplayDevice
+            return;
+        }
+        // updated primary device directly from LogicalDisplay (not from DisplayInfo)
+        final DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
+        // final in LogicalDisplay
         final int displayId = display.getDisplayIdLocked();
-        final String primaryDisplayUniqueId = display.getPrimaryDisplayDeviceLocked().getUniqueId();
+        final String primaryDisplayUniqueId = displayDevice.getUniqueId();
         final Integer linkedDeviceUniqueId =
                 mVirtualDeviceDisplayMapping.get(primaryDisplayUniqueId);
 
@@ -866,8 +872,17 @@
         }
         final DisplayGroup oldGroup = getDisplayGroupLocked(groupId);
 
-        // Get the new display group if a change is needed
-        final boolean needsOwnDisplayGroup = display.needsOwnDisplayGroupLocked();
+        // groupName directly from LogicalDisplay (not from DisplayInfo)
+        final String groupName = display.getDisplayGroupNameLocked();
+        // DisplayDeviceInfo is safe to use, it is updated earlier
+        final DisplayDeviceInfo displayDeviceInfo = displayDevice.getDisplayDeviceInfoLocked();
+        // Get the new display group if a change is needed, if display group name is empty and
+        // {@code DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP} is not set, the display is assigned
+        // to the default display group.
+        final boolean needsOwnDisplayGroup =
+                (displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0
+                        || !TextUtils.isEmpty(groupName);
+
         final boolean hasOwnDisplayGroup = groupId != Display.DEFAULT_DISPLAY_GROUP;
         final boolean needsDeviceDisplayGroup =
                 !needsOwnDisplayGroup && linkedDeviceUniqueId != null;
diff --git a/services/core/java/com/android/server/display/brightness/BrightnessUtils.java b/services/core/java/com/android/server/display/brightness/BrightnessUtils.java
index 169cc4a..3fae224 100644
--- a/services/core/java/com/android/server/display/brightness/BrightnessUtils.java
+++ b/services/core/java/com/android/server/display/brightness/BrightnessUtils.java
@@ -42,6 +42,13 @@
     }
 
     /**
+     * Clamps the brightness value in the maximum and the minimum brightness adjustment range
+     */
+    public static float clampBrightnessAdjustment(float value) {
+        return MathUtils.constrain(value, -1.0f, 1.0f);
+    }
+
+    /**
      * A utility to construct the DisplayBrightnessState
      */
     public static DisplayBrightnessState constructDisplayBrightnessState(
diff --git a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
index 95cbf98..0e885dc 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
@@ -202,7 +202,7 @@
         final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(),
                 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);
         mPendingAutoBrightnessAdjustment = Float.isNaN(adj) ? Float.NaN
-                : BrightnessUtils.clampAbsoluteBrightness(adj);
+                : BrightnessUtils.clampBrightnessAdjustment(adj);
         if (userSwitch) {
             processPendingAutoBrightnessAdjustments();
         }
@@ -402,6 +402,6 @@
     private float getAutoBrightnessAdjustmentSetting() {
         final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(),
                 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);
-        return Float.isNaN(adj) ? 0.0f : BrightnessUtils.clampAbsoluteBrightness(adj);
+        return Float.isNaN(adj) ? 0.0f : BrightnessUtils.clampBrightnessAdjustment(adj);
     }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index f37ad5e..ca1abd6 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -1013,11 +1013,10 @@
     }
 
     @ServiceThreadOnly
-    void addAvbAudioStatusAction(int targetAddress) {
+    void startNewAvbAudioStatusAction(int targetAddress) {
         assertRunOnServiceThread();
-        if (!hasAction(AbsoluteVolumeAudioStatusAction.class)) {
-            addAndStartAction(new AbsoluteVolumeAudioStatusAction(this, targetAddress));
-        }
+        removeAction(AbsoluteVolumeAudioStatusAction.class);
+        addAndStartAction(new AbsoluteVolumeAudioStatusAction(this, targetAddress));
     }
 
     @ServiceThreadOnly
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index e87ed0a..2c54e1c 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -63,10 +63,12 @@
 import android.hardware.hdmi.IHdmiVendorCommandListener;
 import android.hardware.tv.cec.V1_0.SendMessageResult;
 import android.media.AudioAttributes;
+import android.media.AudioDescriptor;
 import android.media.AudioDeviceAttributes;
 import android.media.AudioDeviceInfo;
 import android.media.AudioDeviceVolumeManager;
 import android.media.AudioManager;
+import android.media.AudioProfile;
 import android.media.VolumeInfo;
 import android.media.session.MediaController;
 import android.media.session.MediaSessionManager;
@@ -4341,12 +4343,9 @@
         switch (systemAudioDeviceInfo.getDeviceFeatures().getSetAudioVolumeLevelSupport()) {
             case DeviceFeatures.FEATURE_SUPPORTED:
                 if (currentVolumeBehavior != AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
-                    // If we're currently using adjust-only absolute volume behavior, switch to
-                    // full volume behavior until we successfully adopt absolute volume behavior
-                    switchToFullVolumeBehavior();
                     // Start an action that will call enableAbsoluteVolumeBehavior
                     // once the System Audio device sends <Report Audio Status>
-                    localCecDevice.addAvbAudioStatusAction(
+                    localCecDevice.startNewAvbAudioStatusAction(
                             systemAudioDeviceInfo.getLogicalAddress());
                 }
                 return;
@@ -4358,10 +4357,13 @@
                             != AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY) {
                         // If we're currently using absolute volume behavior, switch to full volume
                         // behavior until we successfully adopt adjust-only absolute volume behavior
-                        switchToFullVolumeBehavior();
+                        if (currentVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
+                            getAudioManager().setDeviceVolumeBehavior(getAvbAudioOutputDevice(),
+                                    AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+                        }
                         // Start an action that will call enableAbsoluteVolumeBehavior
                         // once the System Audio device sends <Report Audio Status>
-                        localCecDevice.addAvbAudioStatusAction(
+                        localCecDevice.startNewAvbAudioStatusAction(
                                 systemAudioDeviceInfo.getLogicalAddress());
                     }
                 } else {
@@ -4369,7 +4371,9 @@
                 }
                 return;
             case DeviceFeatures.FEATURE_SUPPORT_UNKNOWN:
-                switchToFullVolumeBehavior();
+                if (currentVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
+                    switchToFullVolumeBehavior();
+                }
                 localCecDevice.querySetAudioVolumeLevelSupport(
                         systemAudioDeviceInfo.getLogicalAddress());
         }
@@ -4721,13 +4725,24 @@
             Slog.w(TAG, "Tried to update eARC status on a port that doesn't support eARC.");
             return;
         }
-        // If eARC is disabled, the local device is null. In this case, the HAL shouldn't have
-        // reported connection state changes, but even if it did, it won't take effect.
         if (mEarcLocalDevice != null) {
             mEarcLocalDevice.handleEarcStateChange(status);
+        } else if (status == HDMI_EARC_STATUS_ARC_PENDING) {
+            // If eARC is disabled, the local device is null. This is why we notify
+            // AudioService here that the eARC connection is terminated.
+            notifyEarcStatusToAudioService(false, new ArrayList<>());
+            startArcAction(true, null);
         }
     }
 
+    protected void notifyEarcStatusToAudioService(
+            boolean enabled, List<AudioDescriptor> audioDescriptors) {
+        AudioDeviceAttributes attributes = new AudioDeviceAttributes(
+                AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_HDMI_EARC, "", "",
+                new ArrayList<AudioProfile>(), audioDescriptors);
+        getAudioManager().setWiredDeviceConnectionState(attributes, enabled ? 1 : 0);
+    }
+
     @ServiceThreadOnly
     void handleEarcCapabilitiesReported(byte[] rawCapabilities, int portId) {
         assertRunOnServiceThread();
diff --git a/services/core/java/com/android/server/hdmi/HdmiEarcLocalDeviceTx.java b/services/core/java/com/android/server/hdmi/HdmiEarcLocalDeviceTx.java
index 9058c98..873d5fc 100644
--- a/services/core/java/com/android/server/hdmi/HdmiEarcLocalDeviceTx.java
+++ b/services/core/java/com/android/server/hdmi/HdmiEarcLocalDeviceTx.java
@@ -23,8 +23,6 @@
 
 import android.hardware.hdmi.HdmiDeviceInfo;
 import android.media.AudioDescriptor;
-import android.media.AudioDeviceAttributes;
-import android.media.AudioDeviceInfo;
 import android.media.AudioProfile;
 import android.os.Handler;
 import android.util.IndentingPrintWriter;
@@ -88,10 +86,10 @@
 
         mReportCapsHandler.removeCallbacksAndMessages(null);
         if (status == HDMI_EARC_STATUS_IDLE) {
-            notifyEarcStatusToAudioService(false, new ArrayList<>());
+            mService.notifyEarcStatusToAudioService(false, new ArrayList<>());
             mService.startArcAction(false, null);
         } else if (status == HDMI_EARC_STATUS_ARC_PENDING) {
-            notifyEarcStatusToAudioService(false, new ArrayList<>());
+            mService.notifyEarcStatusToAudioService(false, new ArrayList<>());
             mService.startArcAction(true, null);
         } else if (status == HDMI_EARC_STATUS_EARC_PENDING
                 && oldEarcStatus == HDMI_EARC_STATUS_ARC_PENDING) {
@@ -110,19 +108,11 @@
                     && mReportCapsHandler.hasCallbacks(mReportCapsRunnable)) {
                 mReportCapsHandler.removeCallbacksAndMessages(null);
                 List<AudioDescriptor> audioDescriptors = parseCapabilities(rawCapabilities);
-                notifyEarcStatusToAudioService(true, audioDescriptors);
+                mService.notifyEarcStatusToAudioService(true, audioDescriptors);
             }
         }
     }
 
-    private void notifyEarcStatusToAudioService(
-            boolean enabled, List<AudioDescriptor> audioDescriptors) {
-        AudioDeviceAttributes attributes = new AudioDeviceAttributes(
-                AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_HDMI_EARC, "", "",
-                new ArrayList<AudioProfile>(), audioDescriptors);
-        mService.getAudioManager().setWiredDeviceConnectionState(attributes, enabled ? 1 : 0);
-    }
-
     /**
      * Runnable for waiting for a certain amount of time for the audio system to report its
      * capabilities after eARC was connected. If the audio system doesn´t report its capabilities in
@@ -134,7 +124,7 @@
         public void run() {
             synchronized (mLock) {
                 if (mEarcStatus == HDMI_EARC_STATUS_EARC_CONNECTED) {
-                    notifyEarcStatusToAudioService(true, new ArrayList<>());
+                    mService.notifyEarcStatusToAudioService(true, new ArrayList<>());
                 }
             }
         }
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 20f0697..2e62ef4 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -889,22 +889,31 @@
 
     }
 
-    private void migrateOldDataAfterSystemReady() {
-        // Migrate the FRP credential to the persistent data block
+    @VisibleForTesting
+    void migrateOldDataAfterSystemReady() {
+        // Write the FRP persistent data block if needed.
+        //
+        // The original purpose of this code was to write the FRP block for the first time, when
+        // upgrading from Android 8.1 or earlier which didn't use the FRP block.  This code has
+        // since been repurposed to also fix the "bad" (non-forwards-compatible) FRP block written
+        // by Android 14 Beta 2.  For this reason, the database key used here has been renamed from
+        // "migrated_frp" to "migrated_frp2" to cause migrateFrpCredential() to run again on devices
+        // where it had run before.
         if (LockPatternUtils.frpCredentialEnabled(mContext)
-                && !getBoolean("migrated_frp", false, 0)) {
+                && !getBoolean("migrated_frp2", false, 0)) {
             migrateFrpCredential();
-            setBoolean("migrated_frp", true, 0);
+            setBoolean("migrated_frp2", true, 0);
         }
     }
 
     /**
-     * Migrate the credential for the FRP credential owner user if the following are satisfied:
-     * - the user has a secure credential
-     * - the FRP credential is not set up
+     * Write the FRP persistent data block if the following are satisfied:
+     * - the user who owns the FRP credential has a nonempty credential
+     * - the FRP persistent data block doesn't exist or uses the "bad" format from Android 14 Beta 2
      */
     private void migrateFrpCredential() {
-        if (mStorage.readPersistentDataBlock() != PersistentData.NONE) {
+        PersistentData data = mStorage.readPersistentDataBlock();
+        if (data != PersistentData.NONE && !data.isBadFormatFromAndroid14Beta()) {
             return;
         }
         for (UserInfo userInfo : mUserManager.getUsers()) {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
index 731ecad..2fa637e 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
@@ -606,6 +606,11 @@
             this.payload = payload;
         }
 
+        public boolean isBadFormatFromAndroid14Beta() {
+            return (this.type == TYPE_SP_GATEKEEPER || this.type == TYPE_SP_WEAVER)
+                && SyntheticPasswordManager.PasswordData.isBadFormatFromAndroid14Beta(this.payload);
+        }
+
         public static PersistentData fromBytes(byte[] frpData) {
             if (frpData == null || frpData.length == 0) {
                 return NONE;
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index 8b8c5f6..66f862a 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -152,9 +152,6 @@
     // The security strength of the synthetic password, in bytes
     private static final int SYNTHETIC_PASSWORD_SECURITY_STRENGTH = 256 / 8;
 
-    public static final short PASSWORD_DATA_V1 = 1;
-    public static final short PASSWORD_DATA_V2 = 2;
-
     private static final int PASSWORD_SCRYPT_LOG_N = 11;
     private static final int PASSWORD_SCRYPT_LOG_R = 3;
     private static final int PASSWORD_SCRYPT_LOG_P = 1;
@@ -373,27 +370,33 @@
             return result;
         }
 
+        /**
+         * Returns true if the given serialized PasswordData begins with the value 2 as a short.
+         * This detects the "bad" (non-forwards-compatible) PasswordData format that was temporarily
+         * used during development of Android 14.  For more details, see fromBytes() below.
+         */
+        public static boolean isBadFormatFromAndroid14Beta(byte[] data) {
+            return data != null && data.length >= 2 && data[0] == 0 && data[1] == 2;
+        }
+
         public static PasswordData fromBytes(byte[] data) {
             PasswordData result = new PasswordData();
             ByteBuffer buffer = ByteBuffer.allocate(data.length);
             buffer.put(data, 0, data.length);
             buffer.flip();
 
-          /*
-           * Originally this file did not contain a version number. However, its first field was
-           * 'credentialType' as an 'int'. Since 'credentialType' could only be in the range
-           * [-1, 4] and this file uses big endian byte order, the first two bytes were redundant,
-           * and when interpreted as a 'short' could only contain -1 or 0. Therefore, we've now
-           * reclaimed these two bytes for a 'short' version number and shrunk 'credentialType'
-           * to a 'short'.
-           */
-            short version = buffer.getShort();
-            if (version == ((short) 0) || version == (short) -1) {
-                version = PASSWORD_DATA_V1;
-            } else if (version != PASSWORD_DATA_V2) {
-                throw new IllegalArgumentException("Unknown PasswordData version: " + version);
-            }
-            result.credentialType = buffer.getShort();
+            /*
+             * The serialized PasswordData is supposed to begin with credentialType as an int.
+             * However, all credentialType values fit in a short and the byte order is big endian,
+             * so the first two bytes don't convey any non-redundant information.  For this reason,
+             * temporarily during development of Android 14, the first two bytes were "stolen" from
+             * credentialType to use for a data format version number.
+             *
+             * However, this change was reverted as it was a non-forwards-compatible change.  (See
+             * toBytes() for why this data format needs to be forwards-compatible.)  Therefore,
+             * recover from this misstep by ignoring the first two bytes.
+             */
+            result.credentialType = (short) buffer.getInt();
             result.scryptLogN = buffer.get();
             result.scryptLogR = buffer.get();
             result.scryptLogP = buffer.get();
@@ -407,7 +410,7 @@
             } else {
                 result.passwordHandle = null;
             }
-            if (version == PASSWORD_DATA_V2) {
+            if (buffer.remaining() >= Integer.BYTES) {
                 result.pinLength = buffer.getInt();
             } else {
                 result.pinLength = PIN_LENGTH_UNAVAILABLE;
@@ -415,16 +418,25 @@
             return result;
         }
 
+        /**
+         * Serializes this PasswordData into a byte array.
+         * <p>
+         * Careful: all changes to the format of the serialized PasswordData must be forwards
+         * compatible.  I.e., older versions of Android must still accept the latest PasswordData.
+         * This is because a serialized PasswordData is stored in the Factory Reset Protection (FRP)
+         * persistent data block.  It's possible that a device has FRP set up on a newer version of
+         * Android, is factory reset, and then is set up with an older version of Android.
+         */
         public byte[] toBytes() {
 
-            ByteBuffer buffer = ByteBuffer.allocate(2 * Short.BYTES + 3 * Byte.BYTES
+            ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + 3 * Byte.BYTES
                     + Integer.BYTES + salt.length + Integer.BYTES +
                     (passwordHandle != null ? passwordHandle.length : 0) + Integer.BYTES);
+            // credentialType must fit in a short.  For an explanation, see fromBytes().
             if (credentialType < Short.MIN_VALUE || credentialType > Short.MAX_VALUE) {
                 throw new IllegalArgumentException("Unknown credential type: " + credentialType);
             }
-            buffer.putShort(PASSWORD_DATA_V2);
-            buffer.putShort((short) credentialType);
+            buffer.putInt(credentialType);
             buffer.put(scryptLogN);
             buffer.put(scryptLogR);
             buffer.put(scryptLogP);
diff --git a/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java b/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java
index 182aa6f..93f6ff3 100644
--- a/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java
+++ b/services/core/java/com/android/server/media/AudioPoliciesDeviceRouteController.java
@@ -42,13 +42,10 @@
 
 import java.util.Objects;
 
-
 /* package */ final class AudioPoliciesDeviceRouteController implements DeviceRouteController {
 
     private static final String TAG = "APDeviceRoutesController";
 
-    private static final String DEVICE_ROUTE_ID = "DEVICE_ROUTE";
-
     @NonNull
     private final Context mContext;
     @NonNull
@@ -182,10 +179,12 @@
 
         synchronized (this) {
             return new MediaRoute2Info.Builder(
-                    DEVICE_ROUTE_ID, mContext.getResources().getText(name).toString())
-                    .setVolumeHandling(mAudioManager.isVolumeFixed()
-                            ? MediaRoute2Info.PLAYBACK_VOLUME_FIXED
-                            : MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
+                            MediaRoute2Info.ROUTE_ID_DEVICE,
+                            mContext.getResources().getText(name).toString())
+                    .setVolumeHandling(
+                            mAudioManager.isVolumeFixed()
+                                    ? MediaRoute2Info.PLAYBACK_VOLUME_FIXED
+                                    : MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
                     .setVolume(mDeviceVolume)
                     .setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
                     .setType(type)
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index cac22a6..b79991e 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -28,6 +28,7 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.content.BroadcastReceiver;
@@ -75,8 +76,10 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
@@ -97,6 +100,17 @@
     private static final String KEY_SCANNING_PACKAGE_MINIMUM_IMPORTANCE =
             "scanning_package_minimum_importance";
 
+    /**
+     * Contains the list of bluetooth permissions that are required to do system routing.
+     *
+     * <p>Alternatively, apps that hold {@link android.Manifest.permission#MODIFY_AUDIO_ROUTING} are
+     * also allowed to do system routing.
+     */
+    private static final String[] BLUETOOTH_PERMISSIONS_FOR_SYSTEM_ROUTING =
+            new String[] {
+                Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_SCAN
+            };
+
     private static int sPackageImportanceForScanning = DeviceConfig.getInt(
             MEDIA_BETTER_TOGETHER_NAMESPACE,
             /* name */ KEY_SCANNING_PACKAGE_MINIMUM_IMPORTANCE,
@@ -142,6 +156,7 @@
         }
     };
 
+    @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
     /* package */ MediaRouter2ServiceImpl(Context context) {
         mContext = context;
         mActivityManager = mContext.getSystemService(ActivityManager.class);
@@ -155,12 +170,28 @@
         screenOnOffIntentFilter.addAction(ACTION_SCREEN_OFF);
 
         mContext.registerReceiver(mScreenOnOffReceiver, screenOnOffIntentFilter);
+        mContext.getPackageManager().addOnPermissionsChangeListener(this::onPermissionsChanged);
 
         DeviceConfig.addOnPropertiesChangedListener(MEDIA_BETTER_TOGETHER_NAMESPACE,
                 ActivityThread.currentApplication().getMainExecutor(),
                 this::onDeviceConfigChange);
     }
 
+    /**
+     * Called when there's a change in the permissions of an app.
+     *
+     * @param uid The uid of the app whose permissions changed.
+     */
+    private void onPermissionsChanged(int uid) {
+        synchronized (mLock) {
+            Optional<RouterRecord> affectedRouter =
+                    mAllRouterRecords.values().stream().filter(it -> it.mUid == uid).findFirst();
+            if (affectedRouter.isPresent()) {
+                affectedRouter.get().maybeUpdateSystemRoutingPermissionLocked();
+            }
+        }
+    }
+
     // Start of methods that implement MediaRouter2 operations.
 
     @NonNull
@@ -1511,6 +1542,7 @@
         public final int mPid;
         public final boolean mHasConfigureWifiDisplayPermission;
         public final boolean mHasModifyAudioRoutingPermission;
+        public final AtomicBoolean mHasBluetoothRoutingPermission;
         public final int mRouterId;
 
         public RouteDiscoveryPreference mDiscoveryPreference;
@@ -1528,15 +1560,47 @@
             mPid = pid;
             mHasConfigureWifiDisplayPermission = hasConfigureWifiDisplayPermission;
             mHasModifyAudioRoutingPermission = hasModifyAudioRoutingPermission;
+            mHasBluetoothRoutingPermission = new AtomicBoolean(fetchBluetoothPermission());
             mRouterId = mNextRouterOrManagerId.getAndIncrement();
         }
 
+        private boolean fetchBluetoothPermission() {
+            boolean hasBluetoothRoutingPermission = true;
+            for (String permission : BLUETOOTH_PERMISSIONS_FOR_SYSTEM_ROUTING) {
+                hasBluetoothRoutingPermission &=
+                        mContext.checkPermission(permission, mPid, mUid)
+                                == PackageManager.PERMISSION_GRANTED;
+            }
+            return hasBluetoothRoutingPermission;
+        }
+
         /**
          * Returns whether the corresponding router has permission to query and control system
          * routes.
          */
         public boolean hasSystemRoutingPermission() {
-            return mHasModifyAudioRoutingPermission;
+            return mHasModifyAudioRoutingPermission || mHasBluetoothRoutingPermission.get();
+        }
+
+        public void maybeUpdateSystemRoutingPermissionLocked() {
+            boolean oldSystemRoutingPermissionValue = hasSystemRoutingPermission();
+            mHasBluetoothRoutingPermission.set(fetchBluetoothPermission());
+            boolean newSystemRoutingPermissionValue = hasSystemRoutingPermission();
+            if (oldSystemRoutingPermissionValue != newSystemRoutingPermissionValue) {
+                Map<String, MediaRoute2Info> routesToReport =
+                        newSystemRoutingPermissionValue
+                                ? mUserRecord.mHandler.mLastNotifiedRoutesToPrivilegedRouters
+                                : mUserRecord.mHandler.mLastNotifiedRoutesToNonPrivilegedRouters;
+                notifyRoutesUpdated(routesToReport.values().stream().toList());
+
+                List<RoutingSessionInfo> sessionInfos =
+                        mUserRecord.mHandler.mSystemProvider.getSessionInfos();
+                RoutingSessionInfo systemSessionToReport =
+                        newSystemRoutingPermissionValue && !sessionInfos.isEmpty()
+                                ? sessionInfos.get(0)
+                                : mUserRecord.mHandler.mSystemProvider.getDefaultSessionInfo();
+                notifySessionInfoChanged(systemSessionToReport);
+            }
         }
 
         public void dispose() {
@@ -1559,6 +1623,14 @@
             pw.println(indent + "mPid=" + mPid);
             pw.println(indent + "mHasConfigureWifiDisplayPermission="
                     + mHasConfigureWifiDisplayPermission);
+            pw.println(
+                    indent
+                            + "mHasModifyAudioRoutingPermission="
+                            + mHasModifyAudioRoutingPermission);
+            pw.println(
+                    indent
+                            + "mHasBluetoothRoutingPermission="
+                            + mHasBluetoothRoutingPermission.get());
             pw.println(indent + "hasSystemRoutingPermission=" + hasSystemRoutingPermission());
             pw.println(indent + "mRouterId=" + mRouterId);
 
@@ -1581,6 +1653,19 @@
         }
 
         /**
+         * Sends the corresponding router an update for the given session.
+         *
+         * <p>Note: These updates are not directly visible to the app.
+         */
+        public void notifySessionInfoChanged(RoutingSessionInfo sessionInfo) {
+            try {
+                mRouter.notifySessionInfoChanged(sessionInfo);
+            } catch (RemoteException ex) {
+                Slog.w(TAG, "Failed to notify session info changed. Router probably died.", ex);
+            }
+        }
+
+        /**
          * Returns a filtered copy of {@code routes} that contains only the routes that are {@link
          * MediaRoute2Info#isVisibleTo visible} to the router corresponding to this record.
          */
@@ -2471,11 +2556,7 @@
                 @NonNull List<RouterRecord> routerRecords,
                 @NonNull RoutingSessionInfo sessionInfo) {
             for (RouterRecord routerRecord : routerRecords) {
-                try {
-                    routerRecord.mRouter.notifySessionInfoChanged(sessionInfo);
-                } catch (RemoteException ex) {
-                    Slog.w(TAG, "Failed to notify session info changed. Router probably died.", ex);
-                }
+                routerRecord.notifySessionInfoChanged(sessionInfo);
             }
         }
 
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 4d134b6..b440e88 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -18,6 +18,7 @@
 
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
@@ -137,6 +138,7 @@
     private final String mDefaultAudioRouteId;
     private final String mBluetoothA2dpRouteId;
 
+    @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
     public MediaRouterService(Context context) {
         mService2 = new MediaRouter2ServiceImpl(context);
         mContext = context;
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index 6d2d2e4..426bc5e 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -55,7 +55,6 @@
             SystemMediaRoute2Provider.class.getPackage().getName(),
             SystemMediaRoute2Provider.class.getName());
 
-    static final String DEFAULT_ROUTE_ID = "DEFAULT_ROUTE";
     static final String SYSTEM_SESSION_ID = "SYSTEM_SESSION";
 
     private final AudioManager mAudioManager;
@@ -170,7 +169,7 @@
             Bundle sessionHints) {
         // Assume a router without MODIFY_AUDIO_ROUTING permission can't request with
         // a route ID different from the default route ID. The service should've filtered.
-        if (TextUtils.equals(routeId, DEFAULT_ROUTE_ID)) {
+        if (TextUtils.equals(routeId, MediaRoute2Info.ROUTE_ID_DEFAULT)) {
             mCallback.onSessionCreated(this, requestId, mDefaultSessionInfo);
             return;
         }
@@ -213,7 +212,7 @@
 
     @Override
     public void transferToRoute(long requestId, String sessionId, String routeId) {
-        if (TextUtils.equals(routeId, DEFAULT_ROUTE_ID)) {
+        if (TextUtils.equals(routeId, MediaRoute2Info.ROUTE_ID_DEFAULT)) {
             // The currently selected route is the default route.
             return;
         }
@@ -326,10 +325,11 @@
                 builder.addTransferableRoute(deviceRoute.getId());
             }
             mSelectedRouteId = selectedRoute.getId();
-            mDefaultRoute = new MediaRoute2Info.Builder(DEFAULT_ROUTE_ID, selectedRoute)
-                    .setSystemRoute(true)
-                    .setProviderId(mUniqueId)
-                    .build();
+            mDefaultRoute =
+                    new MediaRoute2Info.Builder(MediaRoute2Info.ROUTE_ID_DEFAULT, selectedRoute)
+                            .setSystemRoute(true)
+                            .setProviderId(mUniqueId)
+                            .build();
             builder.addSelectedRoute(mSelectedRouteId);
 
             for (MediaRoute2Info route : mBluetoothRouteController.getTransferableRoutes()) {
@@ -363,12 +363,13 @@
                 }
                 mSessionInfos.clear();
                 mSessionInfos.add(newSessionInfo);
-                mDefaultSessionInfo = new RoutingSessionInfo.Builder(
-                        SYSTEM_SESSION_ID, "" /* clientPackageName */)
-                        .setProviderId(mUniqueId)
-                        .setSystemSession(true)
-                        .addSelectedRoute(DEFAULT_ROUTE_ID)
-                        .build();
+                mDefaultSessionInfo =
+                        new RoutingSessionInfo.Builder(
+                                        SYSTEM_SESSION_ID, "" /* clientPackageName */)
+                                .setProviderId(mUniqueId)
+                                .setSystemSession(true)
+                                .addSelectedRoute(MediaRoute2Info.ROUTE_ID_DEFAULT)
+                                .build();
                 return true;
             }
         }
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 377b8cf..5324acd 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -72,6 +72,7 @@
 import android.view.ContentRecordingSession;
 
 import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
@@ -111,7 +112,11 @@
     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
     static final long MEDIA_PROJECTION_PREVENTS_REUSING_CONSENT = 266201607L; // buganizer id
 
-    private final Object mLock = new Object(); // Protects the list of media projections
+    // Protects access to state at service level & IMediaProjection level.
+    // Invocation order while holding locks must follow below to avoid deadlock:
+    // WindowManagerService -> MediaProjectionManagerService -> DisplayManagerService
+    // See mediaprojection.md
+    private final Object mLock = new Object();
     private final Map<IBinder, IBinder.DeathRecipient> mDeathEaters;
     private final CallbackDelegate mCallbackDelegate;
 
@@ -127,7 +132,9 @@
     private final MediaRouterCallback mMediaRouterCallback;
     private MediaRouter.RouteInfo mMediaRouteInfo;
 
+    @GuardedBy("mLock")
     private IBinder mProjectionToken;
+    @GuardedBy("mLock")
     private MediaProjection mProjectionGrant;
 
     public MediaProjectionManagerService(Context context) {
@@ -232,7 +239,10 @@
                 return;
             }
 
-            if ((serviceTypes & ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION) != 0) {
+            if (mActivityManagerInternal.hasRunningForegroundService(
+                    uid, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION)) {
+                // If there is any process within this UID running a FGS
+                // with the mediaProjection type, that's Okay.
                 return;
             }
 
@@ -311,9 +321,11 @@
      */
     @VisibleForTesting
     boolean setContentRecordingSession(@Nullable ContentRecordingSession incomingSession) {
+        // NEVER lock while calling into WindowManagerService, since WindowManagerService is
+        // ALWAYS locked when it invokes MediaProjectionManagerService.
+        final boolean setSessionSucceeded = mWmInternal.setContentRecordingSession(incomingSession);
         synchronized (mLock) {
-            if (!mWmInternal.setContentRecordingSession(
-                    incomingSession)) {
+            if (!setSessionSucceeded) {
                 // Unable to start mirroring, so tear down this projection.
                 if (mProjectionGrant != null) {
                     mProjectionGrant.stop();
@@ -356,13 +368,20 @@
      */
     @VisibleForTesting
     void requestConsentForInvalidProjection() {
+        Intent reviewConsentIntent;
+        int uid;
         synchronized (mLock) {
-            Slog.v(TAG, "Reusing token: Reshow dialog for due to invalid projection.");
-            // Trigger the permission dialog again in SysUI
-            // Do not handle the result; SysUI will update us when the user has consented.
-            mContext.startActivityAsUser(buildReviewGrantedConsentIntent(),
-                    UserHandle.getUserHandleForUid(mProjectionGrant.uid));
+            reviewConsentIntent = buildReviewGrantedConsentIntentLocked();
+            uid = mProjectionGrant.uid;
         }
+        // NEVER lock while calling into a method that eventually acquires the WindowManagerService
+        // lock, since WindowManagerService is ALWAYS locked when it invokes
+        // MediaProjectionManagerService.
+        Slog.v(TAG, "Reusing token: Reshow dialog for due to invalid projection.");
+        // Trigger the permission dialog again in SysUI
+        // Do not handle the result; SysUI will update us when the user has consented.
+        mContext.startActivityAsUser(reviewConsentIntent,
+                UserHandle.getUserHandleForUid(uid));
     }
 
     /**
@@ -372,7 +391,7 @@
      * <p>Consent dialog result handled in
      * {@link BinderService#setUserReviewGrantedConsentResult(int)}.
      */
-    private Intent buildReviewGrantedConsentIntent() {
+    private Intent buildReviewGrantedConsentIntentLocked() {
         final String permissionDialogString = mContext.getResources().getString(
                 R.string.config_mediaProjectionPermissionDialogComponent);
         final ComponentName mediaProjectionPermissionDialogComponent =
@@ -385,7 +404,8 @@
     }
 
     /**
-     * Handles result of dialog shown from {@link BinderService#buildReviewGrantedConsentIntent()}.
+     * Handles result of dialog shown from
+     * {@link BinderService#buildReviewGrantedConsentIntentLocked()}.
      *
      * <p>Tears down session if user did not consent, or starts mirroring if user did consent.
      */
@@ -406,7 +426,7 @@
                 return;
             }
             if (mProjectionGrant.mSession == null
-                    || !mProjectionGrant.mSession.isWaitingToRecord()) {
+                    || !mProjectionGrant.mSession.isWaitingForConsent()) {
                 Slog.w(TAG, "Reusing token: Ignore consent result " + consentResult
                         + " if not waiting for the result.");
                 return;
@@ -445,7 +465,7 @@
      */
     private void setReviewedConsentSessionLocked(@Nullable ContentRecordingSession session) {
         if (session != null) {
-            session.setWaitingToRecord(false);
+            session.setWaitingForConsent(false);
             session.setVirtualDisplayId(mProjectionGrant.mVirtualDisplayId);
         }
 
@@ -487,23 +507,26 @@
     MediaProjection getProjectionInternal(int uid, String packageName) {
         final long callingToken = Binder.clearCallingIdentity();
         try {
-            // Supposedly the package has re-used the user's consent; confirm the provided details
-            // against the current projection token before re-using the current projection.
-            if (mProjectionGrant == null || mProjectionGrant.mSession == null
-                    || !mProjectionGrant.mSession.isWaitingToRecord()) {
-                Slog.e(TAG, "Reusing token: Not possible to reuse the current projection "
-                        + "instance");
-                return null;
-            }
+            synchronized (mLock) {
+                // Supposedly the package has re-used the user's consent; confirm the provided
+                // details against the current projection token before re-using the current
+                // projection.
+                if (mProjectionGrant == null || mProjectionGrant.mSession == null
+                        || !mProjectionGrant.mSession.isWaitingForConsent()) {
+                    Slog.e(TAG, "Reusing token: Not possible to reuse the current projection "
+                            + "instance");
+                    return null;
+                }
                 // The package matches, go ahead and re-use the token for this request.
-            if (mProjectionGrant.uid == uid
-                    && Objects.equals(mProjectionGrant.packageName, packageName)) {
-                Slog.v(TAG, "Reusing token: getProjection can reuse the current projection");
-                return mProjectionGrant;
-            } else {
-                Slog.e(TAG, "Reusing token: Not possible to reuse the current projection "
-                        + "instance due to package details mismatching");
-                return null;
+                if (mProjectionGrant.uid == uid
+                        && Objects.equals(mProjectionGrant.packageName, packageName)) {
+                    Slog.v(TAG, "Reusing token: getProjection can reuse the current projection");
+                    return mProjectionGrant;
+                } else {
+                    Slog.e(TAG, "Reusing token: Not possible to reuse the current projection "
+                            + "instance due to package details mismatching");
+                    return null;
+                }
             }
         } finally {
             Binder.restoreCallingIdentity(callingToken);
@@ -623,8 +646,10 @@
             }
             final long token = Binder.clearCallingIdentity();
             try {
-                if (mProjectionGrant != null) {
-                    mProjectionGrant.stop();
+                synchronized (mLock) {
+                    if (mProjectionGrant != null) {
+                        mProjectionGrant.stop();
+                    }
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -638,13 +663,17 @@
                 throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to notify "
                         + "on captured content resize");
             }
-            if (!isCurrentProjection(mProjectionGrant)) {
-                return;
+            synchronized (mLock) {
+                if (!isCurrentProjection(mProjectionGrant)) {
+                    return;
+                }
             }
             final long token = Binder.clearCallingIdentity();
             try {
-                if (mProjectionGrant != null && mCallbackDelegate != null) {
-                    mCallbackDelegate.dispatchResize(mProjectionGrant, width, height);
+                synchronized (mLock) {
+                    if (mProjectionGrant != null && mCallbackDelegate != null) {
+                        mCallbackDelegate.dispatchResize(mProjectionGrant, width, height);
+                    }
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -658,13 +687,17 @@
                 throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to notify "
                         + "on captured content visibility changed");
             }
-            if (!isCurrentProjection(mProjectionGrant)) {
-                return;
+            synchronized (mLock) {
+                if (!isCurrentProjection(mProjectionGrant)) {
+                    return;
+                }
             }
             final long token = Binder.clearCallingIdentity();
             try {
-                if (mProjectionGrant != null && mCallbackDelegate != null) {
-                    mCallbackDelegate.dispatchVisibilityChanged(mProjectionGrant, isVisible);
+                synchronized (mLock) {
+                    if (mProjectionGrant != null && mCallbackDelegate != null) {
+                        mCallbackDelegate.dispatchVisibilityChanged(mProjectionGrant, isVisible);
+                    }
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -709,9 +742,11 @@
                 throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION to set session "
                         + "details.");
             }
-            if (!isCurrentProjection(projection)) {
-                throw new SecurityException("Unable to set ContentRecordingSession on "
-                        + "non-current MediaProjection");
+            synchronized (mLock) {
+                if (!isCurrentProjection(projection)) {
+                    throw new SecurityException("Unable to set ContentRecordingSession on "
+                            + "non-current MediaProjection");
+                }
             }
             final long origId = Binder.clearCallingIdentity();
             try {
@@ -729,10 +764,12 @@
                 throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION to check if the given"
                         + "projection is valid.");
             }
-            if (!isCurrentProjection(projection)) {
-                Slog.v(TAG, "Reusing token: Won't request consent again for a token that "
-                        + "isn't current");
-                return;
+            synchronized (mLock) {
+                if (!isCurrentProjection(projection)) {
+                    Slog.v(TAG, "Reusing token: Won't request consent again for a token that "
+                            + "isn't current");
+                    return;
+                }
             }
 
             // Remove calling app identity before performing any privileged operations.
diff --git a/services/core/java/com/android/server/media/projection/mediaprojection.md b/services/core/java/com/android/server/media/projection/mediaprojection.md
new file mode 100644
index 0000000..bccdf34
--- /dev/null
+++ b/services/core/java/com/android/server/media/projection/mediaprojection.md
@@ -0,0 +1,30 @@
+# MediaProjection
+
+## Locking model
+`MediaProjectionManagerService` needs to have consistent lock ordering with its interactions with
+`WindowManagerService` to prevent deadlock.
+
+### TLDR
+`MediaProjectionManagerService` must lock when updating its own fields.
+
+Calls must follow the below invocation order while holding locks:
+
+`WindowManagerService -> MediaProjectionManagerService -> DisplayManagerService`
+
+### Justification
+
+`MediaProjectionManagerService` calls into `WindowManagerService` in the below cases. While handling
+each invocation, `WindowManagerService` acquires its own lock:
+* setting a `ContentRecordingSession`
+  * starting a new `MediaProjection` recording session through
+`MediaProjection#createVirtualDisplay`
+  * indicating the user has granted consent to reuse the consent token
+
+`WindowManagerService` calls into `MediaProjectionManagerService`, always while holding
+`WindowManagerGlobalLock`:
+* `ContentRecorder` handling various events such as resizing recorded content
+
+
+Since `WindowManagerService -> MediaProjectionManagerService` is guaranteed to always hold the
+`WindowManagerService` lock, we must ensure that `MediaProjectionManagerService ->
+WindowManagerService` is NEVER holding the `MediaProjectionManagerService` lock.
diff --git a/services/core/java/com/android/server/net/NetworkManagementService.java b/services/core/java/com/android/server/net/NetworkManagementService.java
index acfa665..e5ffa7e 100644
--- a/services/core/java/com/android/server/net/NetworkManagementService.java
+++ b/services/core/java/com/android/server/net/NetworkManagementService.java
@@ -53,7 +53,6 @@
 import android.net.NetworkStack;
 import android.net.NetworkStats;
 import android.net.RouteInfo;
-import android.net.UidRangeParcel;
 import android.net.util.NetdService;
 import android.os.BatteryStats;
 import android.os.Binder;
@@ -97,7 +96,6 @@
 import java.net.InetAddress;
 import java.net.InterfaceAddress;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -1351,70 +1349,6 @@
         }
     }
 
-    private void closeSocketsForFirewallChainLocked(int chain, String chainName) {
-        // UID ranges to close sockets on.
-        UidRangeParcel[] ranges;
-        // UID ranges whose sockets we won't touch.
-        int[] exemptUids;
-
-        int numUids = 0;
-        if (DBG) Slog.d(TAG, "Closing sockets after enabling chain " + chainName);
-        if (getFirewallType(chain) == FIREWALL_ALLOWLIST) {
-            // Close all sockets on all non-system UIDs...
-            ranges = new UidRangeParcel[] {
-                // TODO: is there a better way of finding all existing users? If so, we could
-                // specify their ranges here.
-                new UidRangeParcel(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE),
-            };
-            // ... except for the UIDs that have allow rules.
-            synchronized (mRulesLock) {
-                final SparseIntArray rules = getUidFirewallRulesLR(chain);
-                exemptUids = new int[rules.size()];
-                for (int i = 0; i < exemptUids.length; i++) {
-                    if (rules.valueAt(i) == FIREWALL_RULE_ALLOW) {
-                        exemptUids[numUids] = rules.keyAt(i);
-                        numUids++;
-                    }
-                }
-            }
-            // Normally, allowlist chains only contain deny rules, so numUids == exemptUids.length.
-            // But the code does not guarantee this in any way, and at least in one case - if we add
-            // a UID rule to the firewall, and then disable the firewall - the chains can contain
-            // the wrong type of rule. In this case, don't close connections that we shouldn't.
-            //
-            // TODO: tighten up this code by ensuring we never set the wrong type of rule, and
-            // fix setFirewallEnabled to grab mQuotaLock and clear rules.
-            if (numUids != exemptUids.length) {
-                exemptUids = Arrays.copyOf(exemptUids, numUids);
-            }
-        } else {
-            // Close sockets for every UID that has a deny rule...
-            synchronized (mRulesLock) {
-                final SparseIntArray rules = getUidFirewallRulesLR(chain);
-                ranges = new UidRangeParcel[rules.size()];
-                for (int i = 0; i < ranges.length; i++) {
-                    if (rules.valueAt(i) == FIREWALL_RULE_DENY) {
-                        int uid = rules.keyAt(i);
-                        ranges[numUids] = new UidRangeParcel(uid, uid);
-                        numUids++;
-                    }
-                }
-            }
-            // As above; usually numUids == ranges.length, but not always.
-            if (numUids != ranges.length) {
-                ranges = Arrays.copyOf(ranges, numUids);
-            }
-            // ... with no exceptions.
-            exemptUids = new int[0];
-        }
-
-        try {
-            mNetdService.socketDestroy(ranges, exemptUids);
-        } catch(RemoteException | ServiceSpecificException e) {
-            Slog.e(TAG, "Error closing sockets after enabling chain " + chainName + ": " + e);
-        }
-    }
-
     @Override
     public void setFirewallChainEnabled(int chain, boolean enable) {
         enforceSystemUid();
@@ -1439,14 +1373,6 @@
             } catch (RuntimeException e) {
                 throw new IllegalStateException(e);
             }
-
-            // Close any sockets that were opened by the affected UIDs. This has to be done after
-            // disabling network connectivity, in case they react to the socket close by reopening
-            // the connection and race with the iptables commands that enable the firewall. All
-            // allowlist and denylist chains allow RSTs through.
-            if (enable) {
-                closeSocketsForFirewallChainLocked(chain, chainName);
-            }
         }
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 31074c1..e56eba6 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1652,7 +1652,8 @@
             if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
                 // update system notification channels
                 SystemNotificationChannels.createAll(context);
-                mZenModeHelper.updateDefaultZenRules();
+                mZenModeHelper.updateDefaultZenRules(Binder.getCallingUid(),
+                        isCallerIsSystemOrSystemUi());
                 mPreferencesHelper.onLocaleChanged(context, ActivityManager.getCurrentUser());
             }
         }
@@ -2280,7 +2281,8 @@
         mRankingHandler = rankingHandler;
         mConditionProviders = conditionProviders;
         mZenModeHelper = new ZenModeHelper(getContext(), mHandler.getLooper(), mConditionProviders,
-                new SysUiStatsEvent.BuilderFactory());
+                new SysUiStatsEvent.BuilderFactory(), flagResolver,
+                new ZenModeEventLogger(mPackageManagerClient));
         mZenModeHelper.addCallback(new ZenModeHelper.Callback() {
             @Override
             public void onConfigChanged() {
@@ -2862,7 +2864,8 @@
         final NotificationChannel preUpdate =
                 mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(), true);
 
-        mPreferencesHelper.updateNotificationChannel(pkg, uid, channel, true);
+        mPreferencesHelper.updateNotificationChannel(pkg, uid, channel, true,
+                Binder.getCallingUid(), isCallerIsSystemOrSystemUi());
         if (mPreferencesHelper.onlyHasDefaultChannel(pkg, uid)) {
             mPermissionHelper.setNotificationPermission(pkg, UserHandle.getUserId(uid),
                     channel.getImportance() != IMPORTANCE_NONE, true);
@@ -2910,7 +2913,7 @@
         final NotificationChannelGroup preUpdate =
                 mPreferencesHelper.getNotificationChannelGroup(group.getId(), pkg, uid);
         mPreferencesHelper.createNotificationChannelGroup(pkg, uid, group,
-                fromApp);
+                fromApp, Binder.getCallingUid(), isCallerIsSystemOrSystemUi());
         if (!fromApp) {
             maybeNotifyChannelGroupOwner(pkg, uid, preUpdate, group);
         }
@@ -3875,7 +3878,8 @@
                 needsPolicyFileChange = mPreferencesHelper.createNotificationChannel(pkg, uid,
                         channel, true /* fromTargetApp */,
                         mConditionProviders.isPackageOrComponentAllowed(
-                                pkg, UserHandle.getUserId(uid)));
+                                pkg, UserHandle.getUserId(uid)), Binder.getCallingUid(),
+                        isCallerIsSystemOrSystemUi());
                 if (needsPolicyFileChange) {
                     mListeners.notifyNotificationChannelChanged(pkg,
                             UserHandle.getUserHandleForUid(uid),
@@ -4011,6 +4015,7 @@
         public void deleteNotificationChannel(String pkg, String channelId) {
             checkCallerIsSystemOrSameApp(pkg);
             final int callingUid = Binder.getCallingUid();
+            final boolean isSystemOrSystemUi = isCallerIsSystemOrSystemUi();
             final int callingUser = UserHandle.getUserId(callingUid);
             if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
                 throw new IllegalArgumentException("Cannot delete default channel");
@@ -4020,7 +4025,7 @@
             cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channelId, 0, 0, true,
                     callingUser, REASON_CHANNEL_REMOVED, null);
             boolean previouslyExisted = mPreferencesHelper.deleteNotificationChannel(
-                    pkg, callingUid, channelId);
+                    pkg, callingUid, channelId, callingUid, isSystemOrSystemUi);
             if (previouslyExisted) {
                 // Remove from both recent notification archive and notification history
                 mArchive.removeChannelNotifications(pkg, callingUser, channelId);
@@ -4053,6 +4058,7 @@
             checkCallerIsSystemOrSameApp(pkg);
 
             final int callingUid = Binder.getCallingUid();
+            final boolean isSystemOrSystemUi = isCallerIsSystemOrSystemUi();
             NotificationChannelGroup groupToDelete =
                     mPreferencesHelper.getNotificationChannelGroupWithChannels(
                             pkg, callingUid, groupId, false);
@@ -4066,7 +4072,8 @@
                     enforceDeletingChannelHasNoUserInitiatedJob(pkg, userId, channelId);
                 }
                 List<NotificationChannel> deletedChannels =
-                        mPreferencesHelper.deleteNotificationChannelGroup(pkg, callingUid, groupId);
+                        mPreferencesHelper.deleteNotificationChannelGroup(pkg, callingUid, groupId,
+                                callingUid, isSystemOrSystemUi);
                 for (int i = 0; i < deletedChannels.size(); i++) {
                     final NotificationChannel deletedChannel = deletedChannels.get(i);
                     cancelAllNotificationsInt(MY_UID, MY_PID, pkg, deletedChannel.getId(), 0, 0,
@@ -4964,11 +4971,14 @@
         @Override
         public void requestInterruptionFilterFromListener(INotificationListener token,
                 int interruptionFilter) throws RemoteException {
+            final int callingUid = Binder.getCallingUid();
+            final boolean isSystemOrSystemUi = isCallerIsSystemOrSystemUi();
             final long identity = Binder.clearCallingIdentity();
             try {
                 synchronized (mNotificationLock) {
                     final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
-                    mZenModeHelper.requestFromListener(info.component, interruptionFilter);
+                    mZenModeHelper.requestFromListener(info.component, interruptionFilter,
+                            callingUid, isSystemOrSystemUi);
                     updateInterruptionFilterLocked();
                 }
             } finally {
@@ -5008,9 +5018,12 @@
         @Override
         public void setZenMode(int mode, Uri conditionId, String reason) throws RemoteException {
             enforceSystemOrSystemUI("INotificationManager.setZenMode");
+            final int callingUid = Binder.getCallingUid();
+            final boolean isSystemOrSystemUi = isCallerIsSystemOrSystemUi();
             final long identity = Binder.clearCallingIdentity();
             try {
-                mZenModeHelper.setManualZenMode(mode, conditionId, null, reason);
+                mZenModeHelper.setManualZenMode(mode, conditionId, null, reason, callingUid,
+                        isSystemOrSystemUi);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -5057,7 +5070,8 @@
             }
 
             return mZenModeHelper.addAutomaticZenRule(rulePkg, automaticZenRule,
-                    "addAutomaticZenRule");
+                    "addAutomaticZenRule", Binder.getCallingUid(),
+                    isCallerIsSystemOrSystemUi());
         }
 
         @Override
@@ -5074,7 +5088,8 @@
             enforcePolicyAccess(Binder.getCallingUid(), "updateAutomaticZenRule");
 
             return mZenModeHelper.updateAutomaticZenRule(id, automaticZenRule,
-                    "updateAutomaticZenRule");
+                    "updateAutomaticZenRule", Binder.getCallingUid(),
+                    isCallerIsSystemOrSystemUi());
         }
 
         @Override
@@ -5083,7 +5098,8 @@
             // Verify that they can modify zen rules.
             enforcePolicyAccess(Binder.getCallingUid(), "removeAutomaticZenRule");
 
-            return mZenModeHelper.removeAutomaticZenRule(id, "removeAutomaticZenRule");
+            return mZenModeHelper.removeAutomaticZenRule(id, "removeAutomaticZenRule",
+                    Binder.getCallingUid(), isCallerIsSystemOrSystemUi());
         }
 
         @Override
@@ -5092,7 +5108,8 @@
             enforceSystemOrSystemUI("removeAutomaticZenRules");
 
             return mZenModeHelper.removeAutomaticZenRules(packageName,
-                    packageName + "|removeAutomaticZenRules");
+                    packageName + "|removeAutomaticZenRules", Binder.getCallingUid(),
+                    isCallerIsSystemOrSystemUi());
         }
 
         @Override
@@ -5110,7 +5127,8 @@
 
             enforcePolicyAccess(Binder.getCallingUid(), "setAutomaticZenRuleState");
 
-            mZenModeHelper.setAutomaticZenRuleState(id, condition);
+            mZenModeHelper.setAutomaticZenRuleState(id, condition, Binder.getCallingUid(),
+                    isCallerIsSystemOrSystemUi());
         }
 
         @Override
@@ -5118,9 +5136,12 @@
             enforcePolicyAccess(pkg, "setInterruptionFilter");
             final int zen = NotificationManager.zenModeFromInterruptionFilter(filter, -1);
             if (zen == -1) throw new IllegalArgumentException("Invalid filter: " + filter);
+            final int callingUid = Binder.getCallingUid();
+            final boolean isSystemOrSystemUi = isCallerIsSystemOrSystemUi();
             final long identity = Binder.clearCallingIdentity();
             try {
-                mZenModeHelper.setManualZenMode(zen, null, pkg, "setInterruptionFilter");
+                mZenModeHelper.setManualZenMode(zen, null, pkg, "setInterruptionFilter",
+                        callingUid, isSystemOrSystemUi);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -5421,6 +5442,7 @@
         public void setNotificationPolicy(String pkg, Policy policy) {
             enforcePolicyAccess(pkg, "setNotificationPolicy");
             int callingUid = Binder.getCallingUid();
+            boolean isSystemOrSystemUi = isCallerIsSystemOrSystemUi();
             final long identity = Binder.clearCallingIdentity();
             try {
                 final ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(pkg,
@@ -5460,7 +5482,7 @@
                         policy.priorityCallSenders, policy.priorityMessageSenders,
                         newVisualEffects, policy.priorityConversationSenders);
                 ZenLog.traceSetNotificationPolicy(pkg, applicationInfo.targetSdkVersion, policy);
-                mZenModeHelper.setNotificationPolicy(policy);
+                mZenModeHelper.setNotificationPolicy(policy, callingUid, isSystemOrSystemUi);
             } catch (RemoteException e) {
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -6698,7 +6720,8 @@
                     channel.setUserVisibleTaskShown(true);
                 }
                 mPreferencesHelper.updateNotificationChannel(
-                        pkg, notificationUid, channel, false);
+                        pkg, notificationUid, channel, false, callingUid,
+                        isCallerIsSystemOrSystemUi());
                 r.updateNotificationChannel(channel);
             } else if (!channel.isUserVisibleTaskShown() && !TextUtils.isEmpty(channelId)
                     && !NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
@@ -6771,7 +6794,8 @@
 
         mHistoryManager.deleteConversations(pkg, uid, shortcuts);
         List<String> deletedChannelIds =
-                mPreferencesHelper.deleteConversations(pkg, uid, shortcuts);
+                mPreferencesHelper.deleteConversations(pkg, uid, shortcuts,
+                        /* callingUid */ Process.SYSTEM_UID, /* is system */ true);
         for (String channelId : deletedChannelIds) {
             cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channelId, 0, 0, true,
                     UserHandle.getUserId(uid), REASON_CHANNEL_REMOVED,
@@ -10000,7 +10024,8 @@
         return isUidSystemOrPhone(Binder.getCallingUid());
     }
 
-    private boolean isCallerIsSystemOrSystemUi() {
+    @VisibleForTesting
+    protected boolean isCallerIsSystemOrSystemUi() {
         if (isCallerSystemOrPhone()) {
             return true;
         }
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
index cd457b7..feb75ef 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
@@ -74,7 +74,8 @@
                 notificationReported.is_ongoing,
                 notificationReported.is_foreground_service,
                 notificationReported.timeout_millis,
-                notificationReported.is_non_dismissible);
+                notificationReported.is_non_dismissible,
+                notificationReported.post_duration_millis);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 2460ce5..4399a3c 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -51,6 +51,7 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
+import android.os.Process;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.ConversationChannelWrapper;
@@ -217,7 +218,7 @@
         updateBadgingEnabled();
         updateBubblesEnabled();
         updateMediaNotificationFilteringEnabled();
-        syncChannelsBypassingDnd();
+        syncChannelsBypassingDnd(Process.SYSTEM_UID, true);  // init comes from system
     }
 
     public void readXml(TypedXmlPullParser parser, boolean forRestore, int userId)
@@ -834,7 +835,7 @@
 
     @Override
     public void createNotificationChannelGroup(String pkg, int uid, NotificationChannelGroup group,
-            boolean fromTargetApp) {
+            boolean fromTargetApp, int callingUid, boolean fromSystemOrSystemUi) {
         Objects.requireNonNull(pkg);
         Objects.requireNonNull(group);
         Objects.requireNonNull(group.getId());
@@ -880,13 +881,14 @@
             r.groups.put(group.getId(), group);
         }
         if (needsDndChange) {
-            updateChannelsBypassingDnd();
+            updateChannelsBypassingDnd(callingUid, fromSystemOrSystemUi);
         }
     }
 
     @Override
     public boolean createNotificationChannel(String pkg, int uid, NotificationChannel channel,
-            boolean fromTargetApp, boolean hasDndAccess) {
+            boolean fromTargetApp, boolean hasDndAccess, int callingUid,
+            boolean fromSystemOrSystemUi) {
         Objects.requireNonNull(pkg);
         Objects.requireNonNull(channel);
         Objects.requireNonNull(channel.getId());
@@ -1027,7 +1029,7 @@
         }
 
         if (needsDndChange) {
-            updateChannelsBypassingDnd();
+            updateChannelsBypassingDnd(callingUid, fromSystemOrSystemUi);
         }
 
         return needsPolicyFileChange;
@@ -1056,7 +1058,7 @@
 
     @Override
     public void updateNotificationChannel(String pkg, int uid, NotificationChannel updatedChannel,
-            boolean fromUser) {
+            boolean fromUser, int callingUid, boolean fromSystemOrSystemUi) {
         Objects.requireNonNull(updatedChannel);
         Objects.requireNonNull(updatedChannel.getId());
         boolean changed = false;
@@ -1112,7 +1114,7 @@
             }
         }
         if (needsDndChange) {
-            updateChannelsBypassingDnd();
+            updateChannelsBypassingDnd(callingUid, fromSystemOrSystemUi);
         }
         if (changed) {
             updateConfig();
@@ -1188,7 +1190,8 @@
     }
 
     @Override
-    public boolean deleteNotificationChannel(String pkg, int uid, String channelId) {
+    public boolean deleteNotificationChannel(String pkg, int uid, String channelId,
+            int callingUid, boolean fromSystemOrSystemUi) {
         boolean deletedChannel = false;
         boolean channelBypassedDnd = false;
         synchronized (mPackagePreferences) {
@@ -1203,7 +1206,7 @@
             }
         }
         if (channelBypassedDnd) {
-            updateChannelsBypassingDnd();
+            updateChannelsBypassingDnd(callingUid, fromSystemOrSystemUi);
         }
         return deletedChannel;
     }
@@ -1394,7 +1397,7 @@
     }
 
     public List<NotificationChannel> deleteNotificationChannelGroup(String pkg, int uid,
-            String groupId) {
+            String groupId, int callingUid, boolean fromSystemOrSystemUi) {
         List<NotificationChannel> deletedChannels = new ArrayList<>();
         boolean groupBypassedDnd = false;
         synchronized (mPackagePreferences) {
@@ -1420,7 +1423,7 @@
             }
         }
         if (groupBypassedDnd) {
-            updateChannelsBypassingDnd();
+            updateChannelsBypassingDnd(callingUid, fromSystemOrSystemUi);
         }
         return deletedChannels;
     }
@@ -1543,7 +1546,7 @@
     }
 
     public @NonNull List<String> deleteConversations(String pkg, int uid,
-            Set<String> conversationIds) {
+            Set<String> conversationIds, int callingUid, boolean fromSystemOrSystemUi) {
         List<String> deletedChannelIds = new ArrayList<>();
         synchronized (mPackagePreferences) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
@@ -1568,7 +1571,7 @@
             }
         }
         if (!deletedChannelIds.isEmpty() && mAreChannelsBypassingDnd) {
-            updateChannelsBypassingDnd();
+            updateChannelsBypassingDnd(callingUid, fromSystemOrSystemUi);
         }
         return deletedChannelIds;
     }
@@ -1673,18 +1676,18 @@
      * Syncs {@link #mAreChannelsBypassingDnd} with the current user's notification policy before
      * updating
      */
-    private void syncChannelsBypassingDnd() {
+    private void syncChannelsBypassingDnd(int callingUid, boolean fromSystemOrSystemUi) {
         mAreChannelsBypassingDnd = (mZenModeHelper.getNotificationPolicy().state
                 & NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND) == 1;
 
-        updateChannelsBypassingDnd();
+        updateChannelsBypassingDnd(callingUid, fromSystemOrSystemUi);
     }
 
     /**
      * Updates the user's NotificationPolicy based on whether the current userId
      * has channels bypassing DND
      */
-    private void updateChannelsBypassingDnd() {
+    private void updateChannelsBypassingDnd(int callingUid, boolean fromSystemOrSystemUi) {
         ArraySet<Pair<String, Integer>> candidatePkgs = new ArraySet<>();
 
         final int currentUserId = getCurrentUser();
@@ -1714,7 +1717,7 @@
         boolean haveBypassingApps = candidatePkgs.size() > 0;
         if (mAreChannelsBypassingDnd != haveBypassingApps) {
             mAreChannelsBypassingDnd = haveBypassingApps;
-            updateZenPolicy(mAreChannelsBypassingDnd);
+            updateZenPolicy(mAreChannelsBypassingDnd, callingUid, fromSystemOrSystemUi);
         }
     }
 
@@ -1739,14 +1742,15 @@
         return true;
     }
 
-    public void updateZenPolicy(boolean areChannelsBypassingDnd) {
+    public void updateZenPolicy(boolean areChannelsBypassingDnd, int callingUid,
+            boolean fromSystemOrSystemUi) {
         NotificationManager.Policy policy = mZenModeHelper.getNotificationPolicy();
         mZenModeHelper.setNotificationPolicy(new NotificationManager.Policy(
                 policy.priorityCategories, policy.priorityCallSenders,
                 policy.priorityMessageSenders, policy.suppressedVisualEffects,
                 (areChannelsBypassingDnd ? NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND
                         : 0),
-                policy.priorityConversationSenders));
+                policy.priorityConversationSenders), callingUid, fromSystemOrSystemUi);
     }
 
     public boolean areChannelsBypassingDnd() {
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 3e9d90c..fec3591 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -39,19 +39,21 @@
     Collection<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
             int uid);
     void createNotificationChannelGroup(String pkg, int uid, NotificationChannelGroup group,
-            boolean fromTargetApp);
+            boolean fromTargetApp, int callingUid, boolean isSystemOrSystemUi);
     ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
             int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty);
     boolean createNotificationChannel(String pkg, int uid, NotificationChannel channel,
-            boolean fromTargetApp, boolean hasDndAccess);
-    void updateNotificationChannel(String pkg, int uid, NotificationChannel channel,
-            boolean fromUser);
+            boolean fromTargetApp, boolean hasDndAccess, int callingUid,
+            boolean isSystemOrSystemUi);
+    void updateNotificationChannel(String pkg, int uid, NotificationChannel updatedChannel,
+            boolean fromUser, int callingUid, boolean fromSystemOrSystemUi);
     NotificationChannel getNotificationChannel(String pkg, int uid, String channelId,
             boolean includeDeleted);
     NotificationChannel getConversationNotificationChannel(String pkg, int uid, String channelId,
             String conversationId, boolean returnParentIfNoConversationChannel,
             boolean includeDeleted);
-    boolean deleteNotificationChannel(String pkg, int uid, String channelId);
+    boolean deleteNotificationChannel(String pkg, int uid, String channelId,
+            int callingUid, boolean fromSystemOrSystemUi);
     void permanentlyDeleteNotificationChannel(String pkg, int uid, String channelId);
     void permanentlyDeleteNotificationChannels(String pkg, int uid);
     ParceledListSlice<NotificationChannel> getNotificationChannels(String pkg, int uid,
diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java
index 50b4d43..6ecd799 100644
--- a/services/core/java/com/android/server/notification/ZenModeConditions.java
+++ b/services/core/java/com/android/server/notification/ZenModeConditions.java
@@ -18,6 +18,8 @@
 
 import android.content.ComponentName;
 import android.net.Uri;
+import android.os.Binder;
+import android.os.Process;
 import android.service.notification.Condition;
 import android.service.notification.IConditionProvider;
 import android.service.notification.ZenModeConfig;
@@ -108,7 +110,9 @@
     @Override
     public void onServiceAdded(ComponentName component) {
         if (DEBUG) Log.d(TAG, "onServiceAdded " + component);
-        mHelper.setConfig(mHelper.getConfig(), component, "zmc.onServiceAdded:" + component);
+        final int callingUid = Binder.getCallingUid();
+        mHelper.setConfig(mHelper.getConfig(), component, "zmc.onServiceAdded:" + component,
+                callingUid, callingUid == Process.SYSTEM_UID);
     }
 
     @Override
@@ -116,7 +120,9 @@
         if (DEBUG) Log.d(TAG, "onConditionChanged " + id + " " + condition);
         ZenModeConfig config = mHelper.getConfig();
         if (config == null) return;
-        mHelper.setAutomaticZenRuleState(id, condition);
+        final int callingUid = Binder.getCallingUid();
+        mHelper.setAutomaticZenRuleState(id, condition, callingUid,
+                callingUid == Process.SYSTEM_UID);
     }
 
     // Only valid for CPS backed rules
diff --git a/services/core/java/com/android/server/notification/ZenModeEventLogger.java b/services/core/java/com/android/server/notification/ZenModeEventLogger.java
new file mode 100644
index 0000000..1641d4a
--- /dev/null
+++ b/services/core/java/com/android/server/notification/ZenModeEventLogger.java
@@ -0,0 +1,611 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.notification;
+
+import static android.app.NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND;
+import static android.provider.Settings.Global.ZEN_MODE_OFF;
+import static android.service.notification.NotificationServiceProto.RULE_TYPE_AUTOMATIC;
+import static android.service.notification.NotificationServiceProto.RULE_TYPE_MANUAL;
+import static android.service.notification.NotificationServiceProto.RULE_TYPE_UNKNOWN;
+
+import android.annotation.NonNull;
+import android.app.NotificationManager;
+import android.content.pm.PackageManager;
+import android.os.Process;
+import android.service.notification.DNDPolicyProto;
+import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenModeDiff;
+import android.service.notification.ZenPolicy;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Objects;
+
+/**
+ * Class for writing DNDStateChanged atoms to the statsd log.
+ * Use ZenModeEventLoggerFake for testing.
+ */
+class ZenModeEventLogger {
+    private static final String TAG = "ZenModeEventLogger";
+
+    // Placeholder int for unknown zen mode, to distinguish from "off".
+    static final int ZEN_MODE_UNKNOWN = -1;
+
+    // Object for tracking config changes and policy changes associated with an overall zen
+    // mode change.
+    ZenModeEventLogger.ZenStateChanges mChangeState = new ZenModeEventLogger.ZenStateChanges();
+
+    private PackageManager mPm;
+
+    ZenModeEventLogger(PackageManager pm) {
+        mPm = pm;
+    }
+
+    /**
+     * Enum used to log the type of DND state changed events.
+     * These use UiEvent IDs for ease of integrating with other UiEvents.
+     */
+    enum ZenStateChangedEvent implements UiEventLogger.UiEventEnum {
+        @UiEvent(doc = "DND was turned on; may additionally include policy change.")
+        DND_TURNED_ON(1368),
+        @UiEvent(doc = "DND was turned off; may additionally include policy change.")
+        DND_TURNED_OFF(1369),
+        @UiEvent(doc = "DND policy was changed but the zen mode did not change.")
+        DND_POLICY_CHANGED(1370),
+        @UiEvent(doc = "Change in DND automatic rules active, without changing mode or policy.")
+        DND_ACTIVE_RULES_CHANGED(1371);
+
+        private final int mId;
+
+        ZenStateChangedEvent(int id) {
+            mId = id;
+        }
+
+        @Override
+        public int getId() {
+            return mId;
+        }
+    }
+
+    /**
+     * Potentially log a zen mode change if the provided config and policy changes warrant it.
+     *
+     * @param prevInfo    ZenModeInfo (zen mode setting, config, policy) prior to this change
+     * @param newInfo     ZenModeInfo after this change takes effect
+     * @param callingUid  the calling UID associated with the change; may be used to attribute the
+     *                    change to a particular package or determine if this is a user action
+     * @param fromSystemOrSystemUi whether the calling UID is either system UID or system UI
+     */
+    public final void maybeLogZenChange(ZenModeInfo prevInfo, ZenModeInfo newInfo, int callingUid,
+            boolean fromSystemOrSystemUi) {
+        mChangeState.init(prevInfo, newInfo, callingUid, fromSystemOrSystemUi);
+        if (mChangeState.shouldLogChanges()) {
+            maybeReassignCallingUid();
+            logChanges();
+        }
+
+        // clear out the state for a fresh start next time
+        mChangeState = new ZenModeEventLogger.ZenStateChanges();
+    }
+
+    /**
+     * Reassign callingUid in mChangeState if we have more specific information that warrants it
+     * (for instance, if the change is automatic and due to an automatic rule change).
+     */
+    private void maybeReassignCallingUid() {
+        int userId = Process.INVALID_UID;
+        String packageName = null;
+
+        // For a manual rule, we consider reassigning the UID only when the call seems to come from
+        // the system and there is a non-null enabler in the new config.
+        // We don't consider the manual rule in the old config because if a manual rule is turning
+        // off with a call from system, that could easily be a user action to explicitly turn it off
+        if (mChangeState.getChangedRuleType() == RULE_TYPE_MANUAL) {
+            if (!mChangeState.mFromSystemOrSystemUi
+                    || mChangeState.getNewManualRuleEnabler() == null) {
+                return;
+            }
+            packageName = mChangeState.getNewManualRuleEnabler();
+            userId = mChangeState.mNewConfig.user;  // mNewConfig must not be null if enabler exists
+        }
+
+        // The conditions where we should consider reassigning UID for an automatic rule change:
+        //   - we've determined it's not a user action
+        //   - our current best guess is that the calling uid is system/sysui
+        if (mChangeState.getChangedRuleType() == RULE_TYPE_AUTOMATIC) {
+            if (mChangeState.getIsUserAction() || !mChangeState.mFromSystemOrSystemUi) {
+                return;
+            }
+
+            // Only try to get the package UID if there's exactly one changed automatic rule. If
+            // there's more than one that changes simultaneously, this is likely to be a boot and
+            // we can leave it attributed to system.
+            ArrayMap<String, ZenModeDiff.RuleDiff> changedRules =
+                    mChangeState.getChangedAutomaticRules();
+            if (changedRules.size() != 1) {
+                return;
+            }
+            Pair<String, Integer> ruleInfo = mChangeState.getRulePackageAndUser(
+                    changedRules.keyAt(0),
+                    changedRules.valueAt(0));
+
+            if (ruleInfo == null || ruleInfo.first.equals(ZenModeConfig.SYSTEM_AUTHORITY)) {
+                // leave system rules as-is
+                return;
+            }
+
+            packageName = ruleInfo.first;
+            userId = ruleInfo.second;
+        }
+
+        if (userId == Process.INVALID_UID || packageName == null) {
+            // haven't found anything to look up.
+            return;
+        }
+
+        try {
+            int uid = mPm.getPackageUidAsUser(packageName, userId);
+            mChangeState.mCallingUid = uid;
+        } catch (PackageManager.NameNotFoundException e) {
+            Slog.e(TAG, "unable to find package name " + packageName + " " + userId);
+        }
+    }
+
+    /**
+     * Actually log all changes stored in the current change state to statsd output. This method
+     * should not be used directly by callers; visible for override by subclasses.
+     */
+    void logChanges() {
+        FrameworkStatsLog.write(FrameworkStatsLog.DND_STATE_CHANGED,
+                /* int32 event_id = 1 */ mChangeState.getEventId().getId(),
+                /* android.stats.dnd.ZenMode new_mode = 2 */ mChangeState.mNewZenMode,
+                /* android.stats.dnd.ZenMode previous_mode = 3 */ mChangeState.mPrevZenMode,
+                /* android.stats.dnd.RuleType rule_type = 4 */ mChangeState.getChangedRuleType(),
+                /* int32 num_rules_active = 5 */ mChangeState.getNumRulesActive(),
+                /* bool user_action = 6 */ mChangeState.getIsUserAction(),
+                /* int32 package_uid = 7 */ mChangeState.getPackageUid(),
+                /* DNDPolicyProto current_policy = 8 */ mChangeState.getDNDPolicyProto(),
+                /* bool are_channels_bypassing = 9 */ mChangeState.getAreChannelsBypassing());
+    }
+
+    /**
+     * Helper class for storing the set of information about a zen mode configuration at a specific
+     * time: the current zen mode setting, ZenModeConfig, and consolidated policy (a result of
+     * evaluating all active zen rules at the time).
+     */
+    public static class ZenModeInfo {
+        final int mZenMode;
+        final ZenModeConfig mConfig;
+        final NotificationManager.Policy mPolicy;
+
+        ZenModeInfo(int zenMode, ZenModeConfig config, NotificationManager.Policy policy) {
+            mZenMode = zenMode;
+            // Store a copy of configs & policies to not accidentally pick up any further changes
+            mConfig = config != null ? config.copy() : null;
+            mPolicy = policy != null ? policy.copy() : null;
+        }
+    }
+
+    /**
+     * Class used to track overall changes in zen mode, since changes such as config updates happen
+     * in multiple stages (first changing the config, then re-evaluating zen mode and the
+     * consolidated policy), and which contains the logic of 1) whether to log the zen mode change
+     * and 2) deriving the properties to log.
+     */
+    static class ZenStateChanges {
+        int mPrevZenMode = ZEN_MODE_UNKNOWN;
+        int mNewZenMode = ZEN_MODE_UNKNOWN;
+        ZenModeConfig mPrevConfig, mNewConfig;
+        NotificationManager.Policy mPrevPolicy, mNewPolicy;
+        int mCallingUid = Process.INVALID_UID;
+        boolean mFromSystemOrSystemUi = false;
+
+        private void init(ZenModeInfo prevInfo, ZenModeInfo newInfo, int callingUid,
+                boolean fromSystemOrSystemUi) {
+            // previous & new may be the same -- that would indicate that zen mode hasn't changed.
+            mPrevZenMode = prevInfo.mZenMode;
+            mNewZenMode = newInfo.mZenMode;
+            mPrevConfig = prevInfo.mConfig;
+            mNewConfig = newInfo.mConfig;
+            mPrevPolicy = prevInfo.mPolicy;
+            mNewPolicy = newInfo.mPolicy;
+            mCallingUid = callingUid;
+            mFromSystemOrSystemUi = fromSystemOrSystemUi;
+        }
+
+        /**
+         * Returns whether there is a policy diff represented by this change. This doesn't count
+         * if the previous policy is null, as that would indicate having no information rather than
+         * having no previous policy.
+         */
+        private boolean hasPolicyDiff() {
+            return mPrevPolicy != null && !Objects.equals(mPrevPolicy, mNewPolicy);
+        }
+
+        /**
+         * Whether the set of changes encapsulated in this state should be logged. This should only
+         * be called after methods to store config and zen mode info.
+         */
+        private boolean shouldLogChanges() {
+            // Did zen mode change from off to on or vice versa? If so, log in all cases.
+            if (zenModeFlipped()) {
+                return true;
+            }
+
+            // If zen mode didn't change, did the policy or number of active rules change? We only
+            // care about changes that take effect while zen mode is on, so make sure the current
+            // zen mode is not "OFF"
+            if (mNewZenMode == ZEN_MODE_OFF) {
+                return false;
+            }
+            return hasPolicyDiff() || hasRuleCountDiff();
+        }
+
+        // Does the difference in zen mode go from off to on or vice versa?
+        private boolean zenModeFlipped() {
+            if (mPrevZenMode == mNewZenMode) {
+                return false;
+            }
+
+            // then it flipped if one or the other is off. (there's only one off state; there are
+            // multiple states one could consider "on")
+            return mPrevZenMode == ZEN_MODE_OFF || mNewZenMode == ZEN_MODE_OFF;
+        }
+
+        // Helper methods below to fill out the atom contents below:
+
+        /**
+         * Based on the changes, returns the event ID corresponding to the change. Assumes that
+         * shouldLogChanges() is true and already checked (and will Log.wtf if not true).
+         */
+        ZenStateChangedEvent getEventId() {
+            if (!shouldLogChanges()) {
+                Log.wtf(TAG, "attempt to get DNDStateChanged fields without shouldLog=true");
+            }
+            if (zenModeFlipped()) {
+                if (mPrevZenMode == ZEN_MODE_OFF) {
+                    return ZenStateChangedEvent.DND_TURNED_ON;
+                } else {
+                    return ZenStateChangedEvent.DND_TURNED_OFF;
+                }
+            }
+
+            // zen mode didn't change; we must be here because of a policy change or rule change
+            if (hasPolicyDiff() || hasChannelsBypassingDiff()) {
+                return ZenStateChangedEvent.DND_POLICY_CHANGED;
+            }
+
+            // Also no policy change, so it has to be a rule change
+            return ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED;
+        }
+
+        /**
+         * Based on the config diff, determine which type of rule changed (or "unknown" to indicate
+         * unknown or neither).
+         * In the (probably somewhat unusual) case that there are both, manual takes precedence over
+         * automatic.
+         */
+        int getChangedRuleType() {
+            ZenModeDiff.ConfigDiff diff = new ZenModeDiff.ConfigDiff(mPrevConfig, mNewConfig);
+            if (!diff.hasDiff()) {
+                // no diff in the config. this probably shouldn't happen, but we can consider it
+                // unknown (given that if zen mode changes it is usually accompanied by some rule
+                // turning on or off, which should cause a config diff).
+                return RULE_TYPE_UNKNOWN;
+            }
+
+            ZenModeDiff.RuleDiff manualDiff = diff.getManualRuleDiff();
+            if (manualDiff != null && manualDiff.hasDiff()) {
+                // a diff in the manual rule doesn't *necessarily* mean that it's responsible for
+                // the change -- only if it's been added or removed.
+                if (manualDiff.wasAdded() || manualDiff.wasRemoved()) {
+                    return RULE_TYPE_MANUAL;
+                }
+            }
+
+            ArrayMap<String, ZenModeDiff.RuleDiff> autoDiffs = diff.getAllAutomaticRuleDiffs();
+            if (autoDiffs != null) {
+                for (ZenModeDiff.RuleDiff d : autoDiffs.values()) {
+                    if (d != null && d.hasDiff()) {
+                        // If the rule became active or inactive, then this is probably relevant.
+                        if (d.becameActive() || d.becameInactive()) {
+                            return RULE_TYPE_AUTOMATIC;
+                        }
+                    }
+                }
+            }
+            return RULE_TYPE_UNKNOWN;
+        }
+
+        /**
+         * Returns whether the previous config and new config have a different number of active
+         * automatic or manual rules.
+         */
+        private boolean hasRuleCountDiff() {
+            return numActiveRulesInConfig(mPrevConfig) != numActiveRulesInConfig(mNewConfig);
+        }
+
+        /**
+         * Get the number of active rules represented in a zen mode config. Because this is based
+         * on a config, this does not take into account the zen mode at the time of the config,
+         * which means callers need to take the zen mode into account for whether the rules are
+         * actually active.
+         */
+        int numActiveRulesInConfig(ZenModeConfig config) {
+            // If the config is null, return early
+            if (config == null) {
+                return 0;
+            }
+
+            int rules = 0;
+            // Loop through the config and check:
+            //  - does a manual rule exist? (if it's non-null, it's active)
+            //  - how many automatic rules are active, as defined by isAutomaticActive()?
+            if (config.manualRule != null) {
+                rules++;
+            }
+
+            if (config.automaticRules != null) {
+                for (ZenModeConfig.ZenRule rule : config.automaticRules.values()) {
+                    if (rule != null && rule.isAutomaticActive()) {
+                        rules++;
+                    }
+                }
+            }
+            return rules;
+        }
+
+        // Determine the number of (automatic & manual) rules active after the change takes place.
+        int getNumRulesActive() {
+            // If the zen mode has turned off, that means nothing can be active.
+            if (mNewZenMode == ZEN_MODE_OFF) {
+                return 0;
+            }
+            return numActiveRulesInConfig(mNewConfig);
+        }
+
+        /**
+         * Return our best guess as to whether the changes observed are due to a user action.
+         * Note that this won't be 100% accurate as we can't necessarily distinguish between a
+         * system uid call indicating "user interacted with Settings" vs "a system app changed
+         * something automatically".
+         */
+        boolean getIsUserAction() {
+            // Approach:
+            //   - if manual rule turned on or off, the calling UID is system, and the new manual
+            //     rule does not have an enabler set, guess that this is likely to be a user action.
+            //     This may represent a system app turning on DND automatically, but we guess "user"
+            //     in this case.
+            //         - note that this has a known failure mode of "manual rule turning off
+            //           automatically after the default time runs out". We currently have no way
+            //           of distinguishing this case from a user manually turning off the rule.
+            //         - the reason for checking the enabler field is that a call may look like it's
+            //           coming from a system UID, but if an enabler is set then the request came
+            //           from an external source. "enabler" will be blank when manual rule is turned
+            //           on from Quick Settings or Settings.
+            //   - if an automatic rule's state changes in whether it is "enabled", then
+            //     that is probably a user action.
+            //   - if an automatic rule goes from "not snoozing" to "snoozing", that is probably
+            //     a user action; that means that the user temporarily turned off DND associated
+            //     with that rule.
+            //   - if an automatic rule becomes active but does *not* change in its enabled state
+            //     (covered by a previous case anyway), we guess that this is an automatic change.
+            //   - if a rule is added or removed and the call comes from the system, we guess that
+            //     this is a user action (as system rules can't be added or removed without a user
+            //     action).
+            switch (getChangedRuleType()) {
+                case RULE_TYPE_MANUAL:
+                    // TODO(b/278888961): Distinguish the automatically-turned-off state
+                    return mFromSystemOrSystemUi && (getNewManualRuleEnabler() == null);
+                case RULE_TYPE_AUTOMATIC:
+                    for (ZenModeDiff.RuleDiff d : getChangedAutomaticRules().values()) {
+                        if (d.wasAdded() || d.wasRemoved()) {
+                            // If the change comes from system, a rule being added/removed indicates
+                            // a likely user action. From an app, it's harder to know for sure.
+                            return mFromSystemOrSystemUi;
+                        }
+                        ZenModeDiff.FieldDiff enabled = d.getDiffForField(
+                                ZenModeDiff.RuleDiff.FIELD_ENABLED);
+                        if (enabled != null && enabled.hasDiff()) {
+                            return true;
+                        }
+                        ZenModeDiff.FieldDiff snoozing = d.getDiffForField(
+                                ZenModeDiff.RuleDiff.FIELD_SNOOZING);
+                        if (snoozing != null && snoozing.hasDiff() && (boolean) snoozing.to()) {
+                            return true;
+                        }
+                    }
+                    // If the change was in an automatic rule and none of the "probably triggered
+                    // by a user" cases apply, then it's probably an automatic change.
+                    return false;
+                case RULE_TYPE_UNKNOWN:
+                default:
+            }
+
+            // If the change wasn't in a rule, but was in the zen policy: consider to be user action
+            // if the calling uid is system
+            if (hasPolicyDiff() || hasChannelsBypassingDiff()) {
+                return mCallingUid == Process.SYSTEM_UID;
+            }
+
+            // don't know, or none of the other things triggered; assume not a user action
+            return false;
+        }
+
+        /**
+         * Get the package UID associated with this change, which is just the calling UID for the
+         * relevant method changes. This may get reset by ZenModeEventLogger, which has access to
+         * a PackageManager to get an appropriate UID for a package.
+         */
+        int getPackageUid() {
+            return mCallingUid;
+        }
+
+        /**
+         * Convert the new policy to a DNDPolicyProto format for output in logs.
+         */
+        byte[] getDNDPolicyProto() {
+            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+            ProtoOutputStream proto = new ProtoOutputStream(bytes);
+
+            // While we don't expect this to be null at any point, guard against any weird cases.
+            if (mNewPolicy != null) {
+                proto.write(DNDPolicyProto.CALLS, toState(mNewPolicy.allowCalls()));
+                proto.write(DNDPolicyProto.REPEAT_CALLERS,
+                        toState(mNewPolicy.allowRepeatCallers()));
+                proto.write(DNDPolicyProto.MESSAGES, toState(mNewPolicy.allowMessages()));
+                proto.write(DNDPolicyProto.CONVERSATIONS, toState(mNewPolicy.allowConversations()));
+                proto.write(DNDPolicyProto.REMINDERS, toState(mNewPolicy.allowReminders()));
+                proto.write(DNDPolicyProto.EVENTS, toState(mNewPolicy.allowEvents()));
+                proto.write(DNDPolicyProto.ALARMS, toState(mNewPolicy.allowAlarms()));
+                proto.write(DNDPolicyProto.MEDIA, toState(mNewPolicy.allowMedia()));
+                proto.write(DNDPolicyProto.SYSTEM, toState(mNewPolicy.allowSystem()));
+
+                proto.write(DNDPolicyProto.FULLSCREEN, toState(mNewPolicy.showFullScreenIntents()));
+                proto.write(DNDPolicyProto.LIGHTS, toState(mNewPolicy.showLights()));
+                proto.write(DNDPolicyProto.PEEK, toState(mNewPolicy.showPeeking()));
+                proto.write(DNDPolicyProto.STATUS_BAR, toState(mNewPolicy.showStatusBarIcons()));
+                proto.write(DNDPolicyProto.BADGE, toState(mNewPolicy.showBadges()));
+                proto.write(DNDPolicyProto.AMBIENT, toState(mNewPolicy.showAmbient()));
+                proto.write(DNDPolicyProto.NOTIFICATION_LIST,
+                        toState(mNewPolicy.showInNotificationList()));
+
+                // Note: The DND policy proto uses the people type enum from *ZenPolicy* and not
+                // *NotificationManager.Policy* (which is the type of the consolidated policy).
+                // This applies to both call and message senders, but not conversation senders,
+                // where they use the same enum values.
+                proto.write(DNDPolicyProto.ALLOW_CALLS_FROM,
+                        ZenModeConfig.getZenPolicySenders(mNewPolicy.allowCallsFrom()));
+                proto.write(DNDPolicyProto.ALLOW_MESSAGES_FROM,
+                        ZenModeConfig.getZenPolicySenders(mNewPolicy.allowMessagesFrom()));
+                proto.write(DNDPolicyProto.ALLOW_CONVERSATIONS_FROM,
+                        mNewPolicy.allowConversationsFrom());
+            } else {
+                Log.wtf(TAG, "attempted to write zen mode log event with null policy");
+            }
+
+            proto.flush();
+            return bytes.toByteArray();
+        }
+
+        /**
+         * Get whether any channels are bypassing DND based on the current new policy.
+         */
+        boolean getAreChannelsBypassing() {
+            if (mNewPolicy != null) {
+                return (mNewPolicy.state & STATE_CHANNELS_BYPASSING_DND) != 0;
+            }
+            return false;
+        }
+
+        private boolean hasChannelsBypassingDiff() {
+            boolean prevChannelsBypassing = mPrevPolicy != null
+                    ? (mPrevPolicy.state & STATE_CHANNELS_BYPASSING_DND) != 0 : false;
+            return prevChannelsBypassing != getAreChannelsBypassing();
+        }
+
+        /**
+         * helper method to turn a boolean allow or disallow state into STATE_ALLOW or
+         * STATE_DISALLOW (there is no concept of "unset" in NM.Policy.)
+         */
+        private int toState(boolean allow) {
+            return allow ? ZenPolicy.STATE_ALLOW : ZenPolicy.STATE_DISALLOW;
+        }
+
+        /**
+         * Get the list of automatic rules that have any diff (as a List of ZenModeDiff.RuleDiff).
+         * Returns an empty list if there isn't anything.
+         */
+        private @NonNull ArrayMap<String, ZenModeDiff.RuleDiff> getChangedAutomaticRules() {
+            ArrayMap<String, ZenModeDiff.RuleDiff> ruleDiffs = new ArrayMap<>();
+
+            ZenModeDiff.ConfigDiff diff = new ZenModeDiff.ConfigDiff(mPrevConfig, mNewConfig);
+            if (!diff.hasDiff()) {
+                return ruleDiffs;
+            }
+
+            ArrayMap<String, ZenModeDiff.RuleDiff> autoDiffs = diff.getAllAutomaticRuleDiffs();
+            if (autoDiffs != null) {
+                return autoDiffs;
+            }
+            return ruleDiffs;
+        }
+
+        /**
+         * Get the package name associated with this rule's owner, given its id and associated
+         * RuleDiff, as well as the user ID associated with the config it was found in. Returns null
+         * if none could be found.
+         */
+        private Pair<String, Integer> getRulePackageAndUser(String id, ZenModeDiff.RuleDiff diff) {
+            // look for the rule info in the new config unless the rule was deleted.
+            ZenModeConfig configForSearch = mNewConfig;
+            if (diff.wasRemoved()) {
+                configForSearch = mPrevConfig;
+            }
+
+            if (configForSearch == null) {
+                return null;
+            }
+
+            ZenModeConfig.ZenRule rule = configForSearch.automaticRules.getOrDefault(id, null);
+            if (rule != null) {
+                if (rule.component != null) {
+                    return new Pair(rule.component.getPackageName(), configForSearch.user);
+                }
+                if (rule.configurationActivity != null) {
+                    return new Pair(rule.configurationActivity.getPackageName(),
+                            configForSearch.user);
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Get the package name listed as the manual rule "enabler", if it exists in the new config.
+         */
+        private String getNewManualRuleEnabler() {
+            if (mNewConfig == null || mNewConfig.manualRule == null) {
+                return null;
+            }
+            return mNewConfig.manualRule.enabler;
+        }
+
+        /**
+         * Makes a copy for storing intermediate state for testing purposes.
+         */
+        protected ZenStateChanges copy() {
+            ZenStateChanges copy = new ZenStateChanges();
+            copy.mPrevZenMode = mPrevZenMode;
+            copy.mNewZenMode = mNewZenMode;
+            copy.mPrevConfig = mPrevConfig.copy();
+            copy.mNewConfig = mNewConfig.copy();
+            copy.mPrevPolicy = mPrevPolicy.copy();
+            copy.mNewPolicy = mNewPolicy.copy();
+            copy.mCallingUid = mCallingUid;
+            copy.mFromSystemOrSystemUi = mFromSystemOrSystemUi;
+            return copy;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index f38c6c1..36a0b0c 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -76,6 +76,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
@@ -125,6 +126,8 @@
     @VisibleForTesting final SparseArray<ZenModeConfig> mConfigs = new SparseArray<>();
     private final Metrics mMetrics = new Metrics();
     private final ConditionProviders.Config mServiceConfig;
+    private SystemUiSystemPropertiesFlags.FlagResolver mFlagResolver;
+    @VisibleForTesting protected ZenModeEventLogger mZenModeEventLogger;
 
     @VisibleForTesting protected int mZenMode;
     @VisibleForTesting protected NotificationManager.Policy mConsolidatedPolicy;
@@ -144,7 +147,9 @@
     private String[] mPriorityOnlyDndExemptPackages;
 
     public ZenModeHelper(Context context, Looper looper, ConditionProviders conditionProviders,
-            SysUiStatsEvent.BuilderFactory statsEventBuilderFactory) {
+            SysUiStatsEvent.BuilderFactory statsEventBuilderFactory,
+            SystemUiSystemPropertiesFlags.FlagResolver flagResolver,
+            ZenModeEventLogger zenModeEventLogger) {
         mContext = context;
         mHandler = new H(looper);
         addCallback(mMetrics);
@@ -165,6 +170,8 @@
         mConditions = new ZenModeConditions(this, conditionProviders);
         mServiceConfig = conditionProviders.getConfig();
         mStatsEventBuilderFactory = statsEventBuilderFactory;
+        mFlagResolver = flagResolver;
+        mZenModeEventLogger = zenModeEventLogger;
     }
 
     public Looper getLooper() {
@@ -214,7 +221,13 @@
 
     public void initZenMode() {
         if (DEBUG) Log.d(TAG, "initZenMode");
-        evaluateZenMode("init", true /*setRingerMode*/);
+        synchronized (mConfig) {
+            // "update" config to itself, which will have no effect in the case where a config
+            // was read in via XML, but will initialize zen mode if nothing was read in and the
+            // config remains the default.
+            updateConfigAndZenModeLocked(mConfig, "init", true /*setRingerMode*/,
+                    Process.SYSTEM_UID /* callingUid */, true /* is system */);
+        }
     }
 
     public void onSystemReady() {
@@ -266,7 +279,7 @@
             config.user = user;
         }
         synchronized (mConfig) {
-            setConfigLocked(config, null, reason);
+            setConfigLocked(config, null, reason, Process.SYSTEM_UID, true);
         }
         cleanUpZenRules();
     }
@@ -275,11 +288,13 @@
         return NotificationManager.zenModeToInterruptionFilter(mZenMode);
     }
 
-    public void requestFromListener(ComponentName name, int filter) {
+    public void requestFromListener(ComponentName name, int filter, int callingUid,
+            boolean fromSystemOrSystemUi) {
         final int newZen = NotificationManager.zenModeFromInterruptionFilter(filter, -1);
         if (newZen != -1) {
             setManualZenMode(newZen, null, name != null ? name.getPackageName() : null,
-                    "listener:" + (name != null ? name.flattenToShortString() : null));
+                    "listener:" + (name != null ? name.flattenToShortString() : null),
+                    callingUid, fromSystemOrSystemUi);
         }
     }
 
@@ -324,7 +339,7 @@
     }
 
     public String addAutomaticZenRule(String pkg, AutomaticZenRule automaticZenRule,
-            String reason) {
+            String reason, int callingUid, boolean fromSystemOrSystemUi) {
         if (!ZenModeConfig.SYSTEM_AUTHORITY.equals(pkg)) {
             PackageItemInfo component = getServiceInfo(automaticZenRule.getOwner());
             if (component == null) {
@@ -360,7 +375,8 @@
             ZenRule rule = new ZenRule();
             populateZenRule(pkg, automaticZenRule, rule, true);
             newConfig.automaticRules.put(rule.id, rule);
-            if (setConfigLocked(newConfig, reason, rule.component, true)) {
+            if (setConfigLocked(newConfig, reason, rule.component, true, callingUid,
+                    fromSystemOrSystemUi)) {
                 return rule.id;
             } else {
                 throw new AndroidRuntimeException("Could not create rule");
@@ -369,7 +385,7 @@
     }
 
     public boolean updateAutomaticZenRule(String ruleId, AutomaticZenRule automaticZenRule,
-            String reason) {
+            String reason, int callingUid, boolean fromSystemOrSystemUi) {
         ZenModeConfig newConfig;
         synchronized (mConfig) {
             if (mConfig == null) return false;
@@ -395,11 +411,13 @@
             }
 
             populateZenRule(rule.pkg, automaticZenRule, rule, false);
-            return setConfigLocked(newConfig, reason, rule.component, true);
+            return setConfigLocked(newConfig, reason, rule.component, true, callingUid,
+                    fromSystemOrSystemUi);
         }
     }
 
-    public boolean removeAutomaticZenRule(String id, String reason) {
+    public boolean removeAutomaticZenRule(String id, String reason, int callingUid,
+            boolean fromSystemOrSystemUi) {
         ZenModeConfig newConfig;
         synchronized (mConfig) {
             if (mConfig == null) return false;
@@ -424,11 +442,13 @@
             }
             dispatchOnAutomaticRuleStatusChanged(
                     mConfig.user, ruleToRemove.getPkg(), id, AUTOMATIC_RULE_STATUS_REMOVED);
-            return setConfigLocked(newConfig, reason, null, true);
+            return setConfigLocked(newConfig, reason, null, true, callingUid,
+                    fromSystemOrSystemUi);
         }
     }
 
-    public boolean removeAutomaticZenRules(String packageName, String reason) {
+    public boolean removeAutomaticZenRules(String packageName, String reason, int callingUid,
+            boolean fromSystemOrSystemUi) {
         ZenModeConfig newConfig;
         synchronized (mConfig) {
             if (mConfig == null) return false;
@@ -439,11 +459,13 @@
                     newConfig.automaticRules.removeAt(i);
                 }
             }
-            return setConfigLocked(newConfig, reason, null, true);
+            return setConfigLocked(newConfig, reason, null, true, callingUid,
+                    fromSystemOrSystemUi);
         }
     }
 
-    public void setAutomaticZenRuleState(String id, Condition condition) {
+    public void setAutomaticZenRuleState(String id, Condition condition, int callingUid,
+            boolean fromSystemOrSystemUi) {
         ZenModeConfig newConfig;
         synchronized (mConfig) {
             if (mConfig == null) return;
@@ -451,11 +473,13 @@
             newConfig = mConfig.copy();
             ArrayList<ZenRule> rules = new ArrayList<>();
             rules.add(newConfig.automaticRules.get(id));
-            setAutomaticZenRuleStateLocked(newConfig, rules, condition);
+            setAutomaticZenRuleStateLocked(newConfig, rules, condition, callingUid,
+                    fromSystemOrSystemUi);
         }
     }
 
-    public void setAutomaticZenRuleState(Uri ruleDefinition, Condition condition) {
+    public void setAutomaticZenRuleState(Uri ruleDefinition, Condition condition, int callingUid,
+            boolean fromSystemOrSystemUi) {
         ZenModeConfig newConfig;
         synchronized (mConfig) {
             if (mConfig == null) return;
@@ -463,18 +487,19 @@
 
             setAutomaticZenRuleStateLocked(newConfig,
                     findMatchingRules(newConfig, ruleDefinition, condition),
-                    condition);
+                    condition, callingUid, fromSystemOrSystemUi);
         }
     }
 
     private void setAutomaticZenRuleStateLocked(ZenModeConfig config, List<ZenRule> rules,
-            Condition condition) {
+            Condition condition, int callingUid, boolean fromSystemOrSystemUi) {
         if (rules == null || rules.isEmpty()) return;
 
         for (ZenRule rule : rules) {
             rule.condition = condition;
             updateSnoozing(rule);
-            setConfigLocked(config, rule.component, "conditionChanged");
+            setConfigLocked(config, rule.component, "conditionChanged", callingUid,
+                    fromSystemOrSystemUi);
         }
     }
 
@@ -561,7 +586,7 @@
         }
     }
 
-    protected void updateDefaultZenRules() {
+    protected void updateDefaultZenRules(int callingUid, boolean fromSystemOrSystemUi) {
         updateDefaultAutomaticRuleNames();
         for (ZenRule defaultRule : mDefaultConfig.automaticRules.values()) {
             ZenRule currRule = mConfig.automaticRules.get(defaultRule.id);
@@ -575,7 +600,7 @@
                     // update default rule (if locale changed, name of rule will change)
                     currRule.name = defaultRule.name;
                     updateAutomaticZenRule(defaultRule.id, createAutomaticZenRule(currRule),
-                            "locale changed");
+                            "locale changed", callingUid, fromSystemOrSystemUi);
                 }
             }
         }
@@ -650,14 +675,16 @@
         return azr;
     }
 
-    public void setManualZenMode(int zenMode, Uri conditionId, String caller, String reason) {
-        setManualZenMode(zenMode, conditionId, reason, caller, true /*setRingerMode*/);
+    public void setManualZenMode(int zenMode, Uri conditionId, String caller, String reason,
+            int callingUid, boolean fromSystemOrSystemUi) {
+        setManualZenMode(zenMode, conditionId, reason, caller, true /*setRingerMode*/, callingUid,
+                fromSystemOrSystemUi);
         Settings.Secure.putInt(mContext.getContentResolver(),
                 Settings.Secure.SHOW_ZEN_SETTINGS_SUGGESTION, 0);
     }
 
     private void setManualZenMode(int zenMode, Uri conditionId, String reason, String caller,
-            boolean setRingerMode) {
+            boolean setRingerMode, int callingUid, boolean fromSystemOrSystemUi) {
         ZenModeConfig newConfig;
         synchronized (mConfig) {
             if (mConfig == null) return;
@@ -681,7 +708,8 @@
                 newRule.enabler = caller;
                 newConfig.manualRule = newRule;
             }
-            setConfigLocked(newConfig, reason, null, setRingerMode);
+            setConfigLocked(newConfig, reason, null, setRingerMode, callingUid,
+                    fromSystemOrSystemUi);
         }
     }
 
@@ -806,7 +834,7 @@
             }
             if (DEBUG) Log.d(TAG, reason);
             synchronized (mConfig) {
-                setConfigLocked(config, null, reason);
+                setConfigLocked(config, null, reason, Process.SYSTEM_UID, true);
             }
         }
     }
@@ -838,12 +866,13 @@
     /**
      * Sets the global notification policy used for priority only do not disturb
      */
-    public void setNotificationPolicy(Policy policy) {
+    public void setNotificationPolicy(Policy policy, int callingUid, boolean fromSystemOrSystemUi) {
         if (policy == null || mConfig == null) return;
         synchronized (mConfig) {
             final ZenModeConfig newConfig = mConfig.copy();
             newConfig.applyNotificationPolicy(policy);
-            setConfigLocked(newConfig, null, "setNotificationPolicy");
+            setConfigLocked(newConfig, null, "setNotificationPolicy", callingUid,
+                    fromSystemOrSystemUi);
         }
     }
 
@@ -868,7 +897,8 @@
                     }
                 }
             }
-            setConfigLocked(newConfig, null, "cleanUpZenRules");
+            setConfigLocked(newConfig, null, "cleanUpZenRules", Process.SYSTEM_UID,
+                    true);
         }
     }
 
@@ -889,18 +919,21 @@
     }
 
     public boolean setConfigLocked(ZenModeConfig config, ComponentName triggeringComponent,
-            String reason) {
-        return setConfigLocked(config, reason, triggeringComponent, true /*setRingerMode*/);
+            String reason, int callingUid, boolean fromSystemOrSystemUi) {
+        return setConfigLocked(config, reason, triggeringComponent, true /*setRingerMode*/,
+                callingUid, fromSystemOrSystemUi);
     }
 
-    public void setConfig(ZenModeConfig config, ComponentName triggeringComponent, String reason) {
+    public void setConfig(ZenModeConfig config, ComponentName triggeringComponent, String reason,
+            int callingUid, boolean fromSystemOrSystemUi) {
         synchronized (mConfig) {
-            setConfigLocked(config, triggeringComponent, reason);
+            setConfigLocked(config, triggeringComponent, reason, callingUid, fromSystemOrSystemUi);
         }
     }
 
     private boolean setConfigLocked(ZenModeConfig config, String reason,
-            ComponentName triggeringComponent, boolean setRingerMode) {
+            ComponentName triggeringComponent, boolean setRingerMode, int callingUid,
+            boolean fromSystemOrSystemUi) {
         final long identity = Binder.clearCallingIdentity();
         try {
             if (config == null || !config.isValid()) {
@@ -927,17 +960,11 @@
             // send some broadcasts
             final boolean policyChanged = !Objects.equals(getNotificationPolicy(mConfig),
                     getNotificationPolicy(config));
-            if (!config.equals(mConfig)) {
-                mConfig = config;
-                dispatchOnConfigChanged();
-                updateConsolidatedPolicy(reason);
-            }
             if (policyChanged) {
                 dispatchOnPolicyChanged();
             }
-            final String val = Integer.toString(config.hashCode());
-            Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_CONFIG_ETAG, val);
-            evaluateZenMode(reason, setRingerMode);
+            updateConfigAndZenModeLocked(config, reason, setRingerMode, callingUid,
+                    fromSystemOrSystemUi);
             mConditions.evaluateConfig(config, triggeringComponent, true /*processSubscriptions*/);
             return true;
         } catch (SecurityException e) {
@@ -948,6 +975,34 @@
         }
     }
 
+    /**
+     * Carries out a config update (if needed) and (re-)evaluates the zen mode value afterwards.
+     * If logging is enabled, will also request logging of the outcome of this change if needed.
+     */
+    private void updateConfigAndZenModeLocked(ZenModeConfig config, String reason,
+            boolean setRingerMode, int callingUid, boolean fromSystemOrSystemUi) {
+        final boolean logZenModeEvents = mFlagResolver.isEnabled(
+                SystemUiSystemPropertiesFlags.NotificationFlags.LOG_DND_STATE_EVENTS);
+        // Store (a copy of) all config and zen mode info prior to any changes taking effect
+        ZenModeEventLogger.ZenModeInfo prevInfo = new ZenModeEventLogger.ZenModeInfo(
+                mZenMode, mConfig, mConsolidatedPolicy);
+        if (!config.equals(mConfig)) {
+            mConfig = config;
+            dispatchOnConfigChanged();
+            updateConsolidatedPolicy(reason);
+        }
+        final String val = Integer.toString(config.hashCode());
+        Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_CONFIG_ETAG, val);
+        evaluateZenMode(reason, setRingerMode);
+        // After all changes have occurred, log if requested
+        if (logZenModeEvents) {
+            ZenModeEventLogger.ZenModeInfo newInfo = new ZenModeEventLogger.ZenModeInfo(
+                    mZenMode, mConfig, mConsolidatedPolicy);
+            mZenModeEventLogger.maybeLogZenChange(prevInfo, newInfo, callingUid,
+                    fromSystemOrSystemUi);
+        }
+    }
+
     private int getZenModeSetting() {
         return Global.getInt(mContext.getContentResolver(), Global.ZEN_MODE, Global.ZEN_MODE_OFF);
     }
@@ -1366,7 +1421,7 @@
 
             if (newZen != -1) {
                 setManualZenMode(newZen, null, "ringerModeInternal", null,
-                        false /*setRingerMode*/);
+                        false /*setRingerMode*/, Process.SYSTEM_UID, true);
             }
             if (isChange || newZen != -1 || ringerModeExternal != ringerModeExternalOut) {
                 ZenLog.traceSetRingerModeInternal(ringerModeOld, ringerModeNew, caller,
@@ -1404,7 +1459,7 @@
             }
             if (newZen != -1) {
                 setManualZenMode(newZen, null, "ringerModeExternal", caller,
-                        false /*setRingerMode*/);
+                        false /*setRingerMode*/, Process.SYSTEM_UID, true);
             }
 
             ZenLog.traceSetRingerModeExternal(ringerModeOld, ringerModeNew, caller,
diff --git a/services/core/java/com/android/server/pm/BackgroundInstallControlService.java b/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
index 0bb05aa..1b34c70 100644
--- a/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
+++ b/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
@@ -231,6 +231,14 @@
             return;
         }
 
+        // the installers without INSTALL_PACKAGES perm can't perform
+        // the installation in background. So we can just filter out them.
+        if (mPermissionManager.checkPermission(installerPackageName,
+                android.Manifest.permission.INSTALL_PACKAGES,
+                userId) != PackageManager.PERMISSION_GRANTED) {
+            return;
+        }
+
         // convert up-time to current time.
         final long installTimestamp = System.currentTimeMillis()
                 - (SystemClock.uptimeMillis() - appInfo.createTimestamp);
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 1aa1fd1..abfc1d7 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -2310,6 +2310,9 @@
         if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
             return false;
         }
+        if ((intent.getFlags() & Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER) != 0) {
+            return false;
+        }
         if (!skipPackageCheck && intent.getPackage() != null) {
             return false;
         }
@@ -2339,6 +2342,11 @@
             Intent intent, List<ResolveInfo> resolvedActivities, int userId,
             boolean skipPackageCheck, @PackageManager.ResolveInfoFlagsBits long flags) {
         final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
+        var debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
+        if (debug) {
+            Slog.d(TAG, "Checking if instant app resolution allowed, resolvedActivities = "
+                    + resolvedActivities);
+        }
         for (int n = 0; n < count; n++) {
             final ResolveInfo info = resolvedActivities.get(n);
             final String packageName = info.activityInfo.packageName;
@@ -2362,6 +2370,8 @@
                     }
                     return false;
                 }
+            } else if (debug) {
+                Slog.d(TAG, "Could not find package " + packageName);
             }
         }
         // We've exhausted all ways to deny ephemeral application; let the system look for them.
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
index a610b5b..5f28e56 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 package com.android.server.pm;
+
 import static android.Manifest.permission.CONFIGURE_INTERACT_ACROSS_PROFILES;
 import static android.Manifest.permission.INTERACT_ACROSS_PROFILES;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
@@ -147,7 +148,7 @@
         if (launchMainActivity) {
             launchIntent.setAction(Intent.ACTION_MAIN);
             launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-            if (targetTask == null) {
+            if (targetTask == null || options != null) {
                 launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                         | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
             } else {
@@ -333,9 +334,10 @@
     }
 
     private boolean isCrossProfilePackageAllowlisted(String packageName) {
+        int userId = mInjector.getCallingUserId();
         return mInjector.withCleanCallingIdentity(() ->
                 mInjector.getDevicePolicyManagerInternal()
-                        .getAllCrossProfilePackages().contains(packageName));
+                        .getAllCrossProfilePackages(userId).contains(packageName));
     }
 
     private boolean isCrossProfilePackageAllowlistedByDefault(String packageName) {
diff --git a/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java b/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
index 8a28888..5b3f7a5 100644
--- a/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
+++ b/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
@@ -382,7 +382,11 @@
         return filters;
     }
 
-    /** Call intent with tel scheme exclusively handled my managed profile. */
+    /** Call intent with tel scheme exclusively handled my managed profile.
+     * Note that work profile telephony relies on this intent filter to redirect intents to
+     * the IntentForwarderActivity. Work profile telephony error handling must be updated in
+     * the Telecomm package CallsManager if this filter is changed.
+     */
     private static final DefaultCrossProfileIntentFilter CALL_MANAGED_PROFILE =
             new DefaultCrossProfileIntentFilter.Builder(
                     DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 5979b12e..06db5be 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -280,7 +280,7 @@
             SharedUserSetting requestSharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(
                     request.getScanRequestPackageSetting());
             SharedUserSetting resultSharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(
-                    request.getScanRequestPackageSetting());
+                    request.getScannedPackageSetting());
             if (requestSharedUserSetting != null
                     && requestSharedUserSetting != resultSharedUserSetting) {
                 // shared user changed, remove from old shared user
@@ -324,7 +324,6 @@
         InstallSource installSource = request.getInstallSource();
         final boolean isApex = (scanFlags & SCAN_AS_APEX) != 0;
         final boolean pkgAlreadyExists = oldPkgSetting != null;
-        final boolean isAllowUpdateOwnership = parsedPackage.isAllowUpdateOwnership();
         final String oldUpdateOwner =
                 pkgAlreadyExists ? oldPkgSetting.getInstallSource().mUpdateOwnerPackageName : null;
         final String updateOwnerFromSysconfig = isApex || !pkgSetting.isSystem() ? null
@@ -346,11 +345,7 @@
             }
 
             // Handle the update ownership enforcement for APK
-            if (!isAllowUpdateOwnership) {
-                // If the app wants to opt-out of the update ownership enforcement via manifest,
-                // it overrides the installer's use of #setRequestUpdateOwnership.
-                installSource = installSource.setUpdateOwnerPackageName(null);
-            } else if (!isApex) {
+            if (!isApex) {
                 // User installer UID as "current" userId if present; otherwise, use the userId
                 // from InstallRequest.
                 final int userId = installSource.mInstallerPackageUid != Process.INVALID_UID
@@ -391,22 +386,18 @@
         // For non-standard install (addForInit), installSource is null.
         } else if (pkgSetting.isSystem()) {
             // We still honor the manifest attr if the system app wants to opt-out of it.
-            if (!isAllowUpdateOwnership) {
-                pkgSetting.setUpdateOwnerPackage(null);
-            } else {
-                final boolean isSameUpdateOwner = isUpdateOwnershipEnabled
-                        && TextUtils.equals(oldUpdateOwner, updateOwnerFromSysconfig);
+            final boolean isSameUpdateOwner = isUpdateOwnershipEnabled
+                    && TextUtils.equals(oldUpdateOwner, updateOwnerFromSysconfig);
 
-                // Here we handle the update owner for the system package, and the rules are:
-                // -. We use the update owner from sysconfig as the initial value.
-                // -. Once an app becomes to system app later via OTA, only retains the update
-                //    owner if it's consistence with sysconfig.
-                // -. Clear the update owner when update owner changes from sysconfig.
-                if (!pkgAlreadyExists || isSameUpdateOwner) {
-                    pkgSetting.setUpdateOwnerPackage(updateOwnerFromSysconfig);
-                } else {
-                    pkgSetting.setUpdateOwnerPackage(null);
-                }
+            // Here we handle the update owner for the system package, and the rules are:
+            // -. We use the update owner from sysconfig as the initial value.
+            // -. Once an app becomes to system app later via OTA, only retains the update
+            //    owner if it's consistence with sysconfig.
+            // -. Clear the update owner when update owner changes from sysconfig.
+            if (!pkgAlreadyExists || isSameUpdateOwner) {
+                pkgSetting.setUpdateOwnerPackage(updateOwnerFromSysconfig);
+            } else {
+                pkgSetting.setUpdateOwnerPackage(null);
             }
         }
 
@@ -606,8 +597,8 @@
         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
     }
 
-    public int installExistingPackageAsUser(@Nullable String packageName, @UserIdInt int userId,
-            @PackageManager.InstallFlags int installFlags,
+    public Pair<Integer, IntentSender> installExistingPackageAsUser(@Nullable String packageName,
+            @UserIdInt int userId, @PackageManager.InstallFlags int installFlags,
             @PackageManager.InstallReason int installReason,
             @Nullable List<String> allowlistedRestrictedPermissions,
             @Nullable IntentSender intentSender) {
@@ -632,7 +623,7 @@
                 true /* requireFullPermission */, true /* checkShell */,
                 "installExistingPackage for user " + userId);
         if (mPm.isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
-            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
+            return Pair.create(PackageManager.INSTALL_FAILED_USER_RESTRICTED, intentSender);
         }
 
         final long callingId = Binder.clearCallingIdentity();
@@ -648,7 +639,7 @@
                 final Computer snapshot = mPm.snapshotComputer();
                 pkgSetting = mPm.mSettings.getPackageLPr(packageName);
                 if (pkgSetting == null || pkgSetting.getPkg() == null) {
-                    return PackageManager.INSTALL_FAILED_INVALID_URI;
+                    return Pair.create(PackageManager.INSTALL_FAILED_INVALID_URI, intentSender);
                 }
                 if (!snapshot.canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
                     // only allow the existing package to be used if it's installed as a full
@@ -661,7 +652,7 @@
                         }
                     }
                     if (!installAllowed) {
-                        return PackageManager.INSTALL_FAILED_INVALID_URI;
+                        return Pair.create(PackageManager.INSTALL_FAILED_INVALID_URI, intentSender);
                     }
                 }
                 if (!pkgSetting.getInstalled(userId)) {
@@ -719,14 +710,17 @@
                 }
                 // start async restore with no post-install since we finish install here
 
+                final IntentSender onCompleteSender = intentSender;
+                intentSender = null;
+
                 InstallRequest request = new InstallRequest(userId,
                         PackageManager.INSTALL_SUCCEEDED, pkgSetting.getPkg(), new int[]{ userId },
                         () -> {
                             mPm.restorePermissionsAndUpdateRolesForNewUserInstall(packageName,
                                     userId);
-                            if (intentSender != null) {
-                                onRestoreComplete(PackageManager.INSTALL_SUCCEEDED, mContext,
-                                        intentSender);
+                            if (onCompleteSender != null) {
+                                onInstallComplete(PackageManager.INSTALL_SUCCEEDED, mContext,
+                                        onCompleteSender);
                             }
                         });
                 restoreAndPostInstall(request);
@@ -735,10 +729,10 @@
             Binder.restoreCallingIdentity(callingId);
         }
 
-        return PackageManager.INSTALL_SUCCEEDED;
+        return Pair.create(PackageManager.INSTALL_SUCCEEDED, intentSender);
     }
 
-    private static void onRestoreComplete(int returnCode, Context context, IntentSender target) {
+    static void onInstallComplete(int returnCode, Context context, IntentSender target) {
         Intent fillIn = new Intent();
         fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
                 PackageManager.installStatusToPublicStatus(returnCode));
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 0bd6dff..ae169318 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -2021,7 +2021,7 @@
                         }
                         // Each launcher has a different set of pinned shortcuts, so we need to do a
                         // query in here.
-                        // (As of now, only one launcher has the permission at a time, so it's bit
+                        // (As of now, only one launcher has the permission at a time, so it's a bit
                         // moot, but we may change the permission model eventually.)
                         final List<ShortcutInfo> list =
                                 mShortcutServiceInternal.getShortcuts(launcherUserId,
diff --git a/services/core/java/com/android/server/pm/NoFilteringResolver.java b/services/core/java/com/android/server/pm/NoFilteringResolver.java
index ccd5b0e..b87256d 100644
--- a/services/core/java/com/android/server/pm/NoFilteringResolver.java
+++ b/services/core/java/com/android/server/pm/NoFilteringResolver.java
@@ -60,15 +60,9 @@
     public static boolean isIntentRedirectionAllowed(Context context,
             AppCloningDeviceConfigHelper appCloningDeviceConfigHelper, boolean resolveForStart,
             long flags) {
-        final long token = Binder.clearCallingIdentity();
-        try {
-            return  context.getResources().getBoolean(R.bool.config_enableAppCloningBuildingBlocks)
-                    && appCloningDeviceConfigHelper.getEnableAppCloningBuildingBlocks()
+        return isAppCloningBuildingBlocksEnabled(context, appCloningDeviceConfigHelper)
                     && (resolveForStart || (((flags & PackageManager.MATCH_CLONE_PROFILE) != 0)
                     && hasPermission(context, Manifest.permission.QUERY_CLONED_APPS)));
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
     }
 
     public NoFilteringResolver(ComponentResolverApi componentResolver,
@@ -146,4 +140,18 @@
         return context.checkCallingOrSelfPermission(permission)
                 == PackageManager.PERMISSION_GRANTED;
     }
+
+    /**
+     * Checks if the AppCloningBuildingBlocks flag is enabled.
+     */
+    private static boolean isAppCloningBuildingBlocksEnabled(Context context,
+            AppCloningDeviceConfigHelper appCloningDeviceConfigHelper) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return context.getResources().getBoolean(R.bool.config_enableAppCloningBuildingBlocks)
+                    && appCloningDeviceConfigHelper.getEnableAppCloningBuildingBlocks();
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 1641d61..6491fd1 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -1293,8 +1293,15 @@
     public void installExistingPackage(String packageName, int installFlags, int installReason,
             IntentSender statusReceiver, int userId, List<String> allowListedPermissions) {
         final InstallPackageHelper installPackageHelper = new InstallPackageHelper(mPm);
-        installPackageHelper.installExistingPackageAsUser(packageName, userId, installFlags,
-                installReason, allowListedPermissions, statusReceiver);
+
+        var result = installPackageHelper.installExistingPackageAsUser(packageName, userId,
+                installFlags, installReason, allowListedPermissions, statusReceiver);
+
+        int returnCode = result.first;
+        IntentSender onCompleteSender = result.second;
+        if (onCompleteSender != null) {
+            InstallPackageHelper.onInstallComplete(returnCode, mContext, onCompleteSender);
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index d3f7002..f0e3895 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -745,9 +745,6 @@
     @GuardedBy("mLock")
     private int mValidatedTargetSdk = INVALID_TARGET_SDK_VERSION;
 
-    @GuardedBy("mLock")
-    private boolean mAllowsUpdateOwnership = true;
-
     private static final FileFilter sAddedApkFilter = new FileFilter() {
         @Override
         public boolean accept(File file) {
@@ -869,11 +866,13 @@
 
     private static final int USER_ACTION_NOT_NEEDED = 0;
     private static final int USER_ACTION_REQUIRED = 1;
+    private static final int USER_ACTION_PENDING_APK_PARSING = 2;
     private static final int USER_ACTION_REQUIRED_UPDATE_OWNER_REMINDER = 3;
 
     @IntDef({
             USER_ACTION_NOT_NEEDED,
             USER_ACTION_REQUIRED,
+            USER_ACTION_PENDING_APK_PARSING,
             USER_ACTION_REQUIRED_UPDATE_OWNER_REMINDER,
     })
     @interface UserActionRequirement {}
@@ -964,11 +963,11 @@
                 && !isApexSession()
                 && !isUpdateOwner
                 && !isInstallerShell
-                && mAllowsUpdateOwnership
                 // We don't enforce the update ownership for the managed user and profile.
                 && !isFromManagedUserOrProfile) {
             return USER_ACTION_REQUIRED_UPDATE_OWNER_REMINDER;
         }
+
         if (isPermissionGranted) {
             return USER_ACTION_NOT_NEEDED;
         }
@@ -983,20 +982,7 @@
                 && isUpdateWithoutUserActionPermissionGranted
                 && ((isUpdateOwnershipEnforcementEnabled ? isUpdateOwner
                 : isInstallerOfRecord) || isSelfUpdate)) {
-            if (!isApexSession()) {
-                if (!isTargetSdkConditionSatisfied(this)) {
-                    return USER_ACTION_REQUIRED;
-                }
-
-                if (!mSilentUpdatePolicy.isSilentUpdateAllowed(
-                        getInstallerPackageName(), getPackageName())) {
-                    // Fall back to the non-silent update if a repeated installation is invoked
-                    // within the throttle time.
-                    return USER_ACTION_REQUIRED;
-                }
-                mSilentUpdatePolicy.track(getInstallerPackageName(), getPackageName());
-                return USER_ACTION_NOT_NEEDED;
-            }
+            return USER_ACTION_PENDING_APK_PARSING;
         }
 
         return USER_ACTION_REQUIRED;
@@ -2404,6 +2390,26 @@
             session.sendPendingUserActionIntent(target);
             return true;
         }
+
+        if (!session.isApexSession() && userActionRequirement == USER_ACTION_PENDING_APK_PARSING) {
+            if (!isTargetSdkConditionSatisfied(session)) {
+                session.sendPendingUserActionIntent(target);
+                return true;
+            }
+
+            if (session.params.requireUserAction == SessionParams.USER_ACTION_NOT_REQUIRED) {
+                if (!session.mSilentUpdatePolicy.isSilentUpdateAllowed(
+                        session.getInstallerPackageName(), session.getPackageName())) {
+                    // Fall back to the non-silent update if a repeated installation is invoked
+                    // within the throttle time.
+                    session.sendPendingUserActionIntent(target);
+                    return true;
+                }
+                session.mSilentUpdatePolicy.track(session.getInstallerPackageName(),
+                        session.getPackageName());
+            }
+        }
+
         return false;
     }
 
@@ -3409,8 +3415,6 @@
         // {@link PackageLite#getTargetSdk()}
         mValidatedTargetSdk = packageLite.getTargetSdk();
 
-        mAllowsUpdateOwnership = packageLite.isAllowUpdateOwnership();
-
         return packageLite;
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 0c52bb5..bba8043 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -279,6 +279,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
@@ -5350,7 +5351,7 @@
         public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
                 int installReason, List<String> whiteListedPermissions) {
             return mInstallPackageHelper.installExistingPackageAsUser(packageName, userId, installFlags,
-                    installReason, whiteListedPermissions, null);
+                    installReason, whiteListedPermissions, null).first;
         }
 
         @Override
@@ -6295,6 +6296,36 @@
             }
         }
 
+        /**
+         * Wait for the handler to finish handling all pending messages.
+         * @param timeoutMillis Maximum time in milliseconds to wait.
+         * @param forBackgroundHandler Whether to wait for the background handler instead.
+         * @return True if all the waiting messages in the handler has been handled.
+         *         False if timeout.
+         */
+        @Override
+        public boolean waitForHandler(long timeoutMillis, boolean forBackgroundHandler) {
+            final CountDownLatch latch = new CountDownLatch(1);
+            if (forBackgroundHandler) {
+                mBackgroundHandler.post(latch::countDown);
+            } else {
+                mHandler.post(latch::countDown);
+            }
+            final long endTimeMillis = System.currentTimeMillis() + timeoutMillis;
+            while (latch.getCount() > 0) {
+                try {
+                    final long remainingTimeMillis = endTimeMillis - System.currentTimeMillis();
+                    if (remainingTimeMillis <= 0) {
+                        return false;
+                    }
+                    return latch.await(remainingTimeMillis, TimeUnit.MILLISECONDS);
+                } catch (InterruptedException e) {
+                    // ignore and retry
+                }
+            }
+            return true;
+        }
+
         @Override
         public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
                 throws RemoteException {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index d3f3a69..e1f010f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -354,6 +354,10 @@
                     return runSetSilentUpdatesPolicy();
                 case "get-app-metadata":
                     return runGetAppMetadata();
+                case "wait-for-handler":
+                    return runWaitForHandler(/* forBackgroundHandler= */ false);
+                case "wait-for-background-handler":
+                    return runWaitForHandler(/* forBackgroundHandler= */ true);
                 default: {
                     if (ART_SERVICE_COMMANDS.contains(cmd)) {
                         if (DexOptHelper.useArtService()) {
@@ -698,7 +702,7 @@
                         null /* usesSplitNames */, null /* configForSplit */,
                         null /* splitApkPaths */, null /* splitRevisionCodes */,
                         apkLite.getTargetSdkVersion(), null /* requiredSplitTypes */,
-                        null /* splitTypes */, apkLite.isAllowUpdateOwnership());
+                        null /* splitTypes */);
                 sessionSize += InstallLocationUtils.calculateInstalledSize(pkgLite,
                         params.sessionParams.abiOverride, fd.getFileDescriptor());
             } catch (IOException e) {
@@ -3601,6 +3605,40 @@
         return 1;
     }
 
+    private int runWaitForHandler(boolean forBackgroundHandler) {
+        final PrintWriter pw = getOutPrintWriter();
+        long timeoutMillis = 60000; // default timeout is 60 seconds
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "--timeout":
+                    timeoutMillis = Long.parseLong(getNextArgRequired());
+                    break;
+                default:
+                    pw.println("Error: Unknown option: " + opt);
+                    return -1;
+            }
+        }
+        if (timeoutMillis <= 0) {
+            pw.println("Error: --timeout value must be positive: " + timeoutMillis);
+            return -1;
+        }
+        final boolean success;
+        try {
+            success = mInterface.waitForHandler(timeoutMillis, forBackgroundHandler);
+        } catch (RemoteException e) {
+            pw.println("Failure [" + e.getClass().getName() + " - " + e.getMessage() + "]");
+            return -1;
+        }
+        if (success) {
+            pw.println("Success");
+            return 0;
+        } else {
+            pw.println("Timeout. PackageManager handlers are still busy.");
+            return -1;
+        }
+    }
+
     private int runArtServiceCommand() {
         try (var in = ParcelFileDescriptor.dup(getInFileDescriptor());
                 var out = ParcelFileDescriptor.dup(getOutFileDescriptor());
@@ -4427,6 +4465,18 @@
         pw.println("      --reset: restore the installer and throttle time to the default, and");
         pw.println("        clear tracks of silent updates in the system.");
         pw.println("");
+        pw.println("  wait-for-handler --timeout <MILLIS>");
+        pw.println("    Wait for a given amount of time till the package manager handler finishes");
+        pw.println("    handling all pending messages.");
+        pw.println("      --timeout: wait for a given number of milliseconds. If the handler(s)");
+        pw.println("        fail to finish before the timeout, the command returns error.");
+        pw.println("");
+        pw.println("  wait-for-background-handler --timeout <MILLIS>");
+        pw.println("    Wait for a given amount of time till the package manager's background");
+        pw.println("    handler finishes handling all pending messages.");
+        pw.println("      --timeout: wait for a given number of milliseconds. If the handler(s)");
+        pw.println("        fail to finish before the timeout, the command returns error.");
+        pw.println("");
         if (DexOptHelper.useArtService()) {
             printArtServiceHelp();
         } else {
diff --git a/services/core/java/com/android/server/pm/UserJourneyLogger.java b/services/core/java/com/android/server/pm/UserJourneyLogger.java
index f48a166..895edce 100644
--- a/services/core/java/com/android/server/pm/UserJourneyLogger.java
+++ b/services/core/java/com/android/server/pm/UserJourneyLogger.java
@@ -99,6 +99,8 @@
             FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__GRANT_ADMIN;
     public static final int USER_JOURNEY_REVOKE_ADMIN =
             FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__REVOKE_ADMIN;
+    public static final int USER_JOURNEY_USER_LIFECYCLE =
+            FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__USER_LIFECYCLE;
 
     @IntDef(prefix = {"USER_JOURNEY"}, value = {
             USER_JOURNEY_UNKNOWN,
@@ -109,7 +111,8 @@
             USER_JOURNEY_USER_CREATE,
             USER_JOURNEY_USER_REMOVE,
             USER_JOURNEY_GRANT_ADMIN,
-            USER_JOURNEY_REVOKE_ADMIN
+            USER_JOURNEY_REVOKE_ADMIN,
+            USER_JOURNEY_USER_LIFECYCLE
     })
     public @interface UserJourney {
     }
@@ -272,11 +275,12 @@
             int userType, int userFlags, @UserJourneyErrorCode int errorCode) {
         if (session == null) {
             writeUserLifecycleJourneyReported(-1, journey, originalUserId, targetUserId,
-                    userType, userFlags, ERROR_CODE_INVALID_SESSION_ID);
+                    userType, userFlags, ERROR_CODE_INVALID_SESSION_ID, -1);
         } else {
+            final long elapsedTime = System.currentTimeMillis() - session.mStartTimeInMills;
             writeUserLifecycleJourneyReported(
                     session.mSessionId, journey, originalUserId, targetUserId, userType, userFlags,
-                    errorCode);
+                    errorCode, elapsedTime);
         }
     }
 
@@ -285,10 +289,10 @@
      */
     @VisibleForTesting
     public void writeUserLifecycleJourneyReported(long sessionId, int journey, int originalUserId,
-            int targetUserId, int userType, int userFlags, int errorCode) {
+            int targetUserId, int userType, int userFlags, int errorCode, long elapsedTime) {
         FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED,
                 sessionId, journey, originalUserId, targetUserId, userType, userFlags,
-                errorCode);
+                errorCode, elapsedTime);
     }
 
     /**
@@ -452,6 +456,29 @@
     }
 
     /**
+     * Log user journey event and report finishing with error
+     */
+    public UserJourneySession logDelayedUserJourneyFinishWithError(@UserIdInt int originalUserId,
+            UserInfo targetUser, @UserJourney int journey, @UserJourneyErrorCode int errorCode) {
+        synchronized (mLock) {
+            final int key = getUserJourneyKey(targetUser.id, journey);
+            final UserJourneySession userJourneySession = mUserIdToUserJourneyMap.get(key);
+            if (userJourneySession != null) {
+                logUserLifecycleJourneyReported(
+                        userJourneySession,
+                        journey, originalUserId, targetUser.id,
+                        getUserTypeForStatsd(targetUser.userType),
+                        targetUser.flags,
+                        errorCode);
+                mUserIdToUserJourneyMap.remove(key);
+
+                return userJourneySession;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Log event and report finish when user is null. This is edge case when UserInfo
      * can not be passed because it is null, therefore all information are passed as arguments.
      */
@@ -533,6 +560,23 @@
     }
 
     /**
+     * This keeps the start time when finishing extensively long journey was began.
+     * For instance full user lifecycle ( from creation to deletion )when user is about to delete
+     * we need to get user creation time before it was deleted.
+     */
+    public UserJourneySession startSessionForDelayedJourney(@UserIdInt int targetId,
+            @UserJourney int journey, long startTime) {
+        final long newSessionId = ThreadLocalRandom.current().nextLong(1, Long.MAX_VALUE);
+        synchronized (mLock) {
+            final int key = getUserJourneyKey(targetId, journey);
+            final UserJourneySession userJourneySession =
+                    new UserJourneySession(newSessionId, journey, startTime);
+            mUserIdToUserJourneyMap.append(key, userJourneySession);
+            return userJourneySession;
+        }
+    }
+
+    /**
      * Helper class to store user journey and session id.
      *
      * <p> User journey tracks a chain of user lifecycle events occurring during different user
@@ -542,11 +586,19 @@
         public final long mSessionId;
         @UserJourney
         public final int mJourney;
+        public long mStartTimeInMills;
 
         @VisibleForTesting
         public UserJourneySession(long sessionId, @UserJourney int journey) {
             mJourney = journey;
             mSessionId = sessionId;
+            mStartTimeInMills = System.currentTimeMillis();
+        }
+        @VisibleForTesting
+        public UserJourneySession(long sessionId, @UserJourney int journey, long startTimeInMills) {
+            mJourney = journey;
+            mSessionId = sessionId;
+            mStartTimeInMills = startTimeInMills;
         }
     }
-}
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 4ef68d8..7e88e13 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -30,6 +30,7 @@
 import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_GRANT_ADMIN;
 import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_REVOKE_ADMIN;
 import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_CREATE;
+import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_LIFECYCLE;
 import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_REMOVE;
 
 import android.Manifest;
@@ -2853,9 +2854,8 @@
                     UserHandle.USER_NULL, UserManager.RESTRICTION_SOURCE_SYSTEM));
         }
 
-        synchronized (mRestrictionsLock) {
-            result.addAll(mDevicePolicyUserRestrictions.getEnforcingUsers(restrictionKey, userId));
-        }
+        result.addAll(getDevicePolicyManagerInternal()
+                .getUserRestrictionSources(restrictionKey, userId));
         return result;
     }
 
@@ -3332,7 +3332,7 @@
     }
 
     /**
-    * Enforces that only the system UID or root's UID or apps that have the
+     * Enforces that only the system UID or root's UID or apps that have the
      * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or
      * {@link android.Manifest.permission#QUERY_USERS QUERY_USERS}
      * can make certain calls to the UserManager.
@@ -5535,6 +5535,8 @@
             }
 
             mUserJourneyLogger.logUserJourneyBegin(userId, USER_JOURNEY_USER_REMOVE);
+            mUserJourneyLogger.startSessionForDelayedJourney(userId,
+                    USER_JOURNEY_USER_LIFECYCLE, userData.info.creationTime);
 
             try {
                 mAppOpsService.removeUser(userId);
@@ -5560,6 +5562,10 @@
                                 mUserJourneyLogger.logUserJourneyFinishWithError(originUserId,
                                         userData.info, USER_JOURNEY_USER_REMOVE,
                                         ERROR_CODE_UNSPECIFIED);
+                                mUserJourneyLogger
+                                        .logDelayedUserJourneyFinishWithError(originUserId,
+                                                userData.info, USER_JOURNEY_USER_LIFECYCLE,
+                                                ERROR_CODE_UNSPECIFIED);
                             }
                             @Override
                             public void userStopAborted(int userIdParam) {
@@ -5567,6 +5573,10 @@
                                 mUserJourneyLogger.logUserJourneyFinishWithError(originUserId,
                                         userData.info, USER_JOURNEY_USER_REMOVE,
                                         ERROR_CODE_ABORTED);
+                                mUserJourneyLogger
+                                        .logDelayedUserJourneyFinishWithError(originUserId,
+                                                userData.info, USER_JOURNEY_USER_LIFECYCLE,
+                                                ERROR_CODE_ABORTED);
                             }
                         });
             } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 6032fec..8815834 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -238,6 +238,7 @@
                     UserManager.DISALLOW_CONFIG_DATE_TIME,
                     UserManager.DISALLOW_CONFIG_PRIVATE_DNS,
                     UserManager.DISALLOW_CHANGE_WIFI_STATE,
+                    UserManager.DISALLOW_DEBUGGING_FEATURES,
                     UserManager.DISALLOW_WIFI_TETHERING,
                     UserManager.DISALLOW_WIFI_DIRECT,
                     UserManager.DISALLOW_ADD_WIFI_CONFIG,
diff --git a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
index de31b46..f036835 100644
--- a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
+++ b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
@@ -1810,11 +1810,6 @@
     }
 
     @Override
-    public boolean isAllowUpdateOwnership() {
-        return getBoolean2(Booleans2.ALLOW_UPDATE_OWNERSHIP);
-    }
-
-    @Override
     public boolean isVmSafeMode() {
         return getBoolean(Booleans.VM_SAFE_MODE);
     }
@@ -2518,11 +2513,6 @@
     }
 
     @Override
-    public PackageImpl setAllowUpdateOwnership(boolean value) {
-        return setBoolean2(Booleans2.ALLOW_UPDATE_OWNERSHIP, value);
-    }
-
-    @Override
     public PackageImpl sortActivities() {
         Collections.sort(this.activities, ORDER_COMPARATOR);
         return this;
@@ -3736,6 +3726,5 @@
 
         private static final long STUB = 1L;
         private static final long APEX = 1L << 1;
-        private static final long ALLOW_UPDATE_OWNERSHIP = 1L << 2;
     }
 }
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 4d2b119..9510529 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -216,6 +216,7 @@
         STORAGE_PERMISSIONS.add(Manifest.permission.READ_MEDIA_AUDIO);
         STORAGE_PERMISSIONS.add(Manifest.permission.READ_MEDIA_VIDEO);
         STORAGE_PERMISSIONS.add(Manifest.permission.READ_MEDIA_IMAGES);
+        STORAGE_PERMISSIONS.add(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED);
     }
 
     private static final Set<String> NEARBY_DEVICES_PERMISSIONS = new ArraySet<>();
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index f41d964..3e7ae33 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -2810,29 +2810,55 @@
                                 + pkg.getPackageName());
                     }
 
-                    if ((bp.isNormal() && shouldGrantNormalPermission)
-                            || (bp.isSignature()
-                                    && (!bp.isPrivileged() || CollectionUtils.contains(
-                                            isPrivilegedPermissionAllowlisted, permName))
-                                    && (CollectionUtils.contains(shouldGrantSignaturePermission,
-                                            permName)
-                                            || (((bp.isPrivileged() && CollectionUtils.contains(
-                                                    shouldGrantPrivilegedPermissionIfWasGranted,
-                                                    permName)) || bp.isDevelopment() || bp.isRole())
-                                                    && origState.isPermissionGranted(permName))))
-                            || (bp.isInternal()
-                                    && (!bp.isPrivileged() || CollectionUtils.contains(
-                                            isPrivilegedPermissionAllowlisted, permName))
-                                    && (CollectionUtils.contains(shouldGrantInternalPermission,
-                                            permName)
-                                            || (((bp.isPrivileged() && CollectionUtils.contains(
-                                                    shouldGrantPrivilegedPermissionIfWasGranted,
-                                                    permName)) || bp.isDevelopment() || bp.isRole())
-                                                    && origState.isPermissionGranted(permName))))) {
-                        // Grant an install permission.
-                        if (uidState.grantPermission(bp)) {
-                            installPermissionsChangedForUser = true;
+                    if (bp.isNormal() || bp.isSignature() || bp.isInternal()) {
+                        if ((bp.isNormal() && shouldGrantNormalPermission)
+                                || (bp.isSignature()
+                                        && (!bp.isPrivileged() || CollectionUtils.contains(
+                                                isPrivilegedPermissionAllowlisted, permName))
+                                        && (CollectionUtils.contains(shouldGrantSignaturePermission,
+                                                permName)
+                                                || (((bp.isPrivileged() && CollectionUtils.contains(
+                                                        shouldGrantPrivilegedPermissionIfWasGranted,
+                                                        permName)) || bp.isDevelopment()
+                                                                || bp.isRole())
+                                                        && origState.isPermissionGranted(
+                                                                permName))))
+                                || (bp.isInternal()
+                                        && (!bp.isPrivileged() || CollectionUtils.contains(
+                                                isPrivilegedPermissionAllowlisted, permName))
+                                        && (CollectionUtils.contains(shouldGrantInternalPermission,
+                                                permName)
+                                                || (((bp.isPrivileged() && CollectionUtils.contains(
+                                                        shouldGrantPrivilegedPermissionIfWasGranted,
+                                                        permName)) || bp.isDevelopment()
+                                                                || bp.isRole())
+                                                        && origState.isPermissionGranted(
+                                                                permName))))) {
+                            // Grant an install permission.
+                            if (uidState.grantPermission(bp)) {
+                                installPermissionsChangedForUser = true;
+                            }
+                        } else {
+                            if (DEBUG_PERMISSIONS) {
+                                boolean wasGranted = uidState.isPermissionGranted(bp.getName());
+                                if (wasGranted || bp.isAppOp()) {
+                                    Slog.i(TAG, (wasGranted ? "Un-granting" : "Not granting")
+                                            + " permission " + perm
+                                            + " from package " + friendlyName
+                                            + " (protectionLevel=" + bp.getProtectionLevel()
+                                            + " flags=0x"
+                                            + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg,
+                                            ps))
+                                            + ")");
+                                }
+                            }
+                            if (uidState.revokePermission(bp)) {
+                                installPermissionsChangedForUser = true;
+                            }
                         }
+                        PermissionState origPermState = origState.getPermissionState(perm);
+                        int flags = origPermState != null ? origPermState.getFlags() : 0;
+                        uidState.updatePermissionFlags(bp, MASK_PERMISSION_FLAGS_ALL, flags);
                     } else if (bp.isRuntime()) {
                         boolean hardRestricted = bp.isHardRestricted();
                         boolean softRestricted = bp.isSoftRestricted();
@@ -2956,22 +2982,8 @@
                         uidState.updatePermissionFlags(bp, MASK_PERMISSION_FLAGS_ALL,
                                 flags);
                     } else {
-                        if (DEBUG_PERMISSIONS) {
-                            boolean wasGranted = uidState.isPermissionGranted(bp.getName());
-                            if (wasGranted || bp.isAppOp()) {
-                                Slog.i(TAG, (wasGranted ? "Un-granting" : "Not granting")
-                                        + " permission " + perm
-                                        + " from package " + friendlyName
-                                        + " (protectionLevel=" + bp.getProtectionLevel()
-                                        + " flags=0x"
-                                        + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg,
-                                                ps))
-                                        + ")");
-                            }
-                        }
-                        if (uidState.removePermissionState(bp.getName())) {
-                            installPermissionsChangedForUser = true;
-                        }
+                        Slog.wtf(LOG_TAG, "Unknown permission protection " + bp.getProtection()
+                                + " for permission " + bp.getName());
                     }
                 }
 
diff --git a/services/core/java/com/android/server/pm/pkg/AndroidPackage.java b/services/core/java/com/android/server/pm/pkg/AndroidPackage.java
index 2fdda12..e54f34d 100644
--- a/services/core/java/com/android/server/pm/pkg/AndroidPackage.java
+++ b/services/core/java/com/android/server/pm/pkg/AndroidPackage.java
@@ -1483,10 +1483,4 @@
      * @hide
      */
     boolean isVisibleToInstantApps();
-
-    /**
-     * @see R.styleable#AndroidManifest_allowUpdateOwnership
-     * @hide
-     */
-    boolean isAllowUpdateOwnership();
 }
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
index 6cb6a97..7fc3356 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
@@ -388,8 +388,6 @@
 
     ParsingPackage setLocaleConfigResourceId(int localeConfigRes);
 
-    ParsingPackage setAllowUpdateOwnership(boolean value);
-
     /**
      * Sets the trusted host certificates of apps that are allowed to embed activities of this
      * application.
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
index fda44e4..1567af0 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
@@ -219,7 +219,6 @@
     public static final int PARSE_DEFAULT_INSTALL_LOCATION =
             PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
     public static final int PARSE_DEFAULT_TARGET_SANDBOX = 1;
-    public static final boolean PARSE_DEFAULT_ALLOW_UPDATE_OWNERSHIP = true;
 
     /**
      * If set to true, we will only allow package files that exactly match the DTD. Otherwise, we
@@ -887,9 +886,7 @@
                 .setTargetSandboxVersion(anInteger(PARSE_DEFAULT_TARGET_SANDBOX,
                         R.styleable.AndroidManifest_targetSandboxVersion, sa))
                 /* Set the global "on SD card" flag */
-                .setExternalStorage((flags & PARSE_EXTERNAL_STORAGE) != 0)
-                .setAllowUpdateOwnership(bool(PARSE_DEFAULT_ALLOW_UPDATE_OWNERSHIP,
-                        R.styleable.AndroidManifest_allowUpdateOwnership, sa));
+                .setExternalStorage((flags & PARSE_EXTERNAL_STORAGE) != 0);
 
         boolean foundApp = false;
         final int depth = parser.getDepth();
diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
index 811d6e2..11f62e9 100644
--- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
+++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
@@ -788,7 +788,7 @@
 
     /**
      * @param includeNegative See
-     * {@link #approvalLevelForDomain(PackageStateInternal, String, boolean, int, Object)}.
+     * {@link #approvalLevelForDomain(PackageStateInternal, String, boolean, int, boolean, Object)}.
      * @return Mapping of approval level to packages; packages are sorted by firstInstallTime. Null
      * if no owners were found.
      */
@@ -808,7 +808,7 @@
                 }
 
                 int level = approvalLevelForDomain(pkgSetting, domain, includeNegative, userId,
-                        domain);
+                        DEBUG_APPROVAL, domain);
                 if (!includeNegative && level <= APPROVAL_LEVEL_NONE) {
                     continue;
                 }
@@ -1616,7 +1616,8 @@
                 fillInfoMapForSamePackage(inputMap, packageName, APPROVAL_LEVEL_NONE);
                 continue;
             }
-            int approval = approvalLevelForDomain(pkgSetting, domain, false, userId, domain);
+            int approval = approvalLevelForDomain(pkgSetting, domain, false, userId, DEBUG_APPROVAL,
+                    domain);
             highestApproval = Math.max(highestApproval, approval);
             fillInfoMapForSamePackage(inputMap, packageName, approval);
         }
@@ -1726,15 +1727,21 @@
             @NonNull Intent intent, @PackageManager.ResolveInfoFlagsBits long resolveInfoFlags,
             @UserIdInt int userId) {
         String packageName = pkgSetting.getPackageName();
+        var debug = DEBUG_APPROVAL || (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
         if (!DomainVerificationUtils.isDomainVerificationIntent(intent, resolveInfoFlags)) {
-            if (DEBUG_APPROVAL) {
+            if (debug) {
                 debugApproval(packageName, intent, userId, false, "not valid intent");
             }
             return APPROVAL_LEVEL_NONE;
         }
 
-        return approvalLevelForDomain(pkgSetting, intent.getData().getHost(), false, userId,
-                intent);
+        var approvalLevel = approvalLevelForDomain(pkgSetting, intent.getData().getHost(), false,
+                userId, debug, intent);
+        if (debug) {
+            Slog.d(TAG + "Approval", "Final approval level for " + pkgSetting.getPackageName()
+                    + " for host " + intent.getData().getHost() + " is " + approvalLevel);
+        }
+        return approvalLevel;
     }
 
     /**
@@ -1744,10 +1751,10 @@
      *                          {@link String} otherwise.
      */
     private int approvalLevelForDomain(@NonNull PackageStateInternal pkgSetting,
-            @NonNull String host, boolean includeNegative, @UserIdInt int userId,
+            @NonNull String host, boolean includeNegative, @UserIdInt int userId, boolean debug,
             @NonNull Object debugObject) {
         int approvalLevel = approvalLevelForDomainInternal(pkgSetting, host, includeNegative,
-                userId, debugObject);
+                userId, debug, debugObject);
         if (includeNegative && approvalLevel == APPROVAL_LEVEL_NONE) {
             PackageUserStateInternal pkgUserState = pkgSetting.getUserStateOrDefault(userId);
             if (!pkgUserState.isInstalled()) {
@@ -1768,13 +1775,13 @@
     }
 
     private int approvalLevelForDomainInternal(@NonNull PackageStateInternal pkgSetting,
-            @NonNull String host, boolean includeNegative, @UserIdInt int userId,
+            @NonNull String host, boolean includeNegative, @UserIdInt int userId, boolean debug,
             @NonNull Object debugObject) {
         String packageName = pkgSetting.getPackageName();
         final AndroidPackage pkg = pkgSetting.getPkg();
 
         if (pkg != null && includeNegative && !mCollector.containsWebDomain(pkg, host)) {
-            if (DEBUG_APPROVAL) {
+            if (debug) {
                 debugApproval(packageName, debugObject, userId, false,
                         "domain not declared");
             }
@@ -1783,7 +1790,7 @@
 
         final PackageUserStateInternal pkgUserState = pkgSetting.getUserStates().get(userId);
         if (pkgUserState == null) {
-            if (DEBUG_APPROVAL) {
+            if (debug) {
                 debugApproval(packageName, debugObject, userId, false,
                         "PackageUserState unavailable");
             }
@@ -1791,7 +1798,7 @@
         }
 
         if (!pkgUserState.isInstalled()) {
-            if (DEBUG_APPROVAL) {
+            if (debug) {
                 debugApproval(packageName, debugObject, userId, false,
                         "package not installed for user");
             }
@@ -1799,7 +1806,7 @@
         }
 
         if (!PackageUserStateUtils.isPackageEnabled(pkgUserState, pkg)) {
-            if (DEBUG_APPROVAL) {
+            if (debug) {
                 debugApproval(packageName, debugObject, userId, false,
                         "package not enabled for user");
             }
@@ -1807,7 +1814,7 @@
         }
 
         if (pkgUserState.isSuspended()) {
-            if (DEBUG_APPROVAL) {
+            if (debug) {
                 debugApproval(packageName, debugObject, userId, false,
                         "package suspended for user");
             }
@@ -1834,7 +1841,7 @@
         synchronized (mLock) {
             DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName);
             if (pkgState == null) {
-                if (DEBUG_APPROVAL) {
+                if (debug) {
                     debugApproval(packageName, debugObject, userId, false, "pkgState unavailable");
                 }
                 return APPROVAL_LEVEL_NONE;
@@ -1843,7 +1850,7 @@
             DomainVerificationInternalUserState userState = pkgState.getUserState(userId);
 
             if (userState != null && !userState.isLinkHandlingAllowed()) {
-                if (DEBUG_APPROVAL) {
+                if (debug) {
                     debugApproval(packageName, debugObject, userId, false,
                             "link handling not allowed");
                 }
@@ -1865,7 +1872,7 @@
             // Check if the exact host matches
             Integer state = stateMap.get(host);
             if (state != null && DomainVerificationState.isVerified(state)) {
-                if (DEBUG_APPROVAL) {
+                if (debug) {
                     debugApproval(packageName, debugObject, userId, true,
                             "host verified exactly");
                 }
@@ -1881,7 +1888,7 @@
 
                 String domain = stateMap.keyAt(index);
                 if (domain.startsWith("*.") && host.endsWith(domain.substring(2))) {
-                    if (DEBUG_APPROVAL) {
+                    if (debug) {
                         debugApproval(packageName, debugObject, userId, true,
                                 "host verified by wildcard");
                     }
@@ -1891,7 +1898,7 @@
 
             // Check user state if available
             if (userState == null) {
-                if (DEBUG_APPROVAL) {
+                if (debug) {
                     debugApproval(packageName, debugObject, userId, false, "userState unavailable");
                 }
                 return APPROVAL_LEVEL_NONE;
@@ -1900,7 +1907,7 @@
             // See if the user has approved the exact host
             ArraySet<String> enabledHosts = userState.getEnabledHosts();
             if (enabledHosts.contains(host)) {
-                if (DEBUG_APPROVAL) {
+                if (debug) {
                     debugApproval(packageName, debugObject, userId, true,
                             "host enabled by user exactly");
                 }
@@ -1912,7 +1919,7 @@
             for (int index = 0; index < enabledHostsSize; index++) {
                 String domain = enabledHosts.valueAt(index);
                 if (domain.startsWith("*.") && host.endsWith(domain.substring(2))) {
-                    if (DEBUG_APPROVAL) {
+                    if (debug) {
                         debugApproval(packageName, debugObject, userId, true,
                                 "host enabled by user through wildcard");
                     }
@@ -1920,7 +1927,7 @@
                 }
             }
 
-            if (DEBUG_APPROVAL) {
+            if (debug) {
                 debugApproval(packageName, debugObject, userId, false, "not approved");
             }
             return APPROVAL_LEVEL_NONE;
@@ -1948,7 +1955,7 @@
             }
 
             int level = approvalLevelForDomain(pkgSetting, domain, includeNegative, userId,
-                    domain);
+                    DEBUG_APPROVAL, domain);
             if (level < minimumApproval) {
                 continue;
             }
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index 7a5664f..5288e85 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -37,6 +37,7 @@
 import android.os.IBinder;
 import android.os.PackageTagsList;
 import android.os.Process;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.service.voice.VoiceInteractionManagerInternal;
 import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity;
@@ -68,6 +69,8 @@
     private static final String ACTIVITY_RECOGNITION_TAGS =
             "android:activity_recognition_allow_listed_tags";
     private static final String ACTIVITY_RECOGNITION_TAGS_SEPARATOR = ";";
+    private static final boolean SYSPROP_HOTWORD_DETECTION_SERVICE_REQUIRED =
+            SystemProperties.getBoolean("ro.hotword.detection_service_required", false);
 
     @NonNull
     private final Object mLock = new Object();
@@ -199,10 +202,16 @@
         }
     }
 
-    private static boolean isHotwordDetectionServiceRequired(PackageManager pm) {
+    /**
+     * @hide
+     */
+    public static boolean isHotwordDetectionServiceRequired(PackageManager pm) {
         // The HotwordDetectionService APIs aren't ready yet for Auto or TV.
-        return !(pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
-                || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK));
+        if (pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+                || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
+            return false;
+        }
+        return SYSPROP_HOTWORD_DETECTION_SERVICE_REQUIRED;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index d7eff52..a148de6 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -6010,6 +6010,12 @@
     }
 
     @Override
+    @WindowManagerFuncs.LidState
+    public int getLidState() {
+        return mDefaultDisplayPolicy.getLidState();
+    }
+
+    @Override
     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
         proto.write(ROTATION_MODE, mDefaultDisplayRotation.getUserRotationMode());
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 887f946..3da7812 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -218,6 +218,14 @@
      * between it and the policy.
      */
     public interface WindowManagerFuncs {
+        @IntDef(prefix = { "LID_" }, value = {
+                LID_ABSENT,
+                LID_CLOSED,
+                LID_OPEN,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        @interface LidState{}
+
         public static final int LID_ABSENT = -1;
         public static final int LID_CLOSED = 0;
         public static final int LID_OPEN = 1;
@@ -231,8 +239,9 @@
         public static final int CAMERA_LENS_COVERED = 1;
 
         /**
-         * Returns a code that describes the current state of the lid switch.
+         * Returns a {@link LidState} that describes the current state of the lid switch.
          */
+        @LidState
         public int getLidState();
 
         /**
@@ -282,7 +291,7 @@
         /**
          * Convert the lid state to a human readable format.
          */
-        static String lidStateToString(int lid) {
+        static String lidStateToString(@LidState int lid) {
             switch (lid) {
                 case LID_ABSENT:
                     return "LID_ABSENT";
@@ -1241,4 +1250,11 @@
      * @return {@code true} if the key will be handled globally.
      */
     boolean isGlobalKey(int keyCode);
+
+    /**
+     * Returns a {@link WindowManagerFuncs.LidState} that describes the current state of
+     * the lid switch.
+     */
+    @WindowManagerFuncs.LidState
+    int getLidState();
 }
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 9bc0ee22..a694e31 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -265,7 +265,7 @@
                     + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
                     + ", workSource=" + workSource);
         }
-        notifyWakeLockListener(callback, true);
+        notifyWakeLockListener(callback, tag, true);
         final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
         if (monitorType >= 0) {
             try {
@@ -392,7 +392,7 @@
                     + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
                     + ", workSource=" + workSource);
         }
-        notifyWakeLockListener(callback, false);
+        notifyWakeLockListener(callback, tag, false);
         final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
         if (monitorType >= 0) {
             try {
@@ -1011,13 +1011,13 @@
         return enabled && dndOff;
     }
 
-    private void notifyWakeLockListener(IWakeLockCallback callback, boolean isEnabled) {
+    private void notifyWakeLockListener(IWakeLockCallback callback, String tag, boolean isEnabled) {
         if (callback != null) {
             mHandler.post(() -> {
                 try {
                     callback.onStateChanged(isEnabled);
                 } catch (RemoteException e) {
-                    throw new IllegalArgumentException("Wakelock.mCallback is already dead.", e);
+                    Slog.e(TAG, "Wakelock.mCallback [" + tag + "] is already dead.", e);
                 }
             });
         }
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index b8c5b3f..712be36 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -33,6 +33,7 @@
 import static android.os.PowerManagerInternal.wakefulnessToString;
 
 import static com.android.internal.util.LatencyTracker.ACTION_TURN_ON_SCREEN;
+import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -5733,6 +5734,11 @@
         @Override // Binder call
         public void wakeUp(long eventTime, @WakeReason int reason, String details,
                 String opPackageName) {
+            if (mPolicy.getLidState() == LID_CLOSED) {
+                Slog.d(TAG, "Ignoring wake up call due to the lid being closed");
+                return;
+            }
+
             final long now = mClock.uptimeMillis();
             if (eventTime > now) {
                 Slog.e(TAG, "Event time " + eventTime + " cannot be newer than " + now);
diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
index 93d6676..4a57592a 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -1675,6 +1675,7 @@
 
     String mLastWakeupReason = null;
     long mLastWakeupUptimeMs = 0;
+    long mLastWakeupElapsedTimeMs = 0;
     private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>();
 
     public Map<String, ? extends Timer> getWakeupReasonStats() {
@@ -5048,7 +5049,7 @@
             SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason);
             timer.add(deltaUptimeMs * 1000, 1, elapsedRealtimeMs); // time in in microseconds
             FrameworkStatsLog.write(FrameworkStatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason,
-                    /* duration_usec */ deltaUptimeMs * 1000);
+                    /* duration_usec */ deltaUptimeMs * 1000, mLastWakeupElapsedTimeMs);
             mLastWakeupReason = null;
         }
     }
@@ -5059,6 +5060,7 @@
         mHistory.recordWakeupEvent(elapsedRealtimeMs, uptimeMs, reason);
         mLastWakeupReason = reason;
         mLastWakeupUptimeMs = uptimeMs;
+        mLastWakeupElapsedTimeMs = elapsedRealtimeMs;
     }
 
     @GuardedBy("this")
diff --git a/services/core/java/com/android/server/power/stats/wakeups/CpuWakeupStats.java b/services/core/java/com/android/server/power/stats/wakeups/CpuWakeupStats.java
index 73ab782..712a696 100644
--- a/services/core/java/com/android/server/power/stats/wakeups/CpuWakeupStats.java
+++ b/services/core/java/com/android/server/power/stats/wakeups/CpuWakeupStats.java
@@ -23,6 +23,7 @@
 import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_UNKNOWN;
 import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_WIFI;
 
+import android.annotation.SuppressLint;
 import android.app.ActivityManager;
 import android.content.Context;
 import android.os.Handler;
@@ -48,6 +49,7 @@
 import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
+import java.util.function.LongSupplier;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -62,15 +64,14 @@
     private static final String SUBSYSTEM_SENSOR_STRING = "Sensor";
     private static final String SUBSYSTEM_CELLULAR_DATA_STRING = "Cellular_data";
     private static final String TRACE_TRACK_WAKEUP_ATTRIBUTION = "wakeup_attribution";
-    @VisibleForTesting
-    static final long WAKEUP_REASON_HALF_WINDOW_MS = 500;
+
     private static final long WAKEUP_WRITE_DELAY_MS = TimeUnit.SECONDS.toMillis(30);
 
     private final Handler mHandler;
     private final IrqDeviceMap mIrqDeviceMap;
     @VisibleForTesting
     final Config mConfig = new Config();
-    private final WakingActivityHistory mRecentWakingActivity = new WakingActivityHistory();
+    private final WakingActivityHistory mRecentWakingActivity;
 
     @VisibleForTesting
     final TimeSparseArray<Wakeup> mWakeupEvents = new TimeSparseArray<>();
@@ -85,6 +86,8 @@
 
     public CpuWakeupStats(Context context, int mapRes, Handler handler) {
         mIrqDeviceMap = IrqDeviceMap.getInstance(context, mapRes);
+        mRecentWakingActivity = new WakingActivityHistory(
+                () -> mConfig.WAKING_ACTIVITY_RETENTION_MS);
         mHandler = handler;
     }
 
@@ -202,15 +205,14 @@
     /** Notes a wakeup reason as reported by SuspendControlService to battery stats. */
     public synchronized void noteWakeupTimeAndReason(long elapsedRealtime, long uptime,
             String rawReason) {
-        final Wakeup parsedWakeup = Wakeup.parseWakeup(rawReason, elapsedRealtime, uptime);
+        final Wakeup parsedWakeup = Wakeup.parseWakeup(rawReason, elapsedRealtime, uptime,
+                mIrqDeviceMap);
         if (parsedWakeup == null) {
+            // This wakeup is unsupported for attribution. Exit.
             return;
         }
         mWakeupEvents.put(elapsedRealtime, parsedWakeup);
         attemptAttributionFor(parsedWakeup);
-        // Assuming that wakeups always arrive in monotonically increasing elapsedRealtime order,
-        // we can delete all history that will not be useful in attributing future wakeups.
-        mRecentWakingActivity.clearAllBefore(elapsedRealtime - WAKEUP_REASON_HALF_WINDOW_MS);
 
         // Limit history of wakeups and their attribution to the last retentionDuration. Note that
         // the last wakeup and its attribution (if computed) is always stored, even if that wakeup
@@ -244,25 +246,22 @@
     }
 
     private synchronized void attemptAttributionFor(Wakeup wakeup) {
-        final SparseBooleanArray subsystems = getResponsibleSubsystemsForWakeup(wakeup);
-        if (subsystems == null) {
-            // We don't support attribution for this kind of wakeup yet.
-            return;
-        }
+        final SparseBooleanArray subsystems = wakeup.mResponsibleSubsystems;
 
         SparseArray<SparseIntArray> attribution = mWakeupAttribution.get(wakeup.mElapsedMillis);
         if (attribution == null) {
             attribution = new SparseArray<>();
             mWakeupAttribution.put(wakeup.mElapsedMillis, attribution);
         }
+        final long matchingWindowMillis = mConfig.WAKEUP_MATCHING_WINDOW_MS;
 
         for (int subsystemIdx = 0; subsystemIdx < subsystems.size(); subsystemIdx++) {
             final int subsystem = subsystems.keyAt(subsystemIdx);
 
-            // Blame all activity that happened WAKEUP_REASON_HALF_WINDOW_MS before or after
+            // Blame all activity that happened matchingWindowMillis before or after
             // the wakeup from each responsible subsystem.
-            final long startTime = wakeup.mElapsedMillis - WAKEUP_REASON_HALF_WINDOW_MS;
-            final long endTime = wakeup.mElapsedMillis + WAKEUP_REASON_HALF_WINDOW_MS;
+            final long startTime = wakeup.mElapsedMillis - matchingWindowMillis;
+            final long endTime = wakeup.mElapsedMillis + matchingWindowMillis;
 
             final SparseIntArray uidsToBlame = mRecentWakingActivity.removeBetween(subsystem,
                     startTime, endTime);
@@ -272,18 +271,16 @@
 
     private synchronized boolean attemptAttributionWith(int subsystem, long activityElapsed,
             SparseIntArray uidProcStates) {
+        final long matchingWindowMillis = mConfig.WAKEUP_MATCHING_WINDOW_MS;
+
         final int startIdx = mWakeupEvents.closestIndexOnOrAfter(
-                activityElapsed - WAKEUP_REASON_HALF_WINDOW_MS);
+                activityElapsed - matchingWindowMillis);
         final int endIdx = mWakeupEvents.closestIndexOnOrBefore(
-                activityElapsed + WAKEUP_REASON_HALF_WINDOW_MS);
+                activityElapsed + matchingWindowMillis);
 
         for (int wakeupIdx = startIdx; wakeupIdx <= endIdx; wakeupIdx++) {
             final Wakeup wakeup = mWakeupEvents.valueAt(wakeupIdx);
-            final SparseBooleanArray subsystems = getResponsibleSubsystemsForWakeup(wakeup);
-            if (subsystems == null) {
-                // Unsupported for attribution
-                continue;
-            }
+            final SparseBooleanArray subsystems = wakeup.mResponsibleSubsystems;
             if (subsystems.get(subsystem)) {
                 // We don't expect more than one wakeup to be found within such a short window, so
                 // just attribute this one and exit
@@ -405,11 +402,13 @@
      */
     @VisibleForTesting
     static final class WakingActivityHistory {
-        private static final long WAKING_ACTIVITY_RETENTION_MS = TimeUnit.MINUTES.toMillis(10);
-
+        private LongSupplier mRetentionSupplier;
         @VisibleForTesting
-        final SparseArray<TimeSparseArray<SparseIntArray>> mWakingActivity =
-                new SparseArray<>();
+        final SparseArray<TimeSparseArray<SparseIntArray>> mWakingActivity = new SparseArray<>();
+
+        WakingActivityHistory(LongSupplier retentionSupplier) {
+            mRetentionSupplier = retentionSupplier;
+        }
 
         void recordActivity(int subsystem, long elapsedRealtime, SparseIntArray uidProcStates) {
             if (uidProcStates == null) {
@@ -433,27 +432,13 @@
                     }
                 }
             }
-            // Limit activity history per subsystem to the last WAKING_ACTIVITY_RETENTION_MS.
-            // Note that the last activity is always present, even if it occurred before
-            // WAKING_ACTIVITY_RETENTION_MS.
+            // Limit activity history per subsystem to the last retention period as supplied by
+            // mRetentionSupplier. Note that the last activity is always present, even if it
+            // occurred before the retention period.
             final int endIdx = wakingActivity.closestIndexOnOrBefore(
-                    elapsedRealtime - WAKING_ACTIVITY_RETENTION_MS);
+                    elapsedRealtime - mRetentionSupplier.getAsLong());
             for (int i = endIdx; i >= 0; i--) {
-                wakingActivity.removeAt(endIdx);
-            }
-        }
-
-        void clearAllBefore(long elapsedRealtime) {
-            for (int subsystemIdx = mWakingActivity.size() - 1; subsystemIdx >= 0; subsystemIdx--) {
-                final TimeSparseArray<SparseIntArray> activityPerSubsystem =
-                        mWakingActivity.valueAt(subsystemIdx);
-                final int endIdx = activityPerSubsystem.closestIndexOnOrBefore(elapsedRealtime);
-                for (int removeIdx = endIdx; removeIdx >= 0; removeIdx--) {
-                    activityPerSubsystem.removeAt(removeIdx);
-                }
-                // Generally waking activity is a high frequency occurrence for any subsystem, so we
-                // don't delete the TimeSparseArray even if it is now empty, to avoid object churn.
-                // This will leave one TimeSparseArray per subsystem, which are few right now.
+                wakingActivity.removeAt(i);
             }
         }
 
@@ -515,33 +500,6 @@
         }
     }
 
-    private SparseBooleanArray getResponsibleSubsystemsForWakeup(Wakeup wakeup) {
-        if (ArrayUtils.isEmpty(wakeup.mDevices)) {
-            return null;
-        }
-        final SparseBooleanArray result = new SparseBooleanArray();
-        for (final Wakeup.IrqDevice device : wakeup.mDevices) {
-            final List<String> rawSubsystems = mIrqDeviceMap.getSubsystemsForDevice(device.mDevice);
-
-            boolean anyKnownSubsystem = false;
-            if (rawSubsystems != null) {
-                for (int i = 0; i < rawSubsystems.size(); i++) {
-                    final int subsystem = stringToKnownSubsystem(rawSubsystems.get(i));
-                    if (subsystem != CPU_WAKEUP_SUBSYSTEM_UNKNOWN) {
-                        // Just in case the xml had arbitrary subsystem names, we want to make sure
-                        // that we only put the known ones into our attribution map.
-                        result.put(subsystem, true);
-                        anyKnownSubsystem = true;
-                    }
-                }
-            }
-            if (!anyKnownSubsystem) {
-                result.put(CPU_WAKEUP_SUBSYSTEM_UNKNOWN, true);
-            }
-        }
-        return result;
-    }
-
     static int stringToKnownSubsystem(String rawSubsystem) {
         switch (rawSubsystem) {
             case SUBSYSTEM_ALARM_STRING:
@@ -598,15 +556,19 @@
         long mElapsedMillis;
         long mUptimeMillis;
         IrqDevice[] mDevices;
+        SparseBooleanArray mResponsibleSubsystems;
 
-        private Wakeup(int type, IrqDevice[] devices, long elapsedMillis, long uptimeMillis) {
+        private Wakeup(int type, IrqDevice[] devices, long elapsedMillis, long uptimeMillis,
+                SparseBooleanArray responsibleSubsystems) {
             mType = type;
             mDevices = devices;
             mElapsedMillis = elapsedMillis;
             mUptimeMillis = uptimeMillis;
+            mResponsibleSubsystems = responsibleSubsystems;
         }
 
-        static Wakeup parseWakeup(String rawReason, long elapsedMillis, long uptimeMillis) {
+        static Wakeup parseWakeup(String rawReason, long elapsedMillis, long uptimeMillis,
+                IrqDeviceMap deviceMap) {
             final String[] components = rawReason.split(":");
             if (ArrayUtils.isEmpty(components) || components[0].startsWith(ABORT_REASON_PREFIX)) {
                 // Accounting of aborts is not supported yet.
@@ -616,6 +578,7 @@
             int type = TYPE_IRQ;
             int parsedDeviceCount = 0;
             final IrqDevice[] parsedDevices = new IrqDevice[components.length];
+            final SparseBooleanArray responsibleSubsystems = new SparseBooleanArray();
 
             for (String component : components) {
                 final Matcher matcher = sIrqPattern.matcher(component.trim());
@@ -635,13 +598,35 @@
                         continue;
                     }
                     parsedDevices[parsedDeviceCount++] = new IrqDevice(line, device);
+
+                    final List<String> rawSubsystems = deviceMap.getSubsystemsForDevice(device);
+                    boolean anyKnownSubsystem = false;
+                    if (rawSubsystems != null) {
+                        for (int i = 0; i < rawSubsystems.size(); i++) {
+                            final int subsystem = stringToKnownSubsystem(rawSubsystems.get(i));
+                            if (subsystem != CPU_WAKEUP_SUBSYSTEM_UNKNOWN) {
+                                // Just in case the xml had arbitrary subsystem names, we want to
+                                // make sure that we only put the known ones into our map.
+                                responsibleSubsystems.put(subsystem, true);
+                                anyKnownSubsystem = true;
+                            }
+                        }
+                    }
+                    if (!anyKnownSubsystem) {
+                        responsibleSubsystems.put(CPU_WAKEUP_SUBSYSTEM_UNKNOWN, true);
+                    }
                 }
             }
             if (parsedDeviceCount == 0) {
                 return null;
             }
+            if (responsibleSubsystems.size() == 1 && responsibleSubsystems.get(
+                    CPU_WAKEUP_SUBSYSTEM_UNKNOWN, false)) {
+                // There is no attributable subsystem here, so we do not support it.
+                return null;
+            }
             return new Wakeup(type, Arrays.copyOf(parsedDevices, parsedDeviceCount), elapsedMillis,
-                    uptimeMillis);
+                    uptimeMillis, responsibleSubsystems);
         }
 
         @Override
@@ -651,6 +636,7 @@
                     + ", mElapsedMillis=" + mElapsedMillis
                     + ", mUptimeMillis=" + mUptimeMillis
                     + ", mDevices=" + Arrays.toString(mDevices)
+                    + ", mResponsibleSubsystems=" + mResponsibleSubsystems
                     + '}';
         }
 
@@ -672,18 +658,28 @@
 
     static final class Config implements DeviceConfig.OnPropertiesChangedListener {
         static final String KEY_WAKEUP_STATS_RETENTION_MS = "wakeup_stats_retention_ms";
+        static final String KEY_WAKEUP_MATCHING_WINDOW_MS = "wakeup_matching_window_ms";
+        static final String KEY_WAKING_ACTIVITY_RETENTION_MS = "waking_activity_retention_ms";
 
         private static final String[] PROPERTY_NAMES = {
                 KEY_WAKEUP_STATS_RETENTION_MS,
+                KEY_WAKEUP_MATCHING_WINDOW_MS,
+                KEY_WAKING_ACTIVITY_RETENTION_MS,
         };
 
         static final long DEFAULT_WAKEUP_STATS_RETENTION_MS = TimeUnit.DAYS.toMillis(3);
+        private static final long DEFAULT_WAKEUP_MATCHING_WINDOW_MS = TimeUnit.SECONDS.toMillis(1);
+        private static final long DEFAULT_WAKING_ACTIVITY_RETENTION_MS =
+                TimeUnit.MINUTES.toMillis(5);
 
         /**
          * Wakeup stats are retained only for this duration.
          */
         public volatile long WAKEUP_STATS_RETENTION_MS = DEFAULT_WAKEUP_STATS_RETENTION_MS;
+        public volatile long WAKEUP_MATCHING_WINDOW_MS = DEFAULT_WAKEUP_MATCHING_WINDOW_MS;
+        public volatile long WAKING_ACTIVITY_RETENTION_MS = DEFAULT_WAKING_ACTIVITY_RETENTION_MS;
 
+        @SuppressLint("MissingPermission")
         void register(Executor executor) {
             DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_BATTERY_STATS,
                     executor, this);
@@ -702,6 +698,15 @@
                         WAKEUP_STATS_RETENTION_MS = properties.getLong(
                                 KEY_WAKEUP_STATS_RETENTION_MS, DEFAULT_WAKEUP_STATS_RETENTION_MS);
                         break;
+                    case KEY_WAKEUP_MATCHING_WINDOW_MS:
+                        WAKEUP_MATCHING_WINDOW_MS = properties.getLong(
+                                KEY_WAKEUP_MATCHING_WINDOW_MS, DEFAULT_WAKEUP_MATCHING_WINDOW_MS);
+                        break;
+                    case KEY_WAKING_ACTIVITY_RETENTION_MS:
+                        WAKING_ACTIVITY_RETENTION_MS = properties.getLong(
+                                KEY_WAKING_ACTIVITY_RETENTION_MS,
+                                DEFAULT_WAKING_ACTIVITY_RETENTION_MS);
+                        break;
                 }
             }
         }
@@ -711,7 +716,19 @@
 
             pw.increaseIndent();
 
-            pw.print(KEY_WAKEUP_STATS_RETENTION_MS, WAKEUP_STATS_RETENTION_MS);
+            pw.print(KEY_WAKEUP_STATS_RETENTION_MS);
+            pw.print("=");
+            TimeUtils.formatDuration(WAKEUP_STATS_RETENTION_MS, pw);
+            pw.println();
+
+            pw.print(KEY_WAKEUP_MATCHING_WINDOW_MS);
+            pw.print("=");
+            TimeUtils.formatDuration(WAKEUP_MATCHING_WINDOW_MS, pw);
+            pw.println();
+
+            pw.print(KEY_WAKING_ACTIVITY_RETENTION_MS);
+            pw.print("=");
+            TimeUtils.formatDuration(WAKING_ACTIVITY_RETENTION_MS, pw);
             pw.println();
 
             pw.decreaseIndent();
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 363d2fd..044d30b 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -53,7 +53,6 @@
 import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Icon;
 import android.hardware.biometrics.BiometricAuthenticator.Modality;
-import android.hardware.biometrics.BiometricManager.BiometricMultiSensorMode;
 import android.hardware.biometrics.IBiometricContextListener;
 import android.hardware.biometrics.IBiometricSysuiReceiver;
 import android.hardware.biometrics.PromptInfo;
@@ -949,14 +948,12 @@
     @Override
     public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver,
             int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
-            int userId, long operationId, String opPackageName, long requestId,
-            @BiometricMultiSensorMode int multiSensorConfig) {
+            int userId, long operationId, String opPackageName, long requestId) {
         enforceBiometricDialog();
         if (mBar != null) {
             try {
                 mBar.showAuthenticationDialog(promptInfo, receiver, sensorIds, credentialAllowed,
-                        requireConfirmation, userId, operationId, opPackageName, requestId,
-                        multiSensorConfig);
+                        requireConfirmation, userId, operationId, opPackageName, requestId);
             } catch (RemoteException ex) {
             }
         }
diff --git a/services/core/java/com/android/server/tv/TvInputHal.java b/services/core/java/com/android/server/tv/TvInputHal.java
index 4bbca33..87ebdbf 100644
--- a/services/core/java/com/android/server/tv/TvInputHal.java
+++ b/services/core/java/com/android/server/tv/TvInputHal.java
@@ -19,6 +19,7 @@
 import android.hardware.tv.input.V1_0.Constants;
 import android.media.tv.TvInputHardwareInfo;
 import android.media.tv.TvStreamConfig;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.os.MessageQueue;
@@ -45,12 +46,15 @@
             Constants.EVENT_STREAM_CONFIGURATIONS_CHANGED;
     public static final int EVENT_FIRST_FRAME_CAPTURED = 4;
 
+    public static final int EVENT_TV_MESSAGE = 5;
+
     public interface Callback {
         void onDeviceAvailable(TvInputHardwareInfo info, TvStreamConfig[] configs);
         void onDeviceUnavailable(int deviceId);
         void onStreamConfigurationChanged(int deviceId, TvStreamConfig[] configs,
                 int cableConnectionStatus);
         void onFirstFrameCaptured(int deviceId, int streamId);
+        void onTvMessage(int deviceId, int type, Bundle data);
     }
 
     private native long nativeOpen(MessageQueue queue);
@@ -171,6 +175,10 @@
                 mHandler.obtainMessage(EVENT_STREAM_CONFIGURATION_CHANGED, deviceId, streamId));
     }
 
+    private void tvMessageReceivedFromNative(int deviceId, int type, Bundle data) {
+        mHandler.obtainMessage(EVENT_TV_MESSAGE, deviceId, type, data).sendToTarget();
+    }
+
     // Handler.Callback implementation
 
     @Override
@@ -221,6 +229,14 @@
                 break;
             }
 
+            case EVENT_TV_MESSAGE: {
+                int deviceId = msg.arg1;
+                int type = msg.arg2;
+                Bundle data = (Bundle) msg.obj;
+                mCallback.onTvMessage(deviceId, type, data);
+                break;
+            }
+
             default:
                 Slog.e(TAG, "Unknown event: " + msg);
                 return false;
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 077f8d5..d63a908 100755
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -48,6 +48,7 @@
 import android.media.tv.TvStreamConfig;
 import android.media.tv.tunerresourcemanager.ResourceClientProfile;
 import android.media.tv.tunerresourcemanager.TunerResourceManager;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
@@ -59,6 +60,7 @@
 import android.util.SparseBooleanArray;
 import android.view.Surface;
 
+import com.android.internal.os.SomeArgs;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.SystemService;
@@ -264,6 +266,21 @@
         }
     }
 
+    @Override
+    public void onTvMessage(int deviceId, int type, Bundle data) {
+        synchronized (mLock) {
+            String inputId = mHardwareInputIdMap.get(deviceId);
+            if (inputId == null) {
+                return;
+            }
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = mHardwareInputIdMap.get(deviceId);
+            args.arg2 = data;
+            mHandler.obtainMessage(ListenerHandler.TV_MESSAGE_RECEIVED, type, 0, args)
+                    .sendToTarget();
+        }
+    }
+
     public List<TvInputHardwareInfo> getHardwareList() {
         synchronized (mLock) {
             return Collections.unmodifiableList(mHardwareList);
@@ -1224,6 +1241,7 @@
         void onHdmiDeviceAdded(HdmiDeviceInfo device);
         void onHdmiDeviceRemoved(HdmiDeviceInfo device);
         void onHdmiDeviceUpdated(String inputId, HdmiDeviceInfo device);
+        void onTvMessage(String inputId, int type, Bundle data);
     }
 
     private class ListenerHandler extends Handler {
@@ -1234,6 +1252,7 @@
         private static final int HDMI_DEVICE_REMOVED = 5;
         private static final int HDMI_DEVICE_UPDATED = 6;
         private static final int TVINPUT_INFO_ADDED = 7;
+        private static final int TV_MESSAGE_RECEIVED = 8;
 
         @Override
         public final void handleMessage(Message msg) {
@@ -1303,6 +1322,15 @@
                     }
                     break;
                 }
+                case TV_MESSAGE_RECEIVED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    String inputId = (String) args.arg1;
+                    Bundle data = (Bundle) args.arg2;
+                    int type = msg.arg1;
+                    mListener.onTvMessage(inputId, type, data);
+                    args.recycle();
+                    break;
+                }
                 default: {
                     Slog.w(TAG, "Unhandled message: " + msg);
                     break;
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 1f5c1cf..a05bd2d 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -4146,6 +4146,32 @@
                 }
             }
         }
+
+        @Override
+        public void onTvMessage(String inputId, int type, Bundle data) {
+            synchronized (mLock) {
+                UserState userState = getOrCreateUserStateLocked(mCurrentUserId);
+                TvInputState inputState = userState.inputMap.get(inputId);
+                if (inputState == null) {
+                    Slog.e(TAG, "failed to send TV message - unknown input id " + inputId);
+                    return;
+                }
+                ServiceState serviceState = userState.serviceStateMap.get(inputState.info
+                        .getComponent());
+                for (IBinder token : serviceState.sessionTokens) {
+                    try {
+                        SessionState sessionState = getSessionStateLocked(token,
+                                Binder.getCallingUid(), mCurrentUserId);
+                        if (!sessionState.isRecordingSession
+                                && sessionState.hardwareSessionToken != null) {
+                            sessionState.session.notifyTvMessage(type, data);
+                        }
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "error in onTvMessage", e);
+                    }
+                }
+            }
+        }
     }
 
     private static class SessionNotFoundException extends IllegalArgumentException {
diff --git a/services/core/java/com/android/server/uri/UriPermission.java b/services/core/java/com/android/server/uri/UriPermission.java
index 6db781a..f3eeab0 100644
--- a/services/core/java/com/android/server/uri/UriPermission.java
+++ b/services/core/java/com/android/server/uri/UriPermission.java
@@ -207,7 +207,9 @@
             if (mReadOwners != null && includingOwners) {
                 ownedModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
                 for (UriPermissionOwner r : mReadOwners) {
-                    r.removeReadPermission(this);
+                    if (r != null) {
+                        r.removeReadPermission(this);
+                    }
                 }
                 mReadOwners = null;
             }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 4908529..a079875 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -82,6 +82,7 @@
 import android.os.IInterface;
 import android.os.IRemoteCallback;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
@@ -2514,6 +2515,7 @@
      * Propagate a wake event to the wallpaper engine(s).
      */
     public void notifyWakingUp(int x, int y, @NonNull Bundle extras) {
+        checkCallerIsSystemOrSystemUi();
         synchronized (mLock) {
             if (mIsLockscreenLiveWallpaperEnabled) {
                 for (WallpaperData data : getActiveWallpapers()) {
@@ -2551,6 +2553,7 @@
      * Propagate a sleep event to the wallpaper engine(s).
      */
     public void notifyGoingToSleep(int x, int y, @NonNull Bundle extras) {
+        checkCallerIsSystemOrSystemUi();
         synchronized (mLock) {
             if (mIsLockscreenLiveWallpaperEnabled) {
                 for (WallpaperData data : getActiveWallpapers()) {
@@ -3031,9 +3034,6 @@
             }
         }
 
-        final boolean fromForegroundApp = Binder.withCleanCallingIdentity(() ->
-                mActivityManager.getPackageImportance(callingPackage) == IMPORTANCE_FOREGROUND);
-
         synchronized (mLock) {
             if (DEBUG) Slog.v(TAG, "setWallpaper which=0x" + Integer.toHexString(which));
             WallpaperData wallpaper;
@@ -3066,7 +3066,7 @@
                     wallpaper.mSystemWasBoth = systemIsBoth;
                     wallpaper.mWhich = which;
                     wallpaper.setComplete = completion;
-                    wallpaper.fromForegroundApp = fromForegroundApp;
+                    wallpaper.fromForegroundApp = isFromForegroundApp(callingPackage);
                     wallpaper.cropHint.set(cropHint);
                     wallpaper.allowBackup = allowBackup;
                     wallpaper.mWallpaperDimAmount = getWallpaperDimAmount();
@@ -3153,27 +3153,28 @@
             @SetWallpaperFlags int which, int userId) {
 
         if (isWallpaperSupported(callingPackage) && isSetWallpaperAllowed(callingPackage)) {
-            setWallpaperComponent(name, which, userId);
+            setWallpaperComponent(name, callingPackage, which, userId);
         }
     }
 
     // ToDo: Remove this version of the function
     @Override
     public void setWallpaperComponent(ComponentName name) {
-        setWallpaperComponent(name, UserHandle.getCallingUserId(), FLAG_SYSTEM);
+        setWallpaperComponent(name, "", UserHandle.getCallingUserId(), FLAG_SYSTEM);
     }
 
     @VisibleForTesting
-    void setWallpaperComponent(ComponentName name, @SetWallpaperFlags int which, int userId) {
+    void setWallpaperComponent(ComponentName name, String callingPackage,
+            @SetWallpaperFlags int which, int userId) {
         if (mIsLockscreenLiveWallpaperEnabled) {
-            setWallpaperComponentInternal(name, which, userId);
+            setWallpaperComponentInternal(name, callingPackage, which, userId);
         } else {
-            setWallpaperComponentInternalLegacy(name, which, userId);
+            setWallpaperComponentInternalLegacy(name, callingPackage, which, userId);
         }
     }
 
-    private void setWallpaperComponentInternal(ComponentName name, @SetWallpaperFlags int which,
-            int userIdIn) {
+    private void setWallpaperComponentInternal(ComponentName name, String callingPackage,
+            @SetWallpaperFlags int which, int userIdIn) {
         if (DEBUG) {
             Slog.v(TAG, "Setting new live wallpaper: which=" + which + ", component: " + name);
         }
@@ -3209,6 +3210,7 @@
                 newWallpaper.imageWallpaperPending = false;
                 newWallpaper.mWhich = which;
                 newWallpaper.mSystemWasBoth = systemIsBoth;
+                newWallpaper.fromForegroundApp = isFromForegroundApp(callingPackage);
                 final WallpaperDestinationChangeHandler
                         liveSync = new WallpaperDestinationChangeHandler(
                         newWallpaper);
@@ -3280,7 +3282,7 @@
     }
 
     // TODO(b/266818039) Remove this method
-    private void setWallpaperComponentInternalLegacy(ComponentName name,
+    private void setWallpaperComponentInternalLegacy(ComponentName name, String callingPackage,
             @SetWallpaperFlags int which, int userId) {
         userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
                 false /* all */, true /* full */, "changing live wallpaper", null /* pkg */);
@@ -3320,6 +3322,7 @@
             try {
                 wallpaper.imageWallpaperPending = false;
                 wallpaper.mWhich = which;
+                wallpaper.fromForegroundApp = isFromForegroundApp(callingPackage);
                 boolean same = changingToSame(name, wallpaper);
                 if (bindWallpaperComponentLocked(name, false, true, wallpaper, null)) {
                     if (!same) {
@@ -3679,6 +3682,19 @@
         }
     }
 
+    private boolean isFromForegroundApp(String callingPackage) {
+        return Binder.withCleanCallingIdentity(() ->
+                mActivityManager.getPackageImportance(callingPackage) == IMPORTANCE_FOREGROUND);
+    }
+
+    /** Check that the caller is either system_server or systemui */
+    private void checkCallerIsSystemOrSystemUi() {
+        if (Binder.getCallingUid() != Process.myUid() && mContext.checkCallingPermission(
+                android.Manifest.permission.STATUS_BAR_SERVICE) != PERMISSION_GRANTED) {
+            throw new SecurityException("Access denied: only system processes can call this");
+        }
+    }
+
     /**
      * Certain user types do not support wallpapers (e.g. managed profiles). The check is
      * implemented through through the OP_WRITE_WALLPAPER AppOp.
@@ -3982,6 +3998,8 @@
             if (mFallbackWallpaper != null) {
                 dumpWallpaper(mFallbackWallpaper, pw);
             }
+            pw.print("mIsLockscreenLiveWallpaperEnabled=");
+            pw.println(mIsLockscreenLiveWallpaperEnabled);
         }
     }
 }
diff --git a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
index 5c929a9..bd07622 100644
--- a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
+++ b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
@@ -30,6 +30,7 @@
 import android.graphics.Rect;
 import android.graphics.RenderNode;
 import android.hardware.HardwareBuffer;
+import android.os.SystemClock;
 import android.os.Trace;
 import android.util.Pair;
 import android.util.Slog;
@@ -213,6 +214,7 @@
             // Failed to acquire image. Has been logged.
             return null;
         }
+        builder.setCaptureTime(SystemClock.elapsedRealtimeNanos());
         builder.setSnapshot(screenshotBuffer.getHardwareBuffer());
         builder.setColorSpace(screenshotBuffer.getColorSpace());
         return builder.build();
@@ -432,6 +434,7 @@
         // color above
         return new TaskSnapshot(
                 System.currentTimeMillis() /* id */,
+                SystemClock.elapsedRealtimeNanos() /* captureTime */,
                 topActivity.mActivityComponent, hwBitmap.getHardwareBuffer(),
                 hwBitmap.getColorSpace(), mainWindow.getConfiguration().orientation,
                 mainWindow.getWindowConfiguration().getRotation(), new Point(taskWidth, taskHeight),
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index 6b90181..aafff2c 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
 import static android.app.Activity.FULLSCREEN_MODE_REQUEST_ENTER;
+import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.ActivityTaskManager.INVALID_WINDOWING_MODE;
 import static android.app.FullscreenRequestHandler.REMOTE_CALLBACK_RESULT_KEY;
@@ -818,6 +819,13 @@
                                 null /*startTask */, null /* remoteTransition */,
                                 null /* displayChange */);
                         r.mTransitionController.setReady(r.getDisplayContent());
+                        if (under != null && under.returningOptions != null
+                                && under.returningOptions.getAnimationType()
+                                        == ANIM_SCENE_TRANSITION) {
+                            // Pass along the scene-transition animation-type
+                            transition.setOverrideAnimation(TransitionInfo.AnimationOptions
+                                    .makeSceneTransitionAnimOptions(), null, null);
+                        }
                     } else {
                         transition.abort();
                     }
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index f71f3b1..c5f63ce 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -294,6 +294,8 @@
         final int mProcessState;
         /** The oom adj score of the launching activity prior to the launch */
         final int mProcessOomAdj;
+        /** Whether the activity is launched above a visible activity in the same task. */
+        final boolean mIsInTaskActivityStart;
         /** Whether the last launched activity has reported drawn. */
         boolean mIsDrawn;
         /** The latest activity to have been launched. */
@@ -330,7 +332,7 @@
         static TransitionInfo create(@NonNull ActivityRecord r,
                 @NonNull LaunchingState launchingState, @Nullable ActivityOptions options,
                 boolean processRunning, boolean processSwitch, int processState, int processOomAdj,
-                boolean newActivityCreated, int startResult) {
+                boolean newActivityCreated, boolean isInTaskActivityStart, int startResult) {
             if (startResult != START_SUCCESS && startResult != START_TASK_TO_FRONT) {
                 return null;
             }
@@ -345,19 +347,21 @@
                 transitionType = TYPE_TRANSITION_COLD_LAUNCH;
             }
             return new TransitionInfo(r, launchingState, options, transitionType, processRunning,
-                    processSwitch, processState, processOomAdj);
+                    processSwitch, processState, processOomAdj, isInTaskActivityStart);
         }
 
         /** Use {@link TransitionInfo#create} instead to ensure the transition type is valid. */
         private TransitionInfo(ActivityRecord r, LaunchingState launchingState,
                 ActivityOptions options, int transitionType, boolean processRunning,
-                boolean processSwitch, int processState, int processOomAdj) {
+                boolean processSwitch, int processState, int processOomAdj,
+                boolean isInTaskActivityStart) {
             mLaunchingState = launchingState;
             mTransitionType = transitionType;
             mProcessRunning = processRunning;
             mProcessSwitch = processSwitch;
             mProcessState = processState;
             mProcessOomAdj = processOomAdj;
+            mIsInTaskActivityStart = isInTaskActivityStart;
             setLatestLaunchedActivity(r);
             // The launching state can be reused by consecutive launch. Its original association
             // shouldn't be changed by a separated transition.
@@ -515,7 +519,7 @@
             }
         }
 
-        boolean isIntresetedToEventLog() {
+        boolean isInterestedToEventLog() {
             return type == TYPE_TRANSITION_WARM_LAUNCH || type == TYPE_TRANSITION_COLD_LAUNCH;
         }
 
@@ -728,9 +732,10 @@
             return;
         }
 
+        final boolean isInTaskActivityStart = launchedActivity.getTask().isVisible();
         final TransitionInfo newInfo = TransitionInfo.create(launchedActivity, launchingState,
                 options, processRunning, processSwitch, processState, processOomAdj,
-                newActivityCreated, resultCode);
+                newActivityCreated, isInTaskActivityStart, resultCode);
         if (newInfo == null) {
             abort(launchingState, "unrecognized launch");
             return;
@@ -1042,18 +1047,23 @@
         // Take a snapshot of the transition info before sending it to the handler for logging.
         // This will avoid any races with other operations that modify the ActivityRecord.
         final TransitionInfoSnapshot infoSnapshot = new TransitionInfoSnapshot(info);
-        if (info.isInterestingToLoggerAndObserver()) {
-            final long uptimeNs = info.mLaunchingState.mStartUptimeNs;
-            final int transitionDelay = info.mCurrentTransitionDelayMs;
-            final int processState = info.mProcessState;
-            final int processOomAdj = info.mProcessOomAdj;
-            mLoggerHandler.post(() -> logAppTransition(
-                    uptimeNs, transitionDelay, infoSnapshot, isHibernating,
-                    processState, processOomAdj));
-        }
-        if (infoSnapshot.isIntresetedToEventLog()) {
-            mLoggerHandler.post(() -> logAppDisplayed(infoSnapshot));
-        }
+        final boolean isOpaque = info.mLastLaunchedActivity.mStyleFillsParent;
+        final long uptimeNs = info.mLaunchingState.mStartUptimeNs;
+        final int transitionDelay = info.mCurrentTransitionDelayMs;
+        final int processState = info.mProcessState;
+        final int processOomAdj = info.mProcessOomAdj;
+        mLoggerHandler.post(() -> {
+            if (info.isInterestingToLoggerAndObserver()) {
+                logAppTransition(uptimeNs, transitionDelay, infoSnapshot, isHibernating,
+                        processState, processOomAdj);
+            }
+            if (info.mIsInTaskActivityStart) {
+                logInTaskActivityStart(infoSnapshot, isOpaque, transitionDelay);
+            }
+            if (infoSnapshot.isInterestedToEventLog()) {
+                logAppDisplayed(infoSnapshot);
+            }
+        });
         if (info.mPendingFullyDrawn != null) {
             info.mPendingFullyDrawn.run();
         }
@@ -1158,6 +1168,22 @@
         return info != null && info.isLoading();
     }
 
+    @VisibleForTesting
+    void logInTaskActivityStart(TransitionInfoSnapshot info, boolean isOpaque,
+            int transitionDelayMs) {
+        if (DEBUG_METRICS) {
+            Slog.i(TAG, "IN_TASK_ACTIVITY_STARTED " + info.launchedActivityName
+                    + " transitionDelayMs=" + transitionDelayMs + "ms");
+        }
+        FrameworkStatsLog.write(FrameworkStatsLog.IN_TASK_ACTIVITY_STARTED,
+                info.applicationInfo.uid,
+                getAppStartTransitionType(info.type, info.relaunched),
+                isOpaque,
+                transitionDelayMs,
+                info.windowsDrawnDelayMs,
+                TimeUnit.NANOSECONDS.toMillis(info.timestampNs));
+    }
+
     private void logAppDisplayed(TransitionInfoSnapshot info) {
         EventLog.writeEvent(WM_ACTIVITY_LAUNCH_TIME,
                 info.userId, info.activityRecordIdHashCode, info.launchedActivityShortComponentName,
@@ -1228,7 +1254,7 @@
                         currentTimestampNs - info.mLaunchingState.mStartUptimeNs);
         final TransitionInfoSnapshot infoSnapshot =
                 new TransitionInfoSnapshot(info, r, (int) startupTimeMs);
-        if (infoSnapshot.isIntresetedToEventLog()) {
+        if (infoSnapshot.isInterestedToEventLog()) {
             mLoggerHandler.post(() -> logAppFullyDrawn(infoSnapshot));
         }
         mLastTransitionInfo.remove(r);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 1e50f3d..3db0315 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -78,7 +78,6 @@
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
-import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO;
 import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_EXCLUDE_PORTRAIT_FULLSCREEN;
 import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_LARGE;
 import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM;
@@ -94,6 +93,7 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.content.pm.ActivityInfo.SIZE_CHANGES_SUPPORTED_METADATA;
 import static android.content.pm.ActivityInfo.SIZE_CHANGES_SUPPORTED_OVERRIDE;
+import static android.content.pm.ActivityInfo.SIZE_CHANGES_UNSUPPORTED_METADATA;
 import static android.content.pm.ActivityInfo.SIZE_CHANGES_UNSUPPORTED_OVERRIDE;
 import static android.content.res.Configuration.ASSETS_SEQ_UNDEFINED;
 import static android.content.res.Configuration.EMPTY;
@@ -712,7 +712,7 @@
      * when running ANIM_SCENE_TRANSITION.
      * @see WindowContainer#providesOrientation()
      */
-    private final boolean mStyleFillsParent;
+    final boolean mStyleFillsParent;
 
     // The input dispatching timeout for this application token in milliseconds.
     long mInputDispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
@@ -1299,7 +1299,7 @@
                         + info.getManifestMinAspectRatio());
             }
             pw.println(prefix + "supportsSizeChanges="
-                    + ActivityInfo.sizeChangesSupportModeToString(info.supportsSizeChanges()));
+                    + ActivityInfo.sizeChangesSupportModeToString(supportsSizeChanges()));
             if (info.configChanges != 0) {
                 pw.println(prefix + "configChanges=0x" + Integer.toHexString(info.configChanges));
             }
@@ -3560,7 +3560,7 @@
                 // Note that RecentsAnimation will handle task snapshot while switching apps with
                 // the best capture timing (e.g. IME window capture),
                 // No need additional task capture while task is controlled by RecentsAnimation.
-                if (mAtmService.mWindowManager.mTaskSnapshotController != null
+                if (!mTransitionController.isShellTransitionsEnabled()
                         && !task.isAnimatingByRecents()) {
                     final ArraySet<Task> tasks = Sets.newArraySet(task);
                     mAtmService.mWindowManager.mTaskSnapshotController.snapshotTasks(tasks);
@@ -3570,6 +3570,14 @@
 
                 // Tell window manager to prepare for this one to be removed.
                 setVisibility(false);
+                // Propagate the last IME visibility in the same task, so the IME can show
+                // automatically if the next activity has a focused editable view.
+                if (mLastImeShown && mTransitionController.isShellTransitionsEnabled()) {
+                    final ActivityRecord nextRunning = task.topRunningActivity();
+                    if (nextRunning != null) {
+                        nextRunning.mLastImeShown = true;
+                    }
+                }
 
                 if (getTaskFragment().getPausingActivity() == null) {
                     ProtoLog.v(WM_DEBUG_STATES, "Finish needs to pause: %s", this);
@@ -8128,7 +8136,7 @@
      *         aspect ratio.
      */
     boolean shouldCreateCompatDisplayInsets() {
-        switch (info.supportsSizeChanges()) {
+        switch (supportsSizeChanges()) {
             case SIZE_CHANGES_SUPPORTED_METADATA:
             case SIZE_CHANGES_SUPPORTED_OVERRIDE:
                 return false;
@@ -8155,6 +8163,26 @@
                 && isActivityTypeStandardOrUndefined();
     }
 
+    /**
+     * Returns whether the activity supports size changes.
+     */
+    @ActivityInfo.SizeChangesSupportMode
+    private int supportsSizeChanges() {
+        if (mLetterboxUiController.shouldOverrideForceNonResizeApp()) {
+            return SIZE_CHANGES_UNSUPPORTED_OVERRIDE;
+        }
+
+        if (info.supportsSizeChanges) {
+            return SIZE_CHANGES_SUPPORTED_METADATA;
+        }
+
+        if (mLetterboxUiController.shouldOverrideForceResizeApp()) {
+            return SIZE_CHANGES_SUPPORTED_OVERRIDE;
+        }
+
+        return SIZE_CHANGES_UNSUPPORTED_METADATA;
+    }
+
     @Override
     boolean hasSizeCompatBounds() {
         return mSizeCompatBounds != null;
@@ -8446,21 +8474,23 @@
     private void updateResolvedBoundsPosition(Configuration newParentConfiguration) {
         final Configuration resolvedConfig = getResolvedOverrideConfiguration();
         final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
+        if (resolvedBounds.isEmpty()) {
+            return;
+        }
         final Rect screenResolvedBounds =
                 mSizeCompatBounds != null ? mSizeCompatBounds : resolvedBounds;
         final Rect parentAppBounds = newParentConfiguration.windowConfiguration.getAppBounds();
         final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds();
-        if (resolvedBounds.isEmpty()) {
-            return;
-        }
+        final float screenResolvedBoundsWidth = screenResolvedBounds.width();
+        final float parentAppBoundsWidth = parentAppBounds.width();
         // Horizontal position
         int offsetX = 0;
-        if (parentBounds.width() != screenResolvedBounds.width()) {
-            if (screenResolvedBounds.width() <= parentAppBounds.width()) {
+        if (parentBounds.width() != screenResolvedBoundsWidth) {
+            if (screenResolvedBoundsWidth <= parentAppBoundsWidth) {
                 float positionMultiplier = mLetterboxUiController.getHorizontalPositionMultiplier(
                         newParentConfiguration);
-                offsetX = Math.max(0, (int) Math.ceil((parentAppBounds.width()
-                        - screenResolvedBounds.width()) * positionMultiplier)
+                offsetX = Math.max(0, (int) Math.ceil((parentAppBoundsWidth
+                        - screenResolvedBoundsWidth) * positionMultiplier)
                         // This is added to make sure that insets added inside
                         // CompatDisplayInsets#getContainerBounds() do not break the alignment
                         // provided by the positionMultiplier
@@ -8468,14 +8498,21 @@
             }
         }
 
+        final float parentAppBoundsHeight = parentAppBounds.height();
+        final float parentBoundsHeight = parentBounds.height();
+        final float screenResolvedBoundsHeight = screenResolvedBounds.height();
         // Vertical position
         int offsetY = 0;
-        if (parentBounds.height() != screenResolvedBounds.height()) {
-            if (screenResolvedBounds.height() <= parentAppBounds.height()) {
+        if (parentBoundsHeight != screenResolvedBoundsHeight) {
+            if (screenResolvedBoundsHeight <= parentAppBoundsHeight) {
                 float positionMultiplier = mLetterboxUiController.getVerticalPositionMultiplier(
                         newParentConfiguration);
-                offsetY = Math.max(0, (int) Math.ceil((parentAppBounds.height()
-                        - screenResolvedBounds.height()) * positionMultiplier)
+                // If in immersive mode, always align to bottom and overlap bottom insets (nav bar,
+                // task bar) as they are transient and hidden. This removes awkward bottom spacing.
+                final float newHeight = mDisplayContent.getDisplayPolicy().isImmersiveMode()
+                        ? parentBoundsHeight : parentAppBoundsHeight;
+                offsetY = Math.max(0, (int) Math.ceil((newHeight
+                        - screenResolvedBoundsHeight) * positionMultiplier)
                         // This is added to make sure that insets added inside
                         // CompatDisplayInsets#getContainerBounds() do not break the alignment
                         // provided by the positionMultiplier
@@ -9323,8 +9360,7 @@
         if (info.applicationInfo == null) {
             return info.getMinAspectRatio();
         }
-
-        if (!info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO)) {
+        if (!mLetterboxUiController.shouldOverrideMinAspectRatio()) {
             return info.getMinAspectRatio();
         }
 
@@ -10580,6 +10616,7 @@
             return false;
         }
         if (!isVisibleRequested()) return true;
+        if (mPendingRelaunchCount > 0) return false;
         // Wait for attach. That is the earliest time where we know if there will be an associated
         // display rotation. If we don't wait, the starting-window can finishDrawing first and
         // cause the display rotation to end-up in a following transition.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index 9f738ed..32f1f42 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -263,14 +263,16 @@
     public abstract void setVr2dDisplayId(int vr2dDisplayId);
 
     /**
-     * Set focus on an activity.
-     * @param token The activity token.
+     * Registers a {@link ScreenObserver}.
      */
-    public abstract void setFocusedActivity(IBinder token);
-
     public abstract void registerScreenObserver(ScreenObserver observer);
 
     /**
+     * Unregisters the given {@link ScreenObserver}.
+     */
+    public abstract void unregisterScreenObserver(ScreenObserver observer);
+
+    /**
      * Returns is the caller has the same uid as the Recents component
      */
     public abstract boolean isCallerRecents(int callingUid);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 48569f6..4d4ffba 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -296,6 +296,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
@@ -652,7 +653,8 @@
      */
     float mMinPercentageMultiWindowSupportWidth;
 
-    final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
+    final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers =
+            Collections.synchronizedList(new ArrayList<>());
 
     // VR Vr2d Display Id.
     int mVr2dDisplayId = INVALID_DISPLAY;
@@ -3649,6 +3651,8 @@
                     Slog.e(TAG, "Skip enterPictureInPictureMode, destroyed " + r);
                     return;
                 }
+                EventLogTags.writeWmEnterPip(r.mUserId, System.identityHashCode(r),
+                        r.shortComponentName, Boolean.toString(isAutoEnter));
                 r.setPictureInPictureParams(params);
                 r.mAutoEnteringPip = isAutoEnter;
                 mRootWindowContainer.moveActivityToPinnedRootTask(r,
@@ -3789,7 +3793,7 @@
             TaskSnapshot taskSnapshot = mWindowManager.mTaskSnapshotController.getSnapshot(taskId,
                     task.mUserId, true /* restoreFromDisk */, isLowResolution);
             if (taskSnapshot == null && takeSnapshotIfNeeded) {
-                taskSnapshot = takeTaskSnapshot(taskId);
+                taskSnapshot = takeTaskSnapshot(taskId, false /* updateCache */);
             }
             return taskSnapshot;
         } finally {
@@ -3798,7 +3802,7 @@
     }
 
     @Override
-    public TaskSnapshot takeTaskSnapshot(int taskId) {
+    public TaskSnapshot takeTaskSnapshot(int taskId, boolean updateCache) {
         mAmInternal.enforceCallingPermission(READ_FRAME_BUFFER, "takeTaskSnapshot()");
         final long ident = Binder.clearCallingIdentity();
         try {
@@ -3809,8 +3813,13 @@
                     Slog.w(TAG, "takeTaskSnapshot: taskId=" + taskId + " not found or not visible");
                     return null;
                 }
-                return mWindowManager.mTaskSnapshotController.captureSnapshot(
-                        task, true /* snapshotHome */);
+                if (updateCache) {
+                    return mWindowManager.mTaskSnapshotController.recordSnapshot(task,
+                            true /* snapshotHome */);
+                } else {
+                    return mWindowManager.mTaskSnapshotController.captureSnapshot(task,
+                            true /* snapshotHome */);
+                }
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -5337,6 +5346,12 @@
         return null;
     }
 
+    /**
+     * Returns the {@link WindowProcessController} for the app process for the given uid and pid.
+     *
+     * If no such {@link WindowProcessController} is found, it does not belong to an app, or the
+     * pid does not match the uid {@code null} is returned.
+     */
     WindowProcessController getProcessController(int pid, int uid) {
         final WindowProcessController proc = mProcessMap.getProcess(pid);
         if (proc == null) return null;
@@ -5346,6 +5361,27 @@
         return null;
     }
 
+    /**
+     * Returns the package name if (and only if) the package name can be uniquely determined.
+     * Otherwise returns {@code null}.
+     *
+     * The provided pid must match the provided uid, otherwise this also returns null.
+     */
+    @Nullable String getPackageNameIfUnique(int uid, int pid) {
+        final WindowProcessController proc = mProcessMap.getProcess(pid);
+        if (proc == null || proc.mUid != uid) {
+            Slog.w(TAG, "callingPackage for (uid=" + uid + ", pid=" + pid + ") has no WPC");
+            return null;
+        }
+        List<String> realCallingPackages = proc.getPackageList();
+        if (realCallingPackages.size() != 1) {
+            Slog.w(TAG, "callingPackage for (uid=" + uid + ", pid=" + pid + ") is ambiguous: "
+                    + realCallingPackages);
+            return null;
+        }
+        return realCallingPackages.get(0);
+    }
+
     /** A uid is considered to be foreground if it has a visible non-toast window. */
     @HotPath(caller = HotPath.START_SERVICE)
     boolean hasActiveVisibleWindow(int uid) {
@@ -5818,26 +5854,12 @@
         }
 
         @Override
-        public void setFocusedActivity(IBinder token) {
-            synchronized (mGlobalLock) {
-                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
-                if (r == null) {
-                    throw new IllegalArgumentException(
-                            "setFocusedActivity: No activity record matching token=" + token);
-                }
-                if (r.moveFocusableActivityToTop("setFocusedActivity")) {
-                    mRootWindowContainer.resumeFocusedTasksTopActivities();
-                }
-            }
-        }
-
-        @Override
         public int getDisplayId(IBinder token) {
             synchronized (mGlobalLock) {
                 ActivityRecord r = ActivityRecord.forTokenLocked(token);
                 if (r == null) {
                     throw new IllegalArgumentException(
-                            "setFocusedActivity: No activity record matching token=" + token);
+                            "getDisplayId: No activity record matching token=" + token);
                 }
                 return r.getDisplayId();
             }
@@ -5849,6 +5871,11 @@
         }
 
         @Override
+        public void unregisterScreenObserver(ScreenObserver observer) {
+            mScreenObservers.remove(observer);
+        }
+
+        @Override
         public boolean isCallerRecents(int callingUid) {
             return ActivityTaskManagerService.this.isCallerRecents(callingUid);
         }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 0121513..0171c20 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -1074,6 +1074,12 @@
             // Remove the process record so it won't be considered as alive.
             mService.mProcessNames.remove(wpc.mName, wpc.mUid);
             mService.mProcessMap.remove(wpc.getPid());
+        } else if (r.intent.isSandboxActivity(mService.mContext)) {
+            Slog.e(TAG, "Abort sandbox activity launching as no sandbox process to host it.");
+            r.finishIfPossible("No sandbox process for the activity", false /* oomAdj */);
+            r.launchFailed = true;
+            r.detachFromProcess();
+            return;
         }
 
         r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
diff --git a/services/core/java/com/android/server/wm/AppSnapshotLoader.java b/services/core/java/com/android/server/wm/AppSnapshotLoader.java
index 88c4752..ed65a2b 100644
--- a/services/core/java/com/android/server/wm/AppSnapshotLoader.java
+++ b/services/core/java/com/android/server/wm/AppSnapshotLoader.java
@@ -28,6 +28,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.hardware.HardwareBuffer;
+import android.os.SystemClock;
 import android.util.Slog;
 import android.window.TaskSnapshot;
 
@@ -195,8 +196,9 @@
                 taskSize = new Point(proto.taskWidth, proto.taskHeight);
             }
 
-            return new TaskSnapshot(proto.id, topActivityComponent, buffer,
-                    hwBitmap.getColorSpace(), proto.orientation, proto.rotation, taskSize,
+            return new TaskSnapshot(proto.id, SystemClock.elapsedRealtimeNanos(),
+                    topActivityComponent, buffer, hwBitmap.getColorSpace(),
+                    proto.orientation, proto.rotation, taskSize,
                     new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom),
                     new Rect(proto.letterboxInsetLeft, proto.letterboxInsetTop,
                             proto.letterboxInsetRight, proto.letterboxInsetBottom),
diff --git a/services/core/java/com/android/server/wm/AppWarnings.java b/services/core/java/com/android/server/wm/AppWarnings.java
index d22c38e..123a74d 100644
--- a/services/core/java/com/android/server/wm/AppWarnings.java
+++ b/services/core/java/com/android/server/wm/AppWarnings.java
@@ -28,11 +28,13 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.SystemProperties;
 import android.util.AtomicFile;
 import android.util.DisplayMetrics;
 import android.util.Slog;
 import android.util.Xml;
 
+import com.android.internal.util.ArrayUtils;
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
 
@@ -56,6 +58,7 @@
     public static final int FLAG_HIDE_DISPLAY_SIZE = 0x01;
     public static final int FLAG_HIDE_COMPILE_SDK = 0x02;
     public static final int FLAG_HIDE_DEPRECATED_SDK = 0x04;
+    public static final int FLAG_HIDE_DEPRECATED_ABI = 0x08;
 
     private final HashMap<String, Integer> mPackageFlags = new HashMap<>();
 
@@ -68,6 +71,7 @@
     private UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
     private UnsupportedCompileSdkDialog mUnsupportedCompileSdkDialog;
     private DeprecatedTargetSdkVersionDialog mDeprecatedTargetSdkVersionDialog;
+    private DeprecatedAbiDialog mDeprecatedAbiDialog;
 
     /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
     private HashSet<ComponentName> mAlwaysShowUnsupportedCompileSdkWarningActivities =
@@ -166,6 +170,31 @@
     }
 
     /**
+     * Shows the "deprecated abi" warning, if necessary. This can only happen is the device
+     * supports both 64-bit and 32-bit ABIs, and the app only contains 32-bit libraries. The app
+     * cannot be installed if the device only supports 64-bit ABI while the app contains only 32-bit
+     * libraries.
+     *
+     * @param r activity record for which the warning may be displayed
+     */
+    public void showDeprecatedAbiDialogIfNeeded(ActivityRecord r) {
+        final boolean disableDeprecatedAbiDialog = SystemProperties.getBoolean(
+                "debug.wm.disable_deprecated_abi_dialog", false);
+        if (disableDeprecatedAbiDialog) {
+            return;
+        }
+        final String appPrimaryAbi = r.info.applicationInfo.primaryCpuAbi;
+        final String appSecondaryAbi = r.info.applicationInfo.secondaryCpuAbi;
+        final boolean appContainsOnly32bitLibraries =
+                (appPrimaryAbi != null && appSecondaryAbi == null && !appPrimaryAbi.contains("64"));
+        final boolean is64BitDevice =
+                ArrayUtils.find(Build.SUPPORTED_ABIS, abi -> abi.contains("64")) != null;
+        if (is64BitDevice && appContainsOnly32bitLibraries) {
+            mUiHandler.showDeprecatedAbiDialog(r);
+        }
+    }
+
+    /**
      * Called when an activity is being started.
      *
      * @param r record for the activity being started
@@ -174,6 +203,7 @@
         showUnsupportedCompileSdkDialogIfNeeded(r);
         showUnsupportedDisplaySizeDialogIfNeeded(r);
         showDeprecatedTargetDialogIfNeeded(r);
+        showDeprecatedAbiDialogIfNeeded(r);
     }
 
     /**
@@ -299,6 +329,27 @@
     }
 
     /**
+     * Shows the "deprecated abi" warning for the given application.
+     * <p>
+     * <strong>Note:</strong> Must be called on the UI thread.
+     *
+     * @param ar record for the activity that triggered the warning
+     */
+    @UiThread
+    private void showDeprecatedAbiDialogUiThread(ActivityRecord ar) {
+        if (mDeprecatedAbiDialog != null) {
+            mDeprecatedAbiDialog.dismiss();
+            mDeprecatedAbiDialog = null;
+        }
+        if (ar != null && !hasPackageFlag(
+                ar.packageName, FLAG_HIDE_DEPRECATED_ABI)) {
+            mDeprecatedAbiDialog = new DeprecatedAbiDialog(
+                    AppWarnings.this, mUiContext, ar.info.applicationInfo);
+            mDeprecatedAbiDialog.show();
+        }
+    }
+
+    /**
      * Dismisses all warnings for the given package.
      * <p>
      * <strong>Note:</strong> Must be called on the UI thread.
@@ -328,6 +379,13 @@
             mDeprecatedTargetSdkVersionDialog.dismiss();
             mDeprecatedTargetSdkVersionDialog = null;
         }
+
+        // Hides the "deprecated abi" dialog if necessary.
+        if (mDeprecatedAbiDialog != null && (name == null || name.equals(
+                mDeprecatedAbiDialog.mPackageName))) {
+            mDeprecatedAbiDialog.dismiss();
+            mDeprecatedAbiDialog = null;
+        }
     }
 
     /**
@@ -381,6 +439,7 @@
         private static final int MSG_SHOW_UNSUPPORTED_COMPILE_SDK_DIALOG = 3;
         private static final int MSG_HIDE_DIALOGS_FOR_PACKAGE = 4;
         private static final int MSG_SHOW_DEPRECATED_TARGET_SDK_DIALOG = 5;
+        private static final int MSG_SHOW_DEPRECATED_ABI_DIALOG = 6;
 
         public UiHandler(Looper looper) {
             super(looper, null, true);
@@ -408,6 +467,10 @@
                     final ActivityRecord ar = (ActivityRecord) msg.obj;
                     showDeprecatedTargetSdkDialogUiThread(ar);
                 } break;
+                case MSG_SHOW_DEPRECATED_ABI_DIALOG: {
+                    final ActivityRecord ar = (ActivityRecord) msg.obj;
+                    showDeprecatedAbiDialogUiThread(ar);
+                } break;
             }
         }
 
@@ -431,6 +494,11 @@
             obtainMessage(MSG_SHOW_DEPRECATED_TARGET_SDK_DIALOG, r).sendToTarget();
         }
 
+        public void showDeprecatedAbiDialog(ActivityRecord r) {
+            removeMessages(MSG_SHOW_DEPRECATED_ABI_DIALOG);
+            obtainMessage(MSG_SHOW_DEPRECATED_ABI_DIALOG, r).sendToTarget();
+        }
+
         public void hideDialogsForPackage(String name) {
             obtainMessage(MSG_HIDE_DIALOGS_FOR_PACKAGE, name).sendToTarget();
         }
diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
index 778951a..98ee98b 100644
--- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java
+++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
@@ -248,7 +248,10 @@
                     Slog.e(TAG, "WM sent Transaction to organized, but never received" +
                            " commit callback. Application ANR likely to follow.");
                     Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-                    onCommitted(merged);
+                    synchronized (mWm.mGlobalLock) {
+                        onCommitted(merged.mNativeObject != 0
+                                ? merged : mWm.mTransactionFactory.get());
+                    }
                 }
             };
             CommitCallback callback = new CommitCallback();
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index dc49e8c..b216578 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -180,7 +180,8 @@
             Intent intent,
             ActivityOptions checkedOptions) {
         return checkBackgroundActivityStart(callingUid, callingPid, callingPackage,
-                realCallingUid, realCallingPid, callerApp, originatingPendingIntent,
+                realCallingUid, realCallingPid,
+                callerApp, originatingPendingIntent,
                 backgroundStartPrivileges, intent, checkedOptions) == BAL_BLOCK;
     }
 
@@ -288,11 +289,13 @@
             }
         }
 
+        String realCallingPackage = mService.getPackageNameIfUnique(realCallingUid, realCallingPid);
+
         // Legacy behavior allows to use caller foreground state to bypass BAL restriction.
         // The options here are the options passed by the sender and not those on the intent.
         final BackgroundStartPrivileges balAllowedByPiSender =
                 PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller(
-                        checkedOptions, realCallingUid);
+                        checkedOptions, realCallingUid, realCallingPackage);
 
         final boolean logVerdictChangeByPiDefaultChange = checkedOptions == null
                 || checkedOptions.getPendingIntentBackgroundActivityStartMode()
@@ -460,8 +463,11 @@
         // If we are here, it means all exemptions not based on PI sender failed, so we'll block
         // unless resultIfPiSenderAllowsBal is an allow and the PI sender allows BAL
 
-        String realCallingPackage = callingUid == realCallingUid ? callingPackage :
-                mService.mContext.getPackageManager().getNameForUid(realCallingUid);
+        if (realCallingPackage == null) {
+            realCallingPackage = (callingUid == realCallingUid ? callingPackage :
+                    mService.mContext.getPackageManager().getNameForUid(realCallingUid))
+                    + "[debugOnly]";
+        }
 
         String stateDumpLog = " [callingPackage: " + callingPackage
                 + "; callingUid: " + callingUid
diff --git a/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java b/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java
index e88cfbf..527edc1 100644
--- a/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java
+++ b/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java
@@ -190,6 +190,11 @@
                 return false;
             }
             List<IBinder> binderTokens = getOriginatingTokensThatAllowBal();
+            if (binderTokens.isEmpty()) {
+                // no tokens to allow anything
+                return false;
+            }
+
             // The callback will decide.
             return mBackgroundActivityStartCallback.isActivityStartAllowed(
                     binderTokens, uid, packageName);
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index b808a55..6a7e764 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -276,6 +276,12 @@
             return;
         }
 
+        if (mContentRecordingSession.isWaitingForConsent()) {
+            ProtoLog.v(WM_DEBUG_CONTENT_RECORDING, "Content Recording: waiting to record, so do "
+                    + "nothing");
+            return;
+        }
+
         mRecordedWindowContainer = retrieveRecordedWindowContainer();
         if (mRecordedWindowContainer == null) {
             // Either the token is missing, or the window associated with the token is missing.
diff --git a/services/core/java/com/android/server/wm/ContentRecordingController.java b/services/core/java/com/android/server/wm/ContentRecordingController.java
index 040da88..f24ba5a 100644
--- a/services/core/java/com/android/server/wm/ContentRecordingController.java
+++ b/services/core/java/com/android/server/wm/ContentRecordingController.java
@@ -56,8 +56,8 @@
      * Updates the current recording session.
      * <p>Handles the following scenarios:
      * <ul>
-     *         <li>Invalid scenarios: The incoming session is malformed, or the incoming session is
-     *         identical to the current session</li>
+     *         <li>Invalid scenarios: The incoming session is malformed.</li>
+     *         <li>Ignored scenario: the incoming session is identical to the current session.</li>
      *         <li>Start Scenario: Starting a new session. Recording begins immediately.</li>
      *         <li>Takeover Scenario: Occurs during a Start Scenario, if a pre-existing session was
      *         in-progress. For example, recording on VirtualDisplay "app_foo" was ongoing. A
@@ -66,6 +66,8 @@
      *         begin.</li>
      *         <li>Stopping scenario: The incoming session is null and there is currently an ongoing
      *         session. The controller stops recording.</li>
+     *         <li>Updating scenario: There is an update for the same display, where recording
+     *         was previously not taking place but is now permitted to go ahead.</li>
      * </ul>
      *
      * @param incomingSession The incoming recording session (either an update to a current session
@@ -78,32 +80,50 @@
         if (incomingSession != null && !ContentRecordingSession.isValid(incomingSession)) {
             return;
         }
-        // Invalid scenario: ignore identical incoming session.
+        final boolean hasSessionUpdatedWithConsent =
+                mSession != null && incomingSession != null && mSession.isWaitingForConsent()
+                        && !incomingSession.isWaitingForConsent();
         if (ContentRecordingSession.isProjectionOnSameDisplay(mSession, incomingSession)) {
-            // TODO(242833866): if incoming session is no longer waiting to record, allow
-            //  the update through.
-
-            ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
-                    "Content Recording: Ignoring session on same display %d, with an existing "
-                            + "session %s",
-                    incomingSession.getVirtualDisplayId(), mSession.getVirtualDisplayId());
-            return;
+            if (hasSessionUpdatedWithConsent) {
+                // Updating scenario: accept an incoming session updating the current display.
+                ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                        "Content Recording: Accept session updating same display %d with granted "
+                                + "consent, with an existing session %s",
+                        incomingSession.getVirtualDisplayId(), mSession.getVirtualDisplayId());
+            } else {
+                // Ignored scenario: ignore identical incoming session.
+                ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                        "Content Recording: Ignoring session on same display %d, with an existing "
+                                + "session %s",
+                        incomingSession.getVirtualDisplayId(), mSession.getVirtualDisplayId());
+                return;
+            }
         }
         DisplayContent incomingDisplayContent = null;
-        // Start scenario: recording begins immediately.
         if (incomingSession != null) {
+            // Start scenario: recording begins immediately.
             ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
                     "Content Recording: Handle incoming session on display %d, with a "
                             + "pre-existing session %s", incomingSession.getVirtualDisplayId(),
                     mSession == null ? null : mSession.getVirtualDisplayId());
             incomingDisplayContent = wmService.mRoot.getDisplayContentOrCreate(
                     incomingSession.getVirtualDisplayId());
+            if (incomingDisplayContent == null) {
+                ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                        "Content Recording: Incoming session on display %d can't be set since it "
+                                + "is already null; the corresponding VirtualDisplay must have "
+                                + "already been removed.", incomingSession.getVirtualDisplayId());
+                return;
+            }
             incomingDisplayContent.setContentRecordingSession(incomingSession);
-            // TODO(b/270118861): When user grants consent to re-use, explicitly ask ContentRecorder
-            //  to update, since no config/display change arrives. Mark recording as black.
+            // Updating scenario: Explicitly ask ContentRecorder to update, since no config or
+            // display change will trigger an update from the DisplayContent.
+            if (hasSessionUpdatedWithConsent) {
+                incomingDisplayContent.updateRecording();
+            }
         }
         // Takeover and stopping scenario: stop recording on the pre-existing session.
-        if (mSession != null) {
+        if (mSession != null && !hasSessionUpdatedWithConsent) {
             ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
                     "Content Recording: Pause the recording session on display %s",
                     mDisplayContent.getDisplayId());
diff --git a/services/core/java/com/android/server/wm/DeprecatedAbiDialog.java b/services/core/java/com/android/server/wm/DeprecatedAbiDialog.java
new file mode 100644
index 0000000..e96208d
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DeprecatedAbiDialog.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.view.Window;
+import android.view.WindowManager;
+
+import com.android.internal.R;
+
+class DeprecatedAbiDialog extends AppWarnings.BaseDialog {
+    DeprecatedAbiDialog(final AppWarnings manager, Context context,
+            ApplicationInfo appInfo) {
+        super(manager, appInfo.packageName);
+
+        final PackageManager pm = context.getPackageManager();
+        final CharSequence label = appInfo.loadSafeLabel(pm,
+                PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,
+                PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE
+                        | PackageItemInfo.SAFE_LABEL_FLAG_TRIM);
+        final CharSequence message = context.getString(R.string.deprecated_abi_message);
+
+        final AlertDialog.Builder builder = new AlertDialog.Builder(context)
+                .setPositiveButton(R.string.ok, (dialog, which) ->
+                    manager.setPackageFlag(
+                            mPackageName, AppWarnings.FLAG_HIDE_DEPRECATED_ABI, true))
+                .setMessage(message)
+                .setTitle(label);
+
+        // Ensure the content view is prepared.
+        mDialog = builder.create();
+        mDialog.create();
+
+        final Window window = mDialog.getWindow();
+        window.setType(WindowManager.LayoutParams.TYPE_PHONE);
+
+        // DO NOT MODIFY. Used by CTS to verify the dialog is displayed.
+        window.getAttributes().setTitle("DeprecatedAbiDialog");
+    }
+}
diff --git a/services/core/java/com/android/server/wm/DeviceStateController.java b/services/core/java/com/android/server/wm/DeviceStateController.java
index 270b2f8..41c052d 100644
--- a/services/core/java/com/android/server/wm/DeviceStateController.java
+++ b/services/core/java/com/android/server/wm/DeviceStateController.java
@@ -16,11 +16,13 @@
 
 package com.android.server.wm;
 
+import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.content.Context;
 import android.hardware.devicestate.DeviceStateManager;
 import android.os.Handler;
 import android.os.HandlerExecutor;
+import android.util.ArrayMap;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
@@ -29,6 +31,8 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
 /**
@@ -37,6 +41,9 @@
  */
 final class DeviceStateController implements DeviceStateManager.DeviceStateCallback {
 
+    // Used to synchronize WindowManager services call paths with DeviceStateManager's callbacks.
+    @NonNull
+    private final WindowManagerGlobalLock mWmLock;
     @NonNull
     private final DeviceStateManager mDeviceStateManager;
     @NonNull
@@ -50,10 +57,10 @@
     private final int mConcurrentDisplayDeviceState;
     @NonNull
     private final int[] mReverseRotationAroundZAxisStates;
-    @GuardedBy("this")
+    @GuardedBy("mWmLock")
     @NonNull
     @VisibleForTesting
-    final List<Consumer<DeviceState>> mDeviceStateCallbacks = new ArrayList<>();
+    final Map<Consumer<DeviceState>, Executor> mDeviceStateCallbacks = new ArrayMap<>();
 
     private final boolean mMatchBuiltInDisplayOrientationToDefaultDisplay;
 
@@ -70,7 +77,9 @@
         CONCURRENT,
     }
 
-    DeviceStateController(@NonNull Context context, @NonNull Handler handler) {
+    DeviceStateController(@NonNull Context context, @NonNull Handler handler,
+            @NonNull WindowManagerGlobalLock wmLock) {
+        mWmLock = wmLock;
         mDeviceStateManager = context.getSystemService(DeviceStateManager.class);
 
         mOpenDeviceStates = context.getResources()
@@ -94,14 +103,20 @@
         }
     }
 
-    void registerDeviceStateCallback(@NonNull Consumer<DeviceState> callback) {
-        synchronized (this) {
-            mDeviceStateCallbacks.add(callback);
+    /**
+     * Registers a callback to be notified when the device state changes. Callers should always
+     * post the work onto their own worker thread to avoid holding the WindowManagerGlobalLock for
+     * an extended period of time.
+     */
+    void registerDeviceStateCallback(@NonNull Consumer<DeviceState> callback,
+            @NonNull @CallbackExecutor Executor executor) {
+        synchronized (mWmLock) {
+            mDeviceStateCallbacks.put(callback, executor);
         }
     }
 
     void unregisterDeviceStateCallback(@NonNull Consumer<DeviceState> callback) {
-        synchronized (this) {
+        synchronized (mWmLock) {
             mDeviceStateCallbacks.remove(callback);
         }
     }
@@ -144,11 +159,21 @@
         if (mCurrentDeviceState == null || !mCurrentDeviceState.equals(deviceState)) {
             mCurrentDeviceState = deviceState;
 
-            synchronized (this) {
-                for (Consumer<DeviceState> callback : mDeviceStateCallbacks) {
-                    callback.accept(mCurrentDeviceState);
+            // Make a copy here because it's possible that the consumer tries to remove a callback
+            // while we're still iterating through the list, which would end up in a
+            // ConcurrentModificationException.
+            final List<Map.Entry<Consumer<DeviceState>, Executor>> entries = new ArrayList<>();
+            synchronized (mWmLock) {
+                for (Map.Entry<Consumer<DeviceState>, Executor> entry
+                        : mDeviceStateCallbacks.entrySet()) {
+                    entries.add(entry);
                 }
             }
+
+            for (int i = 0; i < entries.size(); i++) {
+                Map.Entry<Consumer<DeviceState>, Executor> entry = entries.get(i);
+                entry.getValue().execute(() -> entry.getKey().accept(mCurrentDeviceState));
+            }
         }
     }
 }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index fa5da30..e44d279 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -188,6 +188,7 @@
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.Handler;
+import android.os.HandlerExecutor;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.PowerManager;
@@ -1182,7 +1183,8 @@
                     mDisplaySwitchTransitionLauncher.foldStateChanged(newFoldState);
                     mDisplayRotation.foldStateChanged(newFoldState);
                 };
-        mDeviceStateController.registerDeviceStateCallback(mDeviceStateConsumer);
+        mDeviceStateController.registerDeviceStateCallback(mDeviceStateConsumer,
+                new HandlerExecutor(mWmService.mH));
 
         mCloseToSquareMaxAspectRatio = mWmService.mContext.getResources().getFloat(
                 R.dimen.config_closeToSquareDisplayMaxAspectRatio);
@@ -2962,6 +2964,7 @@
                 mDisplaySwitchTransitionLauncher.requestDisplaySwitchTransitionIfNeeded(mDisplayId,
                         mInitialDisplayWidth, mInitialDisplayHeight, newWidth, newHeight);
                 mDisplayRotation.physicalDisplayChanged();
+                mDisplayPolicy.physicalDisplayChanged();
             }
 
             // If there is an override set for base values - use it, otherwise use new values.
@@ -2993,6 +2996,7 @@
             reconfigureDisplayLocked();
 
             if (physicalDisplayChanged) {
+                mDisplayPolicy.physicalDisplayUpdated();
                 mDisplaySwitchTransitionLauncher.onDisplayUpdated(currentRotation, getRotation(),
                         getDisplayAreaInfo());
             }
@@ -3042,7 +3046,7 @@
                         + mBaseDisplayHeight + " on display:" + getDisplayId());
             }
         }
-        if (mDisplayReady) {
+        if (mDisplayReady && !mDisplayPolicy.shouldKeepCurrentDecorInsets()) {
             mDisplayPolicy.mDecorInsets.invalidate();
         }
     }
@@ -6691,9 +6695,10 @@
 
     /**
      * Start recording if this DisplayContent no longer has content. Stop recording if it now
-     * has content or the display is not on.
+     * has content or the display is not on. Update recording if the content has changed (for
+     * example, the user has granted consent to token re-use, so we can now start mirroring).
      */
-    @VisibleForTesting void updateRecording() {
+    void updateRecording() {
         if (mContentRecorder == null || !mContentRecorder.isContentRecordingSessionSet()) {
             if (!setDisplayMirroring()) {
                 return;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index db64b43..46141f8 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -174,6 +174,10 @@
 
     private static final int INSETS_OVERRIDE_INDEX_INVALID = -1;
 
+    // TODO(b/266197298): Remove this by a more general protocol from the insets providers.
+    private static final boolean USE_CACHED_INSETS_FOR_DISPLAY_SWITCH =
+            SystemProperties.getBoolean("persist.wm.debug.cached_insets_switch", false);
+
     private final WindowManagerService mService;
     private final Context mContext;
     private final Context mUiContext;
@@ -218,7 +222,10 @@
     private SystemGesturesPointerEventListener mSystemGestures;
 
     final DecorInsets mDecorInsets;
+    /** Currently it can only be non-null when physical display switch happens. */
+    private DecorInsets.Cache mCachedDecorInsets;
 
+    @WindowManagerFuncs.LidState
     private volatile int mLidState = LID_ABSENT;
     private volatile int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
     private volatile boolean mHdmiPlugged;
@@ -746,10 +753,11 @@
         return mNavigationBarCanMove;
     }
 
-    public void setLidState(int lidState) {
+    public void setLidState(@WindowManagerFuncs.LidState int lidState) {
         mLidState = lidState;
     }
 
+    @WindowManagerFuncs.LidState
     public int getLidState() {
         return mLidState;
     }
@@ -1248,6 +1256,10 @@
         return mNavigationBar;
     }
 
+    boolean isImmersiveMode() {
+        return mIsImmersiveMode;
+    }
+
     /**
      * Control the animation to run when a window's state changes.  Return a positive number to
      * force the animation to a specific resource ID, {@link #ANIMATION_STYLEABLE} to use the
@@ -1707,11 +1719,7 @@
      * Called when the configuration has changed, and it's safe to load new values from resources.
      */
     public void onConfigurationChanged() {
-        final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
-
         final Resources res = getCurrentUserResources();
-        final int portraitRotation = displayRotation.getPortraitRotation();
-
         mNavBarOpacityMode = res.getInteger(R.integer.config_navBarOpacityMode);
         mLeftGestureInset = mGestureNavigationSettingsObserver.getLeftSensitivity(res);
         mRightGestureInset = mGestureNavigationSettingsObserver.getRightSensitivity(res);
@@ -1882,10 +1890,11 @@
 
             @Override
             public String toString() {
-                return "{nonDecorInsets=" + mNonDecorInsets
-                        + ", configInsets=" + mConfigInsets
-                        + ", nonDecorFrame=" + mNonDecorFrame
-                        + ", configFrame=" + mConfigFrame + '}';
+                final StringBuilder tmpSb = new StringBuilder(32);
+                return "{nonDecorInsets=" + mNonDecorInsets.toShortString(tmpSb)
+                        + ", configInsets=" + mConfigInsets.toShortString(tmpSb)
+                        + ", nonDecorFrame=" + mNonDecorFrame.toShortString(tmpSb)
+                        + ", configFrame=" + mConfigFrame.toShortString(tmpSb) + '}';
             }
         }
 
@@ -1923,6 +1932,39 @@
                 info.mNeedUpdate = true;
             }
         }
+
+        void setTo(DecorInsets src) {
+            for (int i = mInfoForRotation.length - 1; i >= 0; i--) {
+                mInfoForRotation[i].set(src.mInfoForRotation[i]);
+            }
+        }
+
+        void dump(String prefix, PrintWriter pw) {
+            for (int rotation = 0; rotation < mInfoForRotation.length; rotation++) {
+                final DecorInsets.Info info = mInfoForRotation[rotation];
+                pw.println(prefix + Surface.rotationToString(rotation) + "=" + info);
+            }
+        }
+
+        private static class Cache {
+            /**
+             * If {@link #mPreserveId} is this value, it is in the middle of updating display
+             * configuration before a transition is started. Then the active cache should be used.
+             */
+            static final int ID_UPDATING_CONFIG = -1;
+            final DecorInsets mDecorInsets;
+            int mPreserveId;
+            boolean mActive;
+
+            Cache(DisplayContent dc) {
+                mDecorInsets = new DecorInsets(dc);
+            }
+
+            boolean canPreserve() {
+                return mPreserveId == ID_UPDATING_CONFIG || mDecorInsets.mDisplayContent
+                        .mTransitionController.inTransition(mPreserveId);
+            }
+        }
     }
 
     /**
@@ -1930,6 +1972,9 @@
      * call {@link DisplayContent#sendNewConfiguration()} if this method returns {@code true}.
      */
     boolean updateDecorInsetsInfo() {
+        if (shouldKeepCurrentDecorInsets()) {
+            return false;
+        }
         final DisplayFrames displayFrames = mDisplayContent.mDisplayFrames;
         final int rotation = displayFrames.mRotation;
         final int dw = displayFrames.mWidth;
@@ -1940,6 +1985,10 @@
         if (newInfo.mConfigFrame.equals(currentInfo.mConfigFrame)) {
             return false;
         }
+        if (mCachedDecorInsets != null && !mCachedDecorInsets.canPreserve()
+                && !mDisplayContent.isSleeping()) {
+            mCachedDecorInsets = null;
+        }
         mDecorInsets.invalidate();
         mDecorInsets.mInfoForRotation[rotation].set(newInfo);
         return true;
@@ -1949,6 +1998,71 @@
         return mDecorInsets.get(rotation, w, h);
     }
 
+    /** Returns {@code true} to trust that {@link #mDecorInsets} already has the expected state. */
+    boolean shouldKeepCurrentDecorInsets() {
+        return mCachedDecorInsets != null && mCachedDecorInsets.mActive
+                && mCachedDecorInsets.canPreserve();
+    }
+
+    void physicalDisplayChanged() {
+        if (USE_CACHED_INSETS_FOR_DISPLAY_SWITCH) {
+            updateCachedDecorInsets();
+        }
+    }
+
+    /**
+     * Caches the current insets and switches current insets to previous cached insets. This is to
+     * reduce multiple display configuration changes if there are multiple insets provider windows
+     * which may trigger {@link #updateDecorInsetsInfo()} individually.
+     */
+    @VisibleForTesting
+    void updateCachedDecorInsets() {
+        DecorInsets prevCache = null;
+        if (mCachedDecorInsets == null) {
+            mCachedDecorInsets = new DecorInsets.Cache(mDisplayContent);
+        } else {
+            prevCache = new DecorInsets(mDisplayContent);
+            prevCache.setTo(mCachedDecorInsets.mDecorInsets);
+        }
+        // Set a special id to preserve it before a real id is available from transition.
+        mCachedDecorInsets.mPreserveId = DecorInsets.Cache.ID_UPDATING_CONFIG;
+        // Cache the current insets.
+        mCachedDecorInsets.mDecorInsets.setTo(mDecorInsets);
+        // Switch current to previous cache.
+        if (prevCache != null) {
+            mDecorInsets.setTo(prevCache);
+            mCachedDecorInsets.mActive = true;
+        }
+    }
+
+    /**
+     * Called after the display configuration is updated according to the physical change. Suppose
+     * there should be a display change transition, so associate the cached decor insets with the
+     * transition to limit the lifetime of using the cache.
+     */
+    void physicalDisplayUpdated() {
+        if (mCachedDecorInsets == null) {
+            return;
+        }
+        if (!mDisplayContent.mTransitionController.isCollecting()) {
+            // Unable to know when the display switch is finished.
+            mCachedDecorInsets = null;
+            return;
+        }
+        mCachedDecorInsets.mPreserveId =
+                mDisplayContent.mTransitionController.getCollectingTransitionId();
+        // The validator will run after the transition is finished. So if the insets are changed
+        // during the transition, it can update to the latest state.
+        mDisplayContent.mTransitionController.mStateValidators.add(() -> {
+            // The insets provider client may defer to change its window until screen is on. So
+            // only validate when awake to avoid the cache being always dropped.
+            if (!mDisplayContent.isSleeping() && updateDecorInsetsInfo()) {
+                Slog.d(TAG, "Insets changed after display switch transition");
+                mDisplayContent.sendNewConfiguration();
+            }
+        });
+    }
+
     @NavigationBarPosition
     int navigationBarPosition(int displayRotation) {
         if (mNavigationBar != null) {
@@ -2626,9 +2740,10 @@
         pw.print(prefix); pw.print("mRemoteInsetsControllerControlsSystemBars=");
         pw.println(mRemoteInsetsControllerControlsSystemBars);
         pw.print(prefix); pw.println("mDecorInsetsInfo:");
-        for (int rotation = 0; rotation < mDecorInsets.mInfoForRotation.length; rotation++) {
-            final DecorInsets.Info info = mDecorInsets.mInfoForRotation[rotation];
-            pw.println(prefixInner + Surface.rotationToString(rotation) + "=" + info);
+        mDecorInsets.dump(prefixInner, pw);
+        if (mCachedDecorInsets != null) {
+            pw.print(prefix); pw.println("mCachedDecorInsets:");
+            mCachedDecorInsets.mDecorInsets.dump(prefixInner, pw);
         }
         if (!CLIENT_TRANSIENT) {
             mSystemGestures.dump(pw, prefix);
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 87de0f6..bc1ddf8 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -513,6 +513,7 @@
             }
 
             if (mDisplayContent.inTransition()
+                    && mDisplayContent.getDisplayPolicy().isScreenOnFully()
                     && !mDisplayContent.mTransitionController.useShellTransitionsRotation()) {
                 // Rotation updates cannot be performed while the previous rotation change animation
                 // is still in progress. Skip this update. We will try updating again after the
diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
index 2b72215..1fbf593 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
@@ -245,7 +245,7 @@
     }
 
     /**
-     * Notifies that animation in {@link ScreenAnimationRotation} has finished.
+     * Notifies that animation in {@link ScreenRotationAnimation} has finished.
      *
      * <p>This class uses this signal as a trigger for notifying the user about forced rotation
      * reason with the {@link Toast}.
diff --git a/services/core/java/com/android/server/wm/EventLogTags.logtags b/services/core/java/com/android/server/wm/EventLogTags.logtags
index 244656c..d957591 100644
--- a/services/core/java/com/android/server/wm/EventLogTags.logtags
+++ b/services/core/java/com/android/server/wm/EventLogTags.logtags
@@ -80,3 +80,6 @@
 
 # Request surface flinger to show / hide the wallpaper surface.
 33001 wm_wallpaper_surface (Display Id|1|5),(Visible|1),(Target|3)
+
+# Entering pip called
+38000 wm_enter_pip (User|1|5),(Token|1|5),(Component Name|3),(is Auto Enter|3)
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index ff2985c..e8a4c1c 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -91,6 +91,21 @@
     }
 
     @Override
+    void setClientVisible(boolean clientVisible) {
+        final boolean wasClientVisible = isClientVisible();
+        super.setClientVisible(clientVisible);
+        // The layer of ImePlaceholder needs to be updated on a higher z-order for
+        // non-activity window (For activity window, IME is already on top of it).
+        if (!wasClientVisible && isClientVisible()) {
+            final InsetsControlTarget imeControlTarget = getControlTarget();
+            if (imeControlTarget != null && imeControlTarget.getWindow() != null
+                    && imeControlTarget.getWindow().mActivityRecord == null) {
+                mDisplayContent.assignWindowLayers(false /* setLayoutNeeded */);
+            }
+        }
+    }
+
+    @Override
     void setServerVisible(boolean serverVisible) {
         mServerVisible = serverVisible;
         if (!mFrozen) {
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 0b960ec..cea886f 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -439,7 +439,10 @@
                                 ? mDisplayContent.getImeInputTarget().getActivityRecord() : null;
                         if (app != null) {
                             mDisplayContent.removeImeSurfaceImmediately();
-                            mDisplayContent.mAtmService.takeTaskSnapshot(app.getTask().mTaskId);
+                            if (app.getTask() != null) {
+                                mDisplayContent.mAtmService.takeTaskSnapshot(app.getTask().mTaskId,
+                                        true /* updateCache */);
+                            }
                         }
                     } else {
                         // Disable IME icon explicitly when IME attached to the app in case
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 5b39790..d83c861 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -17,6 +17,8 @@
 package com.android.server.wm;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.pm.ActivityInfo.FORCE_NON_RESIZE_APP;
+import static android.content.pm.ActivityInfo.FORCE_RESIZE_APP;
 import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION;
 import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
 import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
@@ -25,6 +27,7 @@
 import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
 import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
 import static android.content.pm.ActivityInfo.OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO;
 import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
 import static android.content.pm.ActivityInfo.OVERRIDE_RESPECT_REQUESTED_ORIENTATION;
 import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR;
@@ -49,7 +52,9 @@
 import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE;
 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
 import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;
 import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
 
@@ -185,10 +190,21 @@
     // when dealing with translucent activities.
     private final List<LetterboxUiController> mDestroyListeners = new ArrayList<>();
 
+    // Corresponds to OVERRIDE_MIN_ASPECT_RATIO
+    private final boolean mIsOverrideMinAspectRatio;
+    // Corresponds to FORCE_RESIZE_APP
+    private final boolean mIsOverrideForceResizeApp;
+    // Corresponds to FORCE_NON_RESIZE_APP
+    private final boolean mIsOverrideForceNonResizeApp;
+
     @Nullable
     private final Boolean mBooleanPropertyAllowOrientationOverride;
     @Nullable
     private final Boolean mBooleanPropertyAllowDisplayOrientationOverride;
+    @Nullable
+    private final Boolean mBooleanPropertyAllowMinAspectRatioOverride;
+    @Nullable
+    private final Boolean mBooleanPropertyAllowForceResizeOverride;
 
     /*
      * WindowContainerListener responsible to make translucent activities inherit
@@ -300,6 +316,14 @@
                 readComponentProperty(packageManager, mActivityRecord.packageName,
                         /* gatingCondition */ null,
                         PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE);
+        mBooleanPropertyAllowMinAspectRatioOverride =
+                readComponentProperty(packageManager, mActivityRecord.packageName,
+                        /* gatingCondition */ null,
+                        PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE);
+        mBooleanPropertyAllowForceResizeOverride =
+                readComponentProperty(packageManager, mActivityRecord.packageName,
+                        /* gatingCondition */ null,
+                        PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES);
 
         mIsOverrideAnyOrientationEnabled = isCompatChangeEnabled(OVERRIDE_ANY_ORIENTATION);
         mIsOverrideToPortraitOrientationEnabled =
@@ -330,6 +354,9 @@
 
         mIsOverrideEnableCompatFakeFocusEnabled =
                 isCompatChangeEnabled(OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS);
+        mIsOverrideMinAspectRatio = isCompatChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO);
+        mIsOverrideForceResizeApp = isCompatChangeEnabled(FORCE_RESIZE_APP);
+        mIsOverrideForceNonResizeApp = isCompatChangeEnabled(FORCE_NON_RESIZE_APP);
     }
 
     /**
@@ -502,6 +529,61 @@
     }
 
     /**
+     * Whether we should apply the min aspect ratio per-app override. When this override is applied
+     * the min aspect ratio given in the app's manifest will be overridden to the largest enabled
+     * aspect ratio treatment unless the app's manifest value is higher. The treatment will also
+     * apply if no value is provided in the manifest.
+     *
+     * <p>This method returns {@code true} when the following conditions are met:
+     * <ul>
+     *     <li>Opt-out component property isn't enabled
+     *     <li>Per-app override is enabled
+     * </ul>
+     */
+    boolean shouldOverrideMinAspectRatio() {
+        return shouldEnableWithOptInOverrideAndOptOutProperty(
+                /* gatingCondition */ () -> true,
+                mIsOverrideMinAspectRatio,
+                mBooleanPropertyAllowMinAspectRatioOverride);
+    }
+
+    /**
+     * Whether we should apply the force resize per-app override. When this override is applied it
+     * forces the packages it is applied to to be resizable. It won't change whether the app can be
+     * put into multi-windowing mode, but allow the app to resize without going into size-compat
+     * mode when the window container resizes, such as display size change or screen rotation.
+     *
+     * <p>This method returns {@code true} when the following conditions are met:
+     * <ul>
+     *     <li>Opt-out component property isn't enabled
+     *     <li>Per-app override is enabled
+     * </ul>
+     */
+    boolean shouldOverrideForceResizeApp() {
+        return shouldEnableWithOptInOverrideAndOptOutProperty(
+                /* gatingCondition */ () -> true,
+                mIsOverrideForceResizeApp,
+                mBooleanPropertyAllowForceResizeOverride);
+    }
+
+    /**
+     * Whether we should apply the force non resize per-app override. When this override is applied
+     * it forces the packages it is applied to to be non-resizable.
+     *
+     * <p>This method returns {@code true} when the following conditions are met:
+     * <ul>
+     *     <li>Opt-out component property isn't enabled
+     *     <li>Per-app override is enabled
+     * </ul>
+     */
+    boolean shouldOverrideForceNonResizeApp() {
+        return shouldEnableWithOptInOverrideAndOptOutProperty(
+                /* gatingCondition */ () -> true,
+                mIsOverrideForceNonResizeApp,
+                mBooleanPropertyAllowForceResizeOverride);
+    }
+
+    /**
      * Sets whether an activity is relaunching after the app has called {@link
      * android.app.Activity#setRequestedOrientation}.
      */
@@ -1280,6 +1362,16 @@
 
         final Rect cropBounds = new Rect(mActivityRecord.getBounds());
 
+        // In case of translucent activities we check if the requested size is different from
+        // the size provided using inherited bounds. In that case we decide to not apply rounded
+        // corners because we assume the specific layout would. This is the case when the layout
+        // of the translucent activity uses only a part of all the bounds because of the use of
+        // LayoutParams.WRAP_CONTENT.
+        if (hasInheritedLetterboxBehavior() && (cropBounds.width() != mainWindow.mRequestedWidth
+                || cropBounds.height() != mainWindow.mRequestedHeight)) {
+            return null;
+        }
+
         // It is important to call {@link #adjustBoundsIfNeeded} before {@link cropBounds.offsetTo}
         // because taskbar bounds used in {@link #adjustBoundsIfNeeded}
         // are in screen coordinates
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 0074ebd..5369159 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -438,7 +438,8 @@
         mTaskSupervisor = mService.mTaskSupervisor;
         mTaskSupervisor.mRootWindowContainer = this;
         mDisplayOffTokenAcquirer = mService.new SleepTokenAcquirerImpl(DISPLAY_OFF_SLEEP_TOKEN_TAG);
-        mDeviceStateController = new DeviceStateController(service.mContext, service.mH);
+        mDeviceStateController = new DeviceStateController(service.mContext, service.mH,
+                service.mGlobalLock);
         mDisplayRotationCoordinator = new DisplayRotationCoordinator();
     }
 
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index b7c29bf..bb6f805 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -5673,6 +5673,7 @@
                         }
                         mTransitionController.requestStartTransition(transition, tr,
                                 null /* remoteTransition */, null /* displayChange */);
+                        mTransitionController.collect(tr);
                         moveTaskToBackInner(tr);
                     });
         } else {
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 4d0bff9..c747c09 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -28,6 +28,7 @@
 import android.os.Environment;
 import android.os.Handler;
 import android.util.ArraySet;
+import android.util.IntArray;
 import android.util.Slog;
 import android.view.Display;
 import android.window.ScreenCapture;
@@ -37,8 +38,6 @@
 import com.android.server.policy.WindowManagerPolicy.ScreenOffListener;
 import com.android.server.wm.BaseAppSnapshotPersister.PersistInfoProvider;
 
-import com.google.android.collect.Sets;
-
 import java.util.Set;
 
 /**
@@ -58,7 +57,7 @@
     static final String SNAPSHOTS_DIRNAME = "snapshots";
 
     private final TaskSnapshotPersister mPersister;
-    private final ArraySet<Task> mSkipClosingAppSnapshotTasks = new ArraySet<>();
+    private final IntArray mSkipClosingAppSnapshotTasks = new IntArray();
     private final ArraySet<Task> mTmpTasks = new ArraySet<>();
     private final Handler mHandler = new Handler();
 
@@ -135,26 +134,6 @@
     }
 
     /**
-     * Called when the visibility of an app changes outside of the regular app transition flow.
-     */
-    void notifyAppVisibilityChanged(ActivityRecord appWindowToken, boolean visible) {
-        if (!visible) {
-            handleClosingApps(Sets.newArraySet(appWindowToken));
-        }
-    }
-
-    private void handleClosingApps(ArraySet<ActivityRecord> closingApps) {
-        if (shouldDisableSnapshots()) {
-            return;
-        }
-        // We need to take a snapshot of the task if and only if all activities of the task are
-        // either closing or hidden.
-        getClosingTasks(closingApps, mTmpTasks);
-        snapshotTasks(mTmpTasks);
-        mSkipClosingAppSnapshotTasks.clear();
-    }
-
-    /**
      * Adds the given {@param tasks} to the list of tasks which should not have their snapshots
      * taken upon the next processing of the set of closing apps. The caller is responsible for
      * calling {@link #snapshotTasks} to ensure that the task has an up-to-date snapshot.
@@ -164,20 +143,23 @@
         if (shouldDisableSnapshots()) {
             return;
         }
-        mSkipClosingAppSnapshotTasks.addAll(tasks);
+        for (Task task : tasks) {
+            mSkipClosingAppSnapshotTasks.add(task.mTaskId);
+        }
     }
 
     void snapshotTasks(ArraySet<Task> tasks) {
         snapshotTasks(tasks, false /* allowSnapshotHome */);
     }
 
-    void recordSnapshot(Task task, boolean allowSnapshotHome) {
+    TaskSnapshot recordSnapshot(Task task, boolean allowSnapshotHome) {
         final boolean snapshotHome = allowSnapshotHome && task.isActivityTypeHome();
         final TaskSnapshot snapshot = recordSnapshotInner(task, allowSnapshotHome);
         if (!snapshotHome && snapshot != null) {
             mPersister.persistSnapshot(task.mTaskId, task.mUserId, snapshot);
             task.onSnapshotChanged(snapshot);
         }
+        return snapshot;
     }
 
     private void snapshotTasks(ArraySet<Task> tasks, boolean allowSnapshotHome) {
@@ -198,6 +180,18 @@
     }
 
     /**
+     * Returns the elapsed real time (in nanoseconds) at which a snapshot for the given task was
+     * last taken, or -1 if no such snapshot exists for that task.
+     */
+    long getSnapshotCaptureTime(int taskId) {
+        final TaskSnapshot snapshot = mCache.getSnapshot(taskId);
+        if (snapshot != null) {
+            return snapshot.getCaptureTime();
+        }
+        return -1;
+    }
+
+    /**
      * @see WindowManagerInternal#clearSnapshotCache
      */
     public void clearSnapshotCache() {
@@ -271,31 +265,16 @@
         return source.getTaskDescription();
     }
 
-    /**
-     * Retrieves all closing tasks based on the list of closing apps during an app transition.
-     */
-    @VisibleForTesting
-    void getClosingTasks(ArraySet<ActivityRecord> closingApps, ArraySet<Task> outClosingTasks) {
-        outClosingTasks.clear();
-        for (int i = closingApps.size() - 1; i >= 0; i--) {
-            final ActivityRecord activity = closingApps.valueAt(i);
-            final Task task = activity.getTask();
-            if (task == null) continue;
-
-            getClosingTasksInner(task, outClosingTasks);
-        }
-    }
-
     void getClosingTasksInner(Task task, ArraySet<Task> outClosingTasks) {
         // Since RecentsAnimation will handle task snapshot while switching apps with the
         // best capture timing (e.g. IME window capture),
         // No need additional task capture while task is controlled by RecentsAnimation.
         if (isAnimatingByRecents(task)) {
-            mSkipClosingAppSnapshotTasks.add(task);
+            mSkipClosingAppSnapshotTasks.add(task.mTaskId);
         }
         // If the task of the app is not visible anymore, it means no other app in that task
         // is opening. Thus, the task is closing.
-        if (!task.isVisible() && !mSkipClosingAppSnapshotTasks.contains(task)) {
+        if (!task.isVisible() && mSkipClosingAppSnapshotTasks.indexOf(task.mTaskId) < 0) {
             outClosingTasks.add(task);
         }
     }
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 5e60e921..d5a7ff5 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -21,6 +21,8 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
@@ -380,11 +382,7 @@
             // Add FLAG_ABOVE_TRANSIENT_LAUNCH to the tree of transient-hide tasks,
             // so ChangeInfo#hasChanged() can return true to report the transition info.
             for (int i = mChanges.size() - 1; i >= 0; --i) {
-                final WindowContainer<?> wc = mChanges.keyAt(i);
-                if (wc.asTaskFragment() == null && wc.asActivityRecord() == null) continue;
-                if (isInTransientHide(wc)) {
-                    mChanges.valueAt(i).mFlags |= ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH;
-                }
+                updateTransientFlags(mChanges.valueAt(i));
             }
         }
         ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Transition %d: Set %s as "
@@ -579,7 +577,9 @@
         for (WindowContainer<?> curr = getAnimatableParent(wc);
                 curr != null && !mChanges.containsKey(curr);
                 curr = getAnimatableParent(curr)) {
-            mChanges.put(curr, new ChangeInfo(curr));
+            final ChangeInfo info = new ChangeInfo(curr);
+            updateTransientFlags(info);
+            mChanges.put(curr, info);
             if (isReadyGroup(curr)) {
                 mReadyTracker.addGroup(curr);
                 ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, " Creating Ready-group for"
@@ -598,6 +598,7 @@
         ChangeInfo info = mChanges.get(wc);
         if (info == null) {
             info = new ChangeInfo(wc);
+            updateTransientFlags(info);
             mChanges.put(wc, info);
         }
         mParticipants.add(wc);
@@ -613,6 +614,14 @@
         }
     }
 
+    private void updateTransientFlags(@NonNull ChangeInfo info) {
+        final WindowContainer<?> wc = info.mContainer;
+        // Only look at tasks, taskfragments, or activities
+        if (wc.asTaskFragment() == null && wc.asActivityRecord() == null) return;
+        if (!isInTransientHide(wc)) return;
+        info.mFlags |= ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH;
+    }
+
     private void recordDisplay(DisplayContent dc) {
         if (dc == null || mTargetDisplays.contains(dc)) return;
         mTargetDisplays.add(dc);
@@ -678,7 +687,11 @@
             // All windows are synced already.
             return;
         }
-        if (!isInTransition(wc)) return;
+        if (wc.mDisplayContent == null || !isInTransition(wc)) return;
+        if (!wc.mDisplayContent.getDisplayPolicy().isScreenOnFully()
+                || wc.mDisplayContent.getDisplayInfo().state == Display.STATE_OFF) {
+            mFlags |= WindowManager.TRANSIT_FLAG_INVISIBLE;
+        }
 
         if (mContainerFreezer == null) {
             mContainerFreezer = new ScreenshotFreezer();
@@ -959,8 +972,20 @@
                     true /* beforeStopping */)) {
                 return false;
             }
-            return mController.mAtm.enterPictureInPictureMode(ar, ar.pictureInPictureArgs,
-                    false /* fromClient */, true /* isAutoEnter */);
+            final int prevMode = ar.getTask().getWindowingMode();
+            final boolean inPip = mController.mAtm.enterPictureInPictureMode(ar,
+                    ar.pictureInPictureArgs, false /* fromClient */, true /* isAutoEnter */);
+            final int currentMode = ar.getTask().getWindowingMode();
+            if (prevMode == WINDOWING_MODE_FULLSCREEN && currentMode == WINDOWING_MODE_PINNED
+                    && mTransientLaunches != null
+                    && ar.mDisplayContent.hasTopFixedRotationLaunchingApp()) {
+                // There will be a display configuration change after finishing this transition.
+                // Skip dispatching the change for PiP task to avoid its activity drawing for the
+                // intermediate state which will cause flickering. The final PiP bounds in new
+                // rotation will be applied by PipTransition.
+                ar.mDisplayContent.mPinnedTaskController.setEnterPipTransaction(null);
+            }
+            return inPip;
         }
 
         // Legacy pip-entry (not via isAutoEnterEnabled).
@@ -1065,12 +1090,23 @@
                     if (commitVisibility) {
                         ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
                                 "  Commit activity becoming invisible: %s", ar);
+                        final SnapshotController snapController = mController.mSnapshotController;
                         if (mTransientLaunches != null && !task.isVisibleRequested()) {
+                            final long startTimeNs = mLogger.mSendTimeNs;
+                            final long lastSnapshotTimeNs = snapController.mTaskSnapshotController
+                                    .getSnapshotCaptureTime(task.mTaskId);
                             // If transition is transient, then snapshots are taken at end of
-                            // transition.
-                            mController.mSnapshotController.mTaskSnapshotController
-                                    .recordSnapshot(task, false /* allowSnapshotHome */);
-                            mController.mSnapshotController.mActivitySnapshotController
+                            // transition only if a snapshot was not already captured by request
+                            // during the transition
+                            if (lastSnapshotTimeNs < startTimeNs) {
+                                snapController.mTaskSnapshotController
+                                        .recordSnapshot(task, false /* allowSnapshotHome */);
+                            } else {
+                                ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
+                                        "  Skipping post-transition snapshot for task %d",
+                                        task.mTaskId);
+                            }
+                            snapController.mActivitySnapshotController
                                     .notifyAppVisibilityChanged(ar, false /* visible */);
                         }
                         ar.commitVisibility(false /* visible */, false /* performLayout */,
@@ -1194,6 +1230,13 @@
             if (asyncRotationController != null && containsChangeFor(dc, mTargets)) {
                 asyncRotationController.onTransitionFinished();
             }
+            if (hasParticipatedDisplay && dc.mDisplayRotationCompatPolicy != null) {
+                final ChangeInfo changeInfo = mChanges.get(dc);
+                if (changeInfo != null
+                        && changeInfo.mRotation != dc.getWindowConfiguration().getRotation()) {
+                    dc.mDisplayRotationCompatPolicy.onScreenRotationAnimationFinished();
+                }
+            }
             if (mTransientLaunches != null) {
                 InsetsControlTarget prevImeTarget = dc.getImeTarget(
                         DisplayContent.IME_TARGET_CONTROL);
@@ -1449,6 +1492,9 @@
                 final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord();
                 if (ar == null || ar.getTask() == null
                         || ar.getTask().isVisibleRequested()) continue;
+                final ChangeInfo change = mChanges.get(ar);
+                // Intentionally skip record snapshot for changes originated from PiP.
+                if (change != null && change.mWindowingMode == WINDOWING_MODE_PINNED) continue;
                 mController.mSnapshotController.mTaskSnapshotController.recordSnapshot(
                         ar.getTask(), false /* allowSnapshotHome */);
             }
@@ -1509,7 +1555,7 @@
 
         mController.mLoggerHandler.post(mLogger::logOnSend);
         if (mLogger.mInfo != null) {
-            mController.mTransitionTracer.logSentTransition(this, mTargets, info);
+            mController.mTransitionTracer.logSentTransition(this, mTargets);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index b697ab1..1c6a412 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -431,6 +431,19 @@
         return inCollectingTransition(wc) || inPlayingTransition(wc);
     }
 
+    /** Returns {@code true} if the id matches a collecting or playing transition. */
+    boolean inTransition(int syncId) {
+        if (mCollectingTransition != null && mCollectingTransition.getSyncId() == syncId) {
+            return true;
+        }
+        for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) {
+            if (mPlayingTransitions.get(i).getSyncId() == syncId) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /** @return {@code true} if wc is in a participant subtree */
     boolean isTransitionOnDisplay(@NonNull DisplayContent dc) {
         if (mCollectingTransition != null && mCollectingTransition.isOnDisplay(dc)) {
@@ -503,8 +516,14 @@
      * playing, but can be "opened-up" for certain transition operations like calculating layers
      * for finishTransaction.
      */
-    boolean canAssignLayers() {
-        return mBuildingFinishLayers || !isPlaying();
+    boolean canAssignLayers(@NonNull WindowContainer wc) {
+        // Don't build window state into finish transaction in case another window is added or
+        // removed during transition playing.
+        if (mBuildingFinishLayers) {
+            return wc.asWindowState() == null;
+        }
+        // Always allow WindowState to assign layers since it won't affect transition.
+        return wc.asWindowState() != null || !isPlaying();
     }
 
     @WindowConfiguration.WindowingMode
diff --git a/services/core/java/com/android/server/wm/TransitionTracer.java b/services/core/java/com/android/server/wm/TransitionTracer.java
index a002fba..af8fb02 100644
--- a/services/core/java/com/android/server/wm/TransitionTracer.java
+++ b/services/core/java/com/android/server/wm/TransitionTracer.java
@@ -29,7 +29,6 @@
 import android.os.Trace;
 import android.util.Log;
 import android.util.proto.ProtoOutputStream;
-import android.window.TransitionInfo;
 
 import com.android.internal.util.TraceBuffer;
 import com.android.server.wm.Transition.ChangeInfo;
@@ -49,6 +48,12 @@
 
     private static final int ALWAYS_ON_TRACING_CAPACITY = 15 * 1024; // 15 KB
     private static final int ACTIVE_TRACING_BUFFER_CAPACITY = 5000 * 1024; // 5 MB
+
+    // This will be the size the proto output streams are initialized to.
+    // Ideally this should fit most or all the proto objects we will create and be no bigger than
+    // that to ensure to don't use excessive amounts of memory.
+    private static final int CHUNK_SIZE = 64;
+
     static final String WINSCOPE_EXT = ".winscope";
     private static final String TRACE_FILE =
             "/data/misc/wmtrace/wm_transition_trace" + WINSCOPE_EXT;
@@ -69,26 +74,29 @@
      *
      * @param transition The transition that has been sent to Shell.
      * @param targets Information about the target windows of the transition.
-     * @param info The TransitionInfo send over to Shell to execute the transition.
      */
-    public void logSentTransition(Transition transition, ArrayList<ChangeInfo> targets,
-            TransitionInfo info) {
-        final ProtoOutputStream outputStream = new ProtoOutputStream();
-        final long protoToken = outputStream
-                .start(com.android.server.wm.shell.TransitionTraceProto.TRANSITIONS);
-        outputStream.write(com.android.server.wm.shell.Transition.ID, transition.getSyncId());
-        outputStream.write(com.android.server.wm.shell.Transition.CREATE_TIME_NS,
-                transition.mLogger.mCreateTimeNs);
-        outputStream.write(com.android.server.wm.shell.Transition.SEND_TIME_NS,
-                transition.mLogger.mSendTimeNs);
-        outputStream.write(com.android.server.wm.shell.Transition.START_TRANSACTION_ID,
-                transition.getStartTransaction().getId());
-        outputStream.write(com.android.server.wm.shell.Transition.FINISH_TRANSACTION_ID,
-                transition.getFinishTransaction().getId());
-        dumpTransitionTargetsToProto(outputStream, transition, targets);
-        outputStream.end(protoToken);
+    public void logSentTransition(Transition transition, ArrayList<ChangeInfo> targets) {
+        try {
+            final ProtoOutputStream outputStream = new ProtoOutputStream(CHUNK_SIZE);
+            final long protoToken = outputStream
+                    .start(com.android.server.wm.shell.TransitionTraceProto.TRANSITIONS);
+            outputStream.write(com.android.server.wm.shell.Transition.ID, transition.getSyncId());
+            outputStream.write(com.android.server.wm.shell.Transition.CREATE_TIME_NS,
+                    transition.mLogger.mCreateTimeNs);
+            outputStream.write(com.android.server.wm.shell.Transition.SEND_TIME_NS,
+                    transition.mLogger.mSendTimeNs);
+            outputStream.write(com.android.server.wm.shell.Transition.START_TRANSACTION_ID,
+                    transition.getStartTransaction().getId());
+            outputStream.write(com.android.server.wm.shell.Transition.FINISH_TRANSACTION_ID,
+                    transition.getFinishTransaction().getId());
+            dumpTransitionTargetsToProto(outputStream, transition, targets);
+            outputStream.end(protoToken);
 
-        mTraceBuffer.add(outputStream);
+            mTraceBuffer.add(outputStream);
+        } catch (Exception e) {
+            // Don't let any errors in the tracing cause the transition to fail
+            Log.e(LOG_TAG, "Unexpected exception thrown while logging transitions", e);
+        }
     }
 
     /**
@@ -98,15 +106,20 @@
      * @param transition The transition that has finished.
      */
     public void logFinishedTransition(Transition transition) {
-        final ProtoOutputStream outputStream = new ProtoOutputStream();
-        final long protoToken = outputStream
-                .start(com.android.server.wm.shell.TransitionTraceProto.TRANSITIONS);
-        outputStream.write(com.android.server.wm.shell.Transition.ID, transition.getSyncId());
-        outputStream.write(com.android.server.wm.shell.Transition.FINISH_TIME_NS,
-                transition.mLogger.mFinishTimeNs);
-        outputStream.end(protoToken);
+        try {
+            final ProtoOutputStream outputStream = new ProtoOutputStream(CHUNK_SIZE);
+            final long protoToken = outputStream
+                    .start(com.android.server.wm.shell.TransitionTraceProto.TRANSITIONS);
+            outputStream.write(com.android.server.wm.shell.Transition.ID, transition.getSyncId());
+            outputStream.write(com.android.server.wm.shell.Transition.FINISH_TIME_NS,
+                    transition.mLogger.mFinishTimeNs);
+            outputStream.end(protoToken);
 
-        mTraceBuffer.add(outputStream);
+            mTraceBuffer.add(outputStream);
+        } catch (Exception e) {
+            // Don't let any errors in the tracing cause the transition to fail
+            Log.e(LOG_TAG, "Unexpected exception thrown while logging transitions", e);
+        }
     }
 
     /**
@@ -116,15 +129,20 @@
      * @param transition The transition that has been aborted
      */
     public void logAbortedTransition(Transition transition) {
-        final ProtoOutputStream outputStream = new ProtoOutputStream();
-        final long protoToken = outputStream
-                .start(com.android.server.wm.shell.TransitionTraceProto.TRANSITIONS);
-        outputStream.write(com.android.server.wm.shell.Transition.ID, transition.getSyncId());
-        outputStream.write(com.android.server.wm.shell.Transition.ABORT_TIME_NS,
-                transition.mLogger.mAbortTimeNs);
-        outputStream.end(protoToken);
+        try {
+            final ProtoOutputStream outputStream = new ProtoOutputStream(CHUNK_SIZE);
+            final long protoToken = outputStream
+                    .start(com.android.server.wm.shell.TransitionTraceProto.TRANSITIONS);
+            outputStream.write(com.android.server.wm.shell.Transition.ID, transition.getSyncId());
+            outputStream.write(com.android.server.wm.shell.Transition.ABORT_TIME_NS,
+                    transition.mLogger.mAbortTimeNs);
+            outputStream.end(protoToken);
 
-        mTraceBuffer.add(outputStream);
+            mTraceBuffer.add(outputStream);
+        } catch (Exception e) {
+            // Don't let any errors in the tracing cause the transition to fail
+            Log.e(LOG_TAG, "Unexpected exception thrown while logging transitions", e);
+        }
     }
 
     private void dumpTransitionTargetsToProto(ProtoOutputStream outputStream,
@@ -240,7 +258,7 @@
     private void writeTraceToFileLocked(@Nullable PrintWriter pw, File file) {
         Trace.beginSection("TransitionTracer#writeTraceToFileLocked");
         try {
-            ProtoOutputStream proto = new ProtoOutputStream();
+            ProtoOutputStream proto = new ProtoOutputStream(CHUNK_SIZE);
             proto.write(MAGIC_NUMBER, MAGIC_NUMBER_VALUE);
             long timeOffsetNs =
                     TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis())
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index be5f141..0152666 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -2596,7 +2596,7 @@
     void assignLayer(Transaction t, int layer) {
         // Don't assign layers while a transition animation is playing
         // TODO(b/173528115): establish robust best-practices around z-order fighting.
-        if (!mTransitionController.canAssignLayers()) return;
+        if (!mTransitionController.canAssignLayers(this)) return;
         final boolean changed = layer != mLastLayer || mLastRelativeToLayer != null;
         if (mSurfaceControl != null && changed) {
             setLayer(t, layer);
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 792ec2e..92d4cec 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -449,6 +449,19 @@
     public abstract void moveDisplayToTopIfAllowed(int displayId);
 
     /**
+     * Request to move window input focus to the window with the provided window token.
+     *
+     * <p>
+     * It is necessary to move window input focus before certain actions on views in a window can
+     * be performed, such as opening an IME. Input normally requests to move focus on window touch
+     * so this method should not be necessary in most cases; only features that bypass normal touch
+     * behavior (like Accessibility actions) require this method.
+     * </p>
+     * @param windowToken The window token.
+     */
+    public abstract void requestWindowFocus(IBinder windowToken);
+
+    /**
      * @return Whether the keyguard is engaged.
      */
     public abstract boolean isKeyguardLocked();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 7776132..e33c6f0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -5652,7 +5652,7 @@
                 case ON_POINTER_DOWN_OUTSIDE_FOCUS: {
                     synchronized (mGlobalLock) {
                         final IBinder touchedToken = (IBinder) msg.obj;
-                        onPointerDownOutsideFocusLocked(touchedToken);
+                        onPointerDownOutsideFocusLocked(getInputTargetFromToken(touchedToken));
                     }
                     break;
                 }
@@ -7752,6 +7752,15 @@
         }
 
         @Override
+        public void requestWindowFocus(IBinder windowToken) {
+            synchronized (mGlobalLock) {
+                final InputTarget inputTarget =
+                        WindowManagerService.this.getInputTargetFromWindowTokenLocked(windowToken);
+                WindowManagerService.this.onPointerDownOutsideFocusLocked(inputTarget);
+            }
+        }
+
+        @Override
         public boolean isKeyguardLocked() {
             return WindowManagerService.this.isKeyguardLocked();
         }
@@ -8590,8 +8599,7 @@
         }
     }
 
-    private void onPointerDownOutsideFocusLocked(IBinder touchedToken) {
-        InputTarget t = getInputTargetFromToken(touchedToken);
+    private void onPointerDownOutsideFocusLocked(InputTarget t) {
         if (t == null || !t.receiveFocusFromTapOutside()) {
             // If the window that received the input event cannot receive keys, don't move the
             // display it's on to the top since that window won't be able to get focus anyway.
@@ -9246,7 +9254,6 @@
 
     boolean shouldRestoreImeVisibility(IBinder imeTargetWindowToken) {
         final Task imeTargetWindowTask;
-        boolean hadRequestedShowIme = false;
         synchronized (mGlobalLock) {
             final WindowState imeTargetWindow = mWindowMap.get(imeTargetWindowToken);
             if (imeTargetWindow == null) {
@@ -9256,14 +9263,15 @@
             if (imeTargetWindowTask == null) {
                 return false;
             }
-            if (imeTargetWindow.mActivityRecord != null) {
-                hadRequestedShowIme = imeTargetWindow.mActivityRecord.mLastImeShown;
+            if (imeTargetWindow.mActivityRecord != null
+                    && imeTargetWindow.mActivityRecord.mLastImeShown) {
+                return true;
             }
         }
         final TaskSnapshot snapshot = getTaskSnapshot(imeTargetWindowTask.mTaskId,
                 imeTargetWindowTask.mUserId, false /* isLowResolution */,
                 false /* restoreFromDisk */);
-        return snapshot != null && snapshot.hasImeSurface() || hadRequestedShowIme;
+        return snapshot != null && snapshot.hasImeSurface();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 09312ba..8e85e5b 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -845,11 +845,14 @@
             case HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT: {
                 final WindowContainer wc = WindowContainer.fromBinder(hop.getContainer());
                 final Task task = wc != null ? wc.asTask() : null;
-                if (task != null) {
+                if (task == null) {
+                    throw new IllegalArgumentException("Cannot set non-task as launch root: " + wc);
+                } else if (task.getTaskDisplayArea() == null) {
+                    throw new IllegalArgumentException("Cannot set a task without display area as "
+                            + "launch root: " + wc);
+                } else {
                     task.getDisplayArea().setLaunchRootTask(task,
                             hop.getWindowingModes(), hop.getActivityTypes());
-                } else {
-                    throw new IllegalArgumentException("Cannot set non-task as launch root: " + wc);
                 }
                 break;
             }
@@ -957,20 +960,6 @@
                         errorCallbackToken, organizer);
                 break;
             }
-            default: {
-                // The other operations may change task order so they are skipped while in lock
-                // task mode. The above operations are still allowed because they don't move
-                // tasks. And it may be necessary such as clearing launch root after entering
-                // lock task mode.
-                if (isInLockTaskMode) {
-                    Slog.w(TAG, "Skip applying hierarchy operation " + hop
-                            + " while in lock task mode");
-                    return effects;
-                }
-            }
-        }
-
-        switch (type) {
             case HIERARCHY_OP_TYPE_PENDING_INTENT: {
                 final Bundle launchOpts = hop.getLaunchOptions();
                 ActivityOptions activityOptions = launchOpts != null
@@ -1009,6 +998,20 @@
                 }
                 break;
             }
+            default: {
+                // The other operations may change task order so they are skipped while in lock
+                // task mode. The above operations are still allowed because they don't move
+                // tasks. And it may be necessary such as clearing launch root after entering
+                // lock task mode.
+                if (isInLockTaskMode) {
+                    Slog.w(TAG, "Skip applying hierarchy operation " + hop
+                            + " while in lock task mode");
+                    return effects;
+                }
+            }
+        }
+
+        switch (type) {
             case HIERARCHY_OP_TYPE_START_SHORTCUT: {
                 final Bundle launchOpts = hop.getLaunchOptions();
                 final String callingPackage = launchOpts.getString(
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index dbd9e4b..3672820 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -721,6 +721,12 @@
         }
     }
 
+    List<String> getPackageList() {
+        synchronized (mPkgList) {
+            return new ArrayList<>(mPkgList);
+        }
+    }
+
     void addActivityIfNeeded(ActivityRecord r) {
         // even if we already track this activity, note down that it has been launched
         setLastActivityLaunchTime(r);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ba94282..7cd7f69 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1932,7 +1932,7 @@
         final ActivityRecord atoken = mActivityRecord;
         if (atoken != null) {
             return ((!isParentWindowHidden() && atoken.isVisible())
-                    || isAnimating(TRANSITION | PARENTS));
+                    || isAnimationRunningSelfOrParent());
         }
         final WallpaperWindowToken wtoken = mToken.asWallpaperToken();
         if (wtoken != null) {
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 2ce86ad..d5217c8 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -109,6 +109,7 @@
         "libchrome",
         "libcutils",
         "libcrypto",
+        "libfmq",
         "liblog",
         "libgraphicsenv",
         "libgralloctypes",
@@ -157,6 +158,7 @@
         "android.hardware.broadcastradio@1.0",
         "android.hardware.broadcastradio@1.1",
         "android.hardware.contexthub@1.0",
+        "android.hardware.common.fmq-V1-ndk",
         "android.hardware.gnss-V3-cpp",
         "android.hardware.gnss@1.0",
         "android.hardware.gnss@1.1",
diff --git a/services/core/jni/com_android_server_display_DisplayControl.cpp b/services/core/jni/com_android_server_display_DisplayControl.cpp
index 72829c0..e65b903 100644
--- a/services/core/jni/com_android_server_display_DisplayControl.cpp
+++ b/services/core/jni/com_android_server_display_DisplayControl.cpp
@@ -99,7 +99,10 @@
     // Extract unique HDR output types.
     std::set<int> hdrOutputTypes;
     for (const auto& hdrConversionCapability : hdrConversionCapabilities) {
-        hdrOutputTypes.insert(hdrConversionCapability.outputType);
+        // Filter out the value for SDR which is 0.
+        if (hdrConversionCapability.outputType > 0) {
+            hdrOutputTypes.insert(hdrConversionCapability.outputType);
+        }
     }
     jintArray array = env->NewIntArray(hdrOutputTypes.size());
     if (array == nullptr) {
@@ -107,7 +110,32 @@
         return nullptr;
     }
     jint* arrayValues = env->GetIntArrayElements(array, 0);
-    int index = 0;
+    size_t index = 0;
+    for (auto hdrOutputType : hdrOutputTypes) {
+        arrayValues[index++] = static_cast<jint>(hdrOutputType);
+    }
+    env->ReleaseIntArrayElements(array, arrayValues, 0);
+    return array;
+}
+
+static jintArray nativeGetHdrOutputTypesWithLatency(JNIEnv* env, jclass clazz) {
+    std::vector<gui::HdrConversionCapability> hdrConversionCapabilities;
+    SurfaceComposerClient::getHdrConversionCapabilities(&hdrConversionCapabilities);
+
+    // Extract unique HDR output types with latency.
+    std::set<int> hdrOutputTypes;
+    for (const auto& hdrConversionCapability : hdrConversionCapabilities) {
+        if (hdrConversionCapability.outputType > 0 && hdrConversionCapability.addsLatency) {
+            hdrOutputTypes.insert(hdrConversionCapability.outputType);
+        }
+    }
+    jintArray array = env->NewIntArray(hdrOutputTypes.size());
+    if (array == nullptr) {
+        jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
+        return nullptr;
+    }
+    jint* arrayValues = env->GetIntArrayElements(array, 0);
+    size_t index = 0;
     for (auto hdrOutputType : hdrOutputTypes) {
         arrayValues[index++] = static_cast<jint>(hdrOutputType);
     }
@@ -164,7 +192,9 @@
             (void*)nativeSetHdrConversionMode },
     {"nativeGetSupportedHdrOutputTypes", "()[I",
             (void*)nativeGetSupportedHdrOutputTypes },
-     {"nativeGetHdrOutputConversionSupport", "()Z",
+    {"nativeGetHdrOutputTypesWithLatency", "()[I",
+            (void*)nativeGetHdrOutputTypesWithLatency },
+    {"nativeGetHdrOutputConversionSupport", "()Z",
             (void*) nativeGetHdrOutputConversionSupport },
         // clang-format on
 };
diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp
index a8806b5..1e63840 100644
--- a/services/core/jni/com_android_server_tv_TvInputHal.cpp
+++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp
@@ -20,6 +20,7 @@
 
 #include "tvinput/JTvInputHal.h"
 
+gBundleClassInfoType gBundleClassInfo;
 gTvInputHalClassInfoType gTvInputHalClassInfo;
 gTvStreamConfigClassInfoType gTvStreamConfigClassInfo;
 gTvStreamConfigBuilderClassInfoType gTvStreamConfigBuilderClassInfo;
@@ -133,10 +134,22 @@
     GET_METHOD_ID(
             gTvInputHalClassInfo.firstFrameCaptured, clazz,
             "firstFrameCapturedFromNative", "(II)V");
+    GET_METHOD_ID(gTvInputHalClassInfo.tvMessageReceived, clazz, "tvMessageReceivedFromNative",
+                  "(IILandroid/os/Bundle;)V");
 
     FIND_CLASS(gTvStreamConfigClassInfo.clazz, "android/media/tv/TvStreamConfig");
     gTvStreamConfigClassInfo.clazz = jclass(env->NewGlobalRef(gTvStreamConfigClassInfo.clazz));
 
+    FIND_CLASS(gBundleClassInfo.clazz, "android/os/Bundle");
+    gBundleClassInfo.clazz = jclass(env->NewGlobalRef(gBundleClassInfo.clazz));
+    GET_METHOD_ID(gBundleClassInfo.constructor, gBundleClassInfo.clazz, "<init>", "()V");
+    GET_METHOD_ID(gBundleClassInfo.putByteArray, gBundleClassInfo.clazz, "putByteArray",
+                  "(Ljava/lang/String;[B)V");
+    GET_METHOD_ID(gBundleClassInfo.putString, gBundleClassInfo.clazz, "putString",
+                  "(Ljava/lang/String;Ljava/lang/String;)V");
+    GET_METHOD_ID(gBundleClassInfo.putInt, gBundleClassInfo.clazz, "putInt",
+                  "(Ljava/lang/String;I)V");
+
     FIND_CLASS(gTvStreamConfigBuilderClassInfo.clazz, "android/media/tv/TvStreamConfig$Builder");
     gTvStreamConfigBuilderClassInfo.clazz =
             jclass(env->NewGlobalRef(gTvStreamConfigBuilderClassInfo.clazz));
diff --git a/services/core/jni/tvinput/JTvInputHal.cpp b/services/core/jni/tvinput/JTvInputHal.cpp
index 6bb5217..74fdabf 100644
--- a/services/core/jni/tvinput/JTvInputHal.cpp
+++ b/services/core/jni/tvinput/JTvInputHal.cpp
@@ -16,6 +16,8 @@
 
 #include "JTvInputHal.h"
 
+#include <nativehelper/ScopedLocalRef.h>
+
 namespace android {
 
 JTvInputHal::JTvInputHal(JNIEnv* env, jobject thiz, std::shared_ptr<ITvInputWrapper> tvInput,
@@ -106,7 +108,7 @@
                   status.getServiceSpecificError());
             return UNKNOWN_ERROR;
         }
-        connection.mSourceHandle = NativeHandle::create(makeFromAidl(sidebandStream), true);
+        connection.mSourceHandle = NativeHandle::create(dupFromAidl(sidebandStream), true);
     }
     connection.mSurface = surface;
     if (connection.mSurface != nullptr) {
@@ -275,6 +277,32 @@
                         cableConnectionStatus);
 }
 
+void JTvInputHal::onTvMessage(int deviceId, int streamId, AidlTvMessageEventType type,
+                              AidlTvMessage& message, signed char data[], int dataLength) {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    ScopedLocalRef<jobject> bundle(env,
+                                   env->NewObject(gBundleClassInfo.clazz,
+                                                  gBundleClassInfo.constructor));
+    ScopedLocalRef<jbyteArray> convertedData(env, env->NewByteArray(dataLength));
+    env->SetByteArrayRegion(convertedData.get(), 0, dataLength, reinterpret_cast<jbyte*>(data));
+    std::string key = "android.media.tv.TvInputManager.raw_data";
+    ScopedLocalRef<jstring> jkey(env, env->NewStringUTF(key.c_str()));
+    env->CallVoidMethod(bundle.get(), gBundleClassInfo.putByteArray, jkey.get(),
+                        convertedData.get());
+    ScopedLocalRef<jstring> subtype(env, env->NewStringUTF(message.subType.c_str()));
+    key = "android.media.tv.TvInputManager.subtype";
+    jkey = ScopedLocalRef<jstring>(env, env->NewStringUTF(key.c_str()));
+    env->CallVoidMethod(bundle.get(), gBundleClassInfo.putString, jkey.get(), subtype.get());
+    key = "android.media.tv.TvInputManager.group_id";
+    jkey = ScopedLocalRef<jstring>(env, env->NewStringUTF(key.c_str()));
+    env->CallVoidMethod(bundle.get(), gBundleClassInfo.putInt, jkey.get(), message.groupId);
+    key = "android.media.tv.TvInputManager.stream_id";
+    jkey = ScopedLocalRef<jstring>(env, env->NewStringUTF(key.c_str()));
+    env->CallVoidMethod(bundle.get(), gBundleClassInfo.putInt, jkey.get(), streamId);
+    env->CallVoidMethod(mThiz, gTvInputHalClassInfo.tvMessageReceived, deviceId,
+                        static_cast<jint>(type), bundle.get());
+}
+
 void JTvInputHal::onCaptured(int deviceId, int streamId, uint32_t seq, bool succeeded) {
     sp<BufferProducerThread> thread;
     {
@@ -316,6 +344,17 @@
     return event;
 }
 
+JTvInputHal::TvMessageEventWrapper JTvInputHal::TvMessageEventWrapper::createEventWrapper(
+        const AidlTvMessageEvent& aidlTvMessageEvent) {
+    TvMessageEventWrapper event;
+    event.messages.insert(event.messages.begin(), std::begin(aidlTvMessageEvent.messages) + 1,
+                          std::end(aidlTvMessageEvent.messages));
+    event.streamId = aidlTvMessageEvent.streamId;
+    event.deviceId = aidlTvMessageEvent.messages[0].groupId;
+    event.type = aidlTvMessageEvent.type;
+    return event;
+}
+
 JTvInputHal::NotifyHandler::NotifyHandler(JTvInputHal* hal, const TvInputEventWrapper& event) {
     mHal = hal;
     mEvent = event;
@@ -338,6 +377,41 @@
     }
 }
 
+JTvInputHal::NotifyTvMessageHandler::NotifyTvMessageHandler(JTvInputHal* hal,
+                                                            const TvMessageEventWrapper& event) {
+    mHal = hal;
+    mEvent = event;
+}
+
+void JTvInputHal::NotifyTvMessageHandler::handleMessage(const Message& message) {
+    std::shared_ptr<AidlMessageQueue<int8_t, SynchronizedReadWrite>> queue =
+            mHal->mQueueMap[mEvent.deviceId][mEvent.streamId];
+    for (AidlTvMessage item : mEvent.messages) {
+        if (queue == NULL || !queue->isValid() || queue->availableToRead() < item.dataLengthBytes) {
+            MQDescriptor<int8_t, SynchronizedReadWrite> queueDesc;
+            if (mHal->mTvInput->getTvMessageQueueDesc(&queueDesc, mEvent.deviceId, mEvent.streamId)
+                        .isOk()) {
+                queue = std::make_shared<AidlMessageQueue<int8_t, SynchronizedReadWrite>>(queueDesc,
+                                                                                          false);
+            }
+            if (queue == NULL || !queue->isValid() ||
+                queue->availableToRead() < item.dataLengthBytes) {
+                ALOGE("Incomplete TvMessageQueue data or missing queue");
+                return;
+            }
+            mHal->mQueueMap[mEvent.deviceId][mEvent.streamId] = queue;
+        }
+        signed char* buffer = new signed char[item.dataLengthBytes];
+        if (queue->read(buffer, item.dataLengthBytes)) {
+            mHal->onTvMessage(mEvent.deviceId, mEvent.streamId, mEvent.type, item, buffer,
+                              item.dataLengthBytes);
+        } else {
+            ALOGE("Failed to read from TvMessageQueue");
+        }
+        delete[] buffer;
+    }
+}
+
 JTvInputHal::TvInputCallback::TvInputCallback(JTvInputHal* hal) {
     mHal = hal;
 }
@@ -351,7 +425,15 @@
 
 ::ndk::ScopedAStatus JTvInputHal::TvInputCallback::notifyTvMessageEvent(
         const AidlTvMessageEvent& event) {
-    // TODO: Implement this
+    const std::string DEVICE_ID_SUBTYPE = "device_id";
+    if (event.messages.size() > 1 && event.messages[0].subType == DEVICE_ID_SUBTYPE) {
+        mHal->mLooper
+                ->sendMessage(new NotifyTvMessageHandler(mHal,
+                                                         TvMessageEventWrapper::createEventWrapper(
+                                                                 event)),
+                              static_cast<int>(event.type));
+    }
+
     return ::ndk::ScopedAStatus::ok();
 }
 
@@ -406,4 +488,14 @@
     }
 }
 
+::ndk::ScopedAStatus JTvInputHal::ITvInputWrapper::getTvMessageQueueDesc(
+        MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue, int32_t in_deviceId,
+        int32_t in_streamId) {
+    if (mIsHidl) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    } else {
+        return mAidlTvInput->getTvMessageQueueDesc(out_queue, in_deviceId, in_streamId);
+    }
+}
+
 } // namespace android
diff --git a/services/core/jni/tvinput/JTvInputHal.h b/services/core/jni/tvinput/JTvInputHal.h
index e29da79..e8b1c99 100644
--- a/services/core/jni/tvinput/JTvInputHal.h
+++ b/services/core/jni/tvinput/JTvInputHal.h
@@ -24,6 +24,7 @@
 #include <aidl/android/media/audio/common/AudioDevice.h>
 #include <aidlcommonsupport/NativeHandle.h>
 #include <android/binder_manager.h>
+#include <fmq/AidlMessageQueue.h>
 #include <nativehelper/JNIHelp.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
@@ -40,6 +41,10 @@
 #include "android_runtime/android_view_Surface.h"
 #include "tvinput/jstruct.h"
 
+using ::android::AidlMessageQueue;
+
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
 using ::aidl::android::hardware::tv::input::BnTvInputCallback;
 using ::aidl::android::hardware::tv::input::CableConnectionStatus;
 using ::aidl::android::hardware::tv::input::TvInputEventType;
@@ -54,10 +59,16 @@
 using AidlNativeHandle = ::aidl::android::hardware::common::NativeHandle;
 using AidlTvInputDeviceInfo = ::aidl::android::hardware::tv::input::TvInputDeviceInfo;
 using AidlTvInputEvent = ::aidl::android::hardware::tv::input::TvInputEvent;
+using AidlTvMessage = ::aidl::android::hardware::tv::input::TvMessage;
 using AidlTvMessageEvent = ::aidl::android::hardware::tv::input::TvMessageEvent;
 using AidlTvMessageEventType = ::aidl::android::hardware::tv::input::TvMessageEventType;
 using AidlTvStreamConfig = ::aidl::android::hardware::tv::input::TvStreamConfig;
 
+using AidlMessageQueueMap = std::unordered_map<
+        int,
+        std::unordered_map<int, std::shared_ptr<AidlMessageQueue<int8_t, SynchronizedReadWrite>>>>;
+
+extern gBundleClassInfoType gBundleClassInfo;
 extern gTvInputHalClassInfoType gTvInputHalClassInfo;
 extern gTvStreamConfigClassInfoType gTvStreamConfigClassInfo;
 extern gTvStreamConfigBuilderClassInfoType gTvStreamConfigBuilderClassInfo;
@@ -121,6 +132,19 @@
         TvInputDeviceInfoWrapper deviceInfo;
     };
 
+    class TvMessageEventWrapper {
+    public:
+        TvMessageEventWrapper() {}
+
+        static TvMessageEventWrapper createEventWrapper(
+                const AidlTvMessageEvent& aidlTvMessageEvent);
+
+        int streamId;
+        int deviceId;
+        std::vector<AidlTvMessage> messages;
+        AidlTvMessageEventType type;
+    };
+
     class NotifyHandler : public MessageHandler {
     public:
         NotifyHandler(JTvInputHal* hal, const TvInputEventWrapper& event);
@@ -132,6 +156,17 @@
         JTvInputHal* mHal;
     };
 
+    class NotifyTvMessageHandler : public MessageHandler {
+    public:
+        NotifyTvMessageHandler(JTvInputHal* hal, const TvMessageEventWrapper& event);
+
+        void handleMessage(const Message& message) override;
+
+    private:
+        TvMessageEventWrapper mEvent;
+        JTvInputHal* mHal;
+    };
+
     class TvInputCallback : public HidlITvInputCallback, public BnTvInputCallback {
     public:
         explicit TvInputCallback(JTvInputHal* hal);
@@ -156,6 +191,9 @@
         ::ndk::ScopedAStatus closeStream(int32_t in_deviceId, int32_t in_streamId);
         ::ndk::ScopedAStatus setTvMessageEnabled(int32_t deviceId, int32_t streamId,
                                                  TvMessageEventType in_type, bool enabled);
+        ::ndk::ScopedAStatus getTvMessageQueueDesc(
+                MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue, int32_t in_deviceId,
+                int32_t in_streamId);
 
     private:
         ::ndk::ScopedAStatus hidlSetCallback(const std::shared_ptr<TvInputCallback>& in_callback);
@@ -178,11 +216,14 @@
     void onDeviceUnavailable(int deviceId);
     void onStreamConfigurationsChanged(int deviceId, int cableConnectionStatus);
     void onCaptured(int deviceId, int streamId, uint32_t seq, bool succeeded);
+    void onTvMessage(int deviceId, int streamId, AidlTvMessageEventType type,
+                     AidlTvMessage& message, signed char data[], int dataLength);
 
     Mutex mLock;
     Mutex mStreamLock;
     jweak mThiz;
     sp<Looper> mLooper;
+    AidlMessageQueueMap mQueueMap;
 
     KeyedVector<int, KeyedVector<int, Connection> > mConnections;
 
diff --git a/services/core/jni/tvinput/jstruct.h b/services/core/jni/tvinput/jstruct.h
index 0a4a64d..23cf4ae 100644
--- a/services/core/jni/tvinput/jstruct.h
+++ b/services/core/jni/tvinput/jstruct.h
@@ -23,6 +23,7 @@
     jmethodID deviceUnavailable;
     jmethodID streamConfigsChanged;
     jmethodID firstFrameCaptured;
+    jmethodID tvMessageReceived;
 } gTvInputHalClassInfoType;
 
 typedef struct {
@@ -31,6 +32,14 @@
 
 typedef struct {
     jclass clazz;
+    jmethodID constructor;
+    jmethodID putByteArray;
+    jmethodID putString;
+    jmethodID putInt;
+} gBundleClassInfoType;
+
+typedef struct {
+    jclass clazz;
 
     jmethodID constructor;
     jmethodID streamId;
diff --git a/services/credentials/java/com/android/server/credentials/ClearRequestSession.java b/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
index fe8a8c8..69a5e5c 100644
--- a/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
@@ -93,6 +93,7 @@
     public void onFinalResponseReceived(
             ComponentName componentName,
             Void response) {
+        mRequestSessionMetric.collectUiResponseData(/*uiReturned=*/ true, System.nanoTime());
         mRequestSessionMetric.updateMetricsOnResponseReceived(mProviders, componentName,
                 isPrimaryProviderViaProviderInfo(componentName));
         respondToClientWithResponseAndFinish(null);
diff --git a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
index 20dd181..c37a038 100644
--- a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
@@ -64,7 +64,7 @@
                 RequestInfo.TYPE_CREATE,
                 callingAppInfo, enabledProviders, cancellationSignal, startedTimestamp);
         mRequestSessionMetric.collectCreateFlowInitialMetricInfo(
-                /*origin=*/request.getOrigin() != null);
+                /*origin=*/request.getOrigin() != null, request);
         mPrimaryProviders = primaryProviders;
     }
 
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
index 25561ed..272452e 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
@@ -33,7 +33,6 @@
 import android.os.Looper;
 import android.os.ResultReceiver;
 import android.service.credentials.CredentialProviderInfoFactory;
-import android.util.Log;
 import android.util.Slog;
 
 import java.util.ArrayList;
@@ -72,7 +71,6 @@
     };
 
     private void handleUiResult(int resultCode, Bundle resultData) {
-        Log.i("reemademo", "handleUiResult with resultCOde: " + resultCode);
 
         switch (resultCode) {
             case UserSelectionDialogResult.RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION:
@@ -86,13 +84,11 @@
                 }
                 break;
             case UserSelectionDialogResult.RESULT_CODE_DIALOG_USER_CANCELED:
-                Log.i("reemademo", "RESULT_CODE_DIALOG_USER_CANCELED");
 
                 mStatus = UiStatus.TERMINATED;
                 mCallbacks.onUiCancellation(/* isUserCancellation= */ true);
                 break;
             case UserSelectionDialogResult.RESULT_CODE_CANCELED_AND_LAUNCHED_SETTINGS:
-                Log.i("reemademo", "RESULT_CODE_CANCELED_AND_LAUNCHED_SETTINGS");
 
                 mStatus = UiStatus.TERMINATED;
                 mCallbacks.onUiCancellation(/* isUserCancellation= */ false);
@@ -102,7 +98,6 @@
                 mCallbacks.onUiSelectorInvocationFailure();
                 break;
             default:
-                Log.i("reemademo", "Unknown error code returned from the UI");
                 mStatus = UiStatus.IN_PROGRESS;
                 mCallbacks.onUiSelectorInvocationFailure();
                 break;
diff --git a/services/credentials/java/com/android/server/credentials/GetRequestSession.java b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
index e820d8a..aee4f58 100644
--- a/services/credentials/java/com/android/server/credentials/GetRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
@@ -133,6 +133,7 @@
     public void onFinalResponseReceived(ComponentName componentName,
             @Nullable GetCredentialResponse response) {
         Slog.i(TAG, "onFinalResponseReceived from: " + componentName.flattenToString());
+        mRequestSessionMetric.collectUiResponseData(/*uiReturned=*/ true, System.nanoTime());
         mRequestSessionMetric.updateMetricsOnResponseReceived(mProviders, componentName,
                 isPrimaryProviderViaProviderInfo(componentName));
         if (response != null) {
diff --git a/services/credentials/java/com/android/server/credentials/MetricUtilities.java b/services/credentials/java/com/android/server/credentials/MetricUtilities.java
index 64a73c9..b36de0b 100644
--- a/services/credentials/java/com/android/server/credentials/MetricUtilities.java
+++ b/services/credentials/java/com/android/server/credentials/MetricUtilities.java
@@ -39,7 +39,6 @@
 /**
  * For all future metric additions, this will contain their names for local usage after importing
  * from {@link com.android.internal.util.FrameworkStatsLog}.
- * TODO(b/271135048) - Emit all atoms, including all V4 atoms (specifically the rest of track 1).
  */
 public class MetricUtilities {
     private static final boolean LOG_FLAG = true;
@@ -101,7 +100,9 @@
      */
     protected static int getMetricTimestampDifferenceMicroseconds(long t2, long t1) {
         if (t2 - t1 > Integer.MAX_VALUE) {
-            throw new ArithmeticException("Input timestamps are too far apart and unsupported");
+            Slog.i(TAG, "Input timestamps are too far apart and unsupported, "
+                    + "falling back to default int");
+            return DEFAULT_INT_32;
         }
         if (t2 < t1) {
             Slog.i(TAG, "The timestamps aren't in expected order, falling back to default int");
@@ -229,7 +230,7 @@
                     authenticationMetric.isAuthReturned()
             );
         } catch (Exception e) {
-            Slog.w(TAG, "Unexpected error during candidate get metric logging: " + e);
+            Slog.w(TAG, "Unexpected error during candidate auth metric logging: " + e);
         }
     }
 
@@ -252,22 +253,18 @@
             }
             var sessions = providers.values();
             for (var session : sessions) {
-                try {
-                    var metric = session.getProviderSessionMetric()
-                            .getCandidatePhasePerProviderMetric();
-                    FrameworkStatsLog.write(
-                            FrameworkStatsLog.CREDENTIAL_MANAGER_GET_REPORTED,
-                            /* session_id */ metric.getSessionIdProvider(),
-                            /* sequence_num */ emitSequenceId,
-                            /* candidate_provider_uid */ metric.getCandidateUid(),
-                            /* response_unique_classtypes */
-                            metric.getResponseCollective().getUniqueResponseStrings(),
-                            /* per_classtype_counts */
-                            metric.getResponseCollective().getUniqueResponseCounts()
-                    );
-                } catch (Exception e) {
-                    Slog.w(TAG, "Unexpected exception during get metric logging" + e);
-                }
+                var metric = session.getProviderSessionMetric()
+                        .getCandidatePhasePerProviderMetric();
+                FrameworkStatsLog.write(
+                        FrameworkStatsLog.CREDENTIAL_MANAGER_GET_REPORTED,
+                        /* session_id */ metric.getSessionIdProvider(),
+                        /* sequence_num */ emitSequenceId,
+                        /* candidate_provider_uid */ metric.getCandidateUid(),
+                        /* response_unique_classtypes */
+                        metric.getResponseCollective().getUniqueResponseStrings(),
+                        /* per_classtype_counts */
+                        metric.getResponseCollective().getUniqueResponseCounts()
+                );
             }
         } catch (Exception e) {
             Slog.w(TAG, "Unexpected error during candidate get metric logging: " + e);
@@ -399,7 +396,7 @@
                     /* caller_uid */ callingUid,
                     /* api_status */ apiStatus.getMetricCode());
         } catch (Exception e) {
-            Slog.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.w(TAG, "Unexpected error during simple v2 metric logging: " + e);
         }
     }
 
@@ -505,7 +502,7 @@
                     candidateAggregateMetric.isAuthReturned()
             );
         } catch (Exception e) {
-            Slog.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.w(TAG, "Unexpected error during total candidate metric logging: " + e);
         }
     }
 
@@ -570,7 +567,7 @@
                     /* primary_indicated */ finalPhaseMetric.isPrimary()
             );
         } catch (Exception e) {
-            Slog.w(TAG, "Unexpected error during metric logging: " + e);
+            Slog.w(TAG, "Unexpected error during final no uid metric logging: " + e);
         }
     }
 
diff --git a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
index 25f20ca..6f79852 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
@@ -54,7 +54,7 @@
     private static final String TAG = "ProviderCreateSession";
 
     // Key to be used as an entry key for a save entry
-    private static final String SAVE_ENTRY_KEY = "save_entry_key";
+    public static final String SAVE_ENTRY_KEY = "save_entry_key";
     // Key to be used as an entry key for a remote entry
     private static final String REMOTE_ENTRY_KEY = "remote_entry_key";
 
@@ -193,11 +193,13 @@
         mProviderResponseDataHandler.addResponseContent(response.getCreateEntries(),
                 response.getRemoteCreateEntry());
         if (mProviderResponseDataHandler.isEmptyResponse(response)) {
-            mProviderSessionMetric.collectCandidateEntryMetrics(response, /*isAuthEntry*/false);
+            mProviderSessionMetric.collectCandidateEntryMetrics(response, /*isAuthEntry*/false,
+                    ((RequestSession) mCallbacks).mRequestSessionMetric.getInitialPhaseMetric());
             updateStatusAndInvokeCallback(Status.EMPTY_RESPONSE,
                     /*source=*/ CredentialsSource.REMOTE_PROVIDER);
         } else {
-            mProviderSessionMetric.collectCandidateEntryMetrics(response, /*isAuthEntry*/false);
+            mProviderSessionMetric.collectCandidateEntryMetrics(response, /*isAuthEntry*/false,
+                    ((RequestSession) mCallbacks).mRequestSessionMetric.getInitialPhaseMetric());
             updateStatusAndInvokeCallback(Status.SAVE_ENTRIES_RECEIVED,
                     /*source=*/ CredentialsSource.REMOTE_PROVIDER);
         }
diff --git a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
index 14260f0..3c1432a 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
@@ -150,7 +150,7 @@
         List<CredentialOption> filteredOptions = new ArrayList<>();
         for (CredentialOption option : clientRequest.getCredentialOptions()) {
             if (providerCapabilities.contains(option.getType())
-                    && isProviderAllowed(option, info.getComponentName())
+                    && isProviderAllowed(option, info)
                     && checkSystemProviderRequirement(option, info.isSystemProvider())) {
                 Slog.i(TAG, "Option of type: " + option.getType() + " meets all filtering"
                         + "conditions");
@@ -167,9 +167,14 @@
         return null;
     }
 
-    private static boolean isProviderAllowed(CredentialOption option, ComponentName componentName) {
+    private static boolean isProviderAllowed(CredentialOption option,
+            CredentialProviderInfo providerInfo) {
+        if (providerInfo.isSystemProvider()) {
+            // Always allow system providers , including the remote provider
+            return true;
+        }
         if (!option.getAllowedProviders().isEmpty() && !option.getAllowedProviders().contains(
-                componentName)) {
+                providerInfo.getComponentName())) {
             Slog.i(TAG, "Provider allow list specified but does not contain this provider");
             return false;
         }
@@ -435,7 +440,7 @@
         BeginGetCredentialResponse response = PendingIntentResultHandler
                 .extractResponseContent(providerPendingIntentResponse
                         .getResultData());
-        mProviderSessionMetric.collectCandidateEntryMetrics(response, /*isAuthEntry*/true);
+        mProviderSessionMetric.collectCandidateEntryMetrics(response, /*isAuthEntry*/true, null);
         if (response != null && !mProviderResponseDataHandler.isEmptyResponse(response)) {
             addToInitialRemoteResponse(response, /*isInitialResponse=*/ false);
             // Additional content received is in the form of new response content.
@@ -473,12 +478,14 @@
         addToInitialRemoteResponse(response, /*isInitialResponse=*/true);
         // Log the data.
         if (mProviderResponseDataHandler.isEmptyResponse(response)) {
-            mProviderSessionMetric.collectCandidateEntryMetrics(response, /*isAuthEntry*/false);
+            mProviderSessionMetric.collectCandidateEntryMetrics(response, /*isAuthEntry*/false,
+                    null);
             updateStatusAndInvokeCallback(Status.EMPTY_RESPONSE,
                     /*source=*/ CredentialsSource.REMOTE_PROVIDER);
             return;
         }
-        mProviderSessionMetric.collectCandidateEntryMetrics(response, /*isAuthEntry*/false);
+        mProviderSessionMetric.collectCandidateEntryMetrics(response, /*isAuthEntry*/false,
+                null);
         updateStatusAndInvokeCallback(Status.CREDENTIALS_RECEIVED,
                 /*source=*/ CredentialsSource.REMOTE_PROVIDER);
     }
diff --git a/services/credentials/java/com/android/server/credentials/ProviderSession.java b/services/credentials/java/com/android/server/credentials/ProviderSession.java
index 83f21af..f2055d0 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderSession.java
@@ -215,8 +215,10 @@
             CredentialsSource source) {
         setStatus(status);
         boolean isPrimary = mProviderInfo != null && mProviderInfo.isPrimary();
-        mProviderSessionMetric.collectCandidateMetricUpdate(isTerminatingStatus(status),
-                isCompletionStatus(status), mProviderSessionUid,
+        mProviderSessionMetric.collectCandidateMetricUpdate(isTerminatingStatus(status)
+                        || isStatusWaitingForRemoteResponse(status),
+                isCompletionStatus(status) || isUiInvokingStatus(status),
+                mProviderSessionUid,
                 /*isAuthEntry*/source == CredentialsSource.AUTH_ENTRY,
                 /*isPrimary*/isPrimary);
         mCallbacks.onProviderStatusChanged(status, mComponentName, source);
diff --git a/services/credentials/java/com/android/server/credentials/metrics/ApiName.java b/services/credentials/java/com/android/server/credentials/metrics/ApiName.java
index cb6a5d0..d828349 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/ApiName.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/ApiName.java
@@ -30,6 +30,7 @@
 import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_INITIAL_PHASE_REPORTED__API_NAME__API_NAME_REGISTER_CREDENTIAL_DESCRIPTION;
 import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_INITIAL_PHASE_REPORTED__API_NAME__API_NAME_SET_ENABLED_PROVIDERS;
 import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_INITIAL_PHASE_REPORTED__API_NAME__API_NAME_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_INITIAL_PHASE_REPORTED__API_NAME__API_NAME_UNREGISTER_CREDENTIAL_DESCRIPTION;
 
 import android.credentials.ui.RequestInfo;
 import android.util.Slog;
@@ -61,7 +62,7 @@
     ),
 
     UNREGISTER_CREDENTIAL_DESCRIPTION(
-    CREDENTIAL_MANAGER_INITIAL_PHASE_REPORTED__API_NAME__API_NAME_REGISTER_CREDENTIAL_DESCRIPTION
+    CREDENTIAL_MANAGER_INITIAL_PHASE_REPORTED__API_NAME__API_NAME_UNREGISTER_CREDENTIAL_DESCRIPTION
     );
 
     private static final String TAG = "ApiName";
diff --git a/services/credentials/java/com/android/server/credentials/metrics/BrowsedAuthenticationMetric.java b/services/credentials/java/com/android/server/credentials/metrics/BrowsedAuthenticationMetric.java
index 62b8f24..1ac8a71 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/BrowsedAuthenticationMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/BrowsedAuthenticationMetric.java
@@ -43,9 +43,6 @@
     // Indicates if this provider returned from the authentication entry query, default false
     private boolean mAuthReturned = false;
 
-    // TODO(b/271135048) - Match the atom and provide a clean per provider session metric
-    // encapsulation.
-
     public BrowsedAuthenticationMetric(int sessionIdProvider) {
         mSessionIdProvider = sessionIdProvider;
     }
diff --git a/services/credentials/java/com/android/server/credentials/metrics/CandidateAggregateMetric.java b/services/credentials/java/com/android/server/credentials/metrics/CandidateAggregateMetric.java
index 339c221..9154778 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/CandidateAggregateMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/CandidateAggregateMetric.java
@@ -16,6 +16,7 @@
 
 package com.android.server.credentials.metrics;
 
+import com.android.server.credentials.MetricUtilities;
 import com.android.server.credentials.ProviderSession;
 import com.android.server.credentials.metrics.shared.ResponseCollective;
 
@@ -29,7 +30,7 @@
  */
 public class CandidateAggregateMetric {
 
-    private static final String TAG = "CandidateProviderMetric";
+    private static final String TAG = "CandidateTotalMetric";
     // The session id of this provider metric
     private final int mSessionIdProvider;
     // Indicates if this provider returned from the candidate query phase,
@@ -74,8 +75,6 @@
 
     /**
      * This will take all the candidate data captured and aggregate that information.
-     * TODO(b/271135048) : Add on authentication entry outputs from track 2 here as well once
-     * generated
      * @param providers the providers associated with the candidate flow
      */
     public void collectAverages(Map<String, ProviderSession> providers) {
@@ -88,11 +87,15 @@
         Map<String, Integer> responseCountQuery = new LinkedHashMap<>();
         Map<EntryEnum, Integer> entryCountQuery = new LinkedHashMap<>();
         var providerSessions = providers.values();
-        long min_query_start = Integer.MAX_VALUE;
-        long max_query_end = Integer.MIN_VALUE;
+        long min_query_start = Long.MAX_VALUE;
+        long max_query_end = Long.MIN_VALUE;
         for (var session : providerSessions) {
             var sessionMetric = session.getProviderSessionMetric();
             var candidateMetric = sessionMetric.getCandidatePhasePerProviderMetric();
+            if (candidateMetric.getCandidateUid() == MetricUtilities.DEFAULT_INT_32) {
+                mNumProviders--;
+                continue; // Do not aggregate this one and reduce the size of actual candidates
+            }
             if (mServiceBeganTimeNanoseconds == -1) {
                 mServiceBeganTimeNanoseconds = candidateMetric.getServiceBeganTimeNanoseconds();
             }
@@ -119,15 +122,17 @@
     }
 
     private void collectAuthAggregates(Map<String, ProviderSession> providers) {
-        mNumProviders = providers.size();
         Map<String, Integer> responseCountAuth = new LinkedHashMap<>();
         Map<EntryEnum, Integer> entryCountAuth = new LinkedHashMap<>();
         var providerSessions = providers.values();
         for (var session : providerSessions) {
             var sessionMetric = session.getProviderSessionMetric();
             var authMetrics = sessionMetric.getBrowsedAuthenticationMetric();
-            mNumAuthEntriesTapped += authMetrics.size();
             for (var authMetric : authMetrics) {
+                if (authMetric.getProviderUid() == MetricUtilities.DEFAULT_INT_32) {
+                    continue; // skip this unfilled base auth entry
+                }
+                mNumAuthEntriesTapped++;
                 mAuthReturned = mAuthReturned || authMetric.isAuthReturned();
                 ResponseCollective authCollective = authMetric.getAuthEntryCollective();
                 ResponseCollective.combineTypeCountMaps(responseCountAuth,
diff --git a/services/credentials/java/com/android/server/credentials/metrics/EntryEnum.java b/services/credentials/java/com/android/server/credentials/metrics/EntryEnum.java
index 530f01c..226cd2c 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/EntryEnum.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/EntryEnum.java
@@ -28,6 +28,8 @@
 
 import android.util.Slog;
 
+import com.android.server.credentials.ProviderCreateSession;
+
 import java.util.AbstractMap;
 import java.util.Map;
 
@@ -52,6 +54,8 @@
             new AbstractMap.SimpleEntry<>(REMOTE_ENTRY_KEY,
                     REMOTE_ENTRY.mInnerMetricCode),
             new AbstractMap.SimpleEntry<>(CREDENTIAL_ENTRY_KEY,
+                    CREDENTIAL_ENTRY.mInnerMetricCode),
+            new AbstractMap.SimpleEntry<>(ProviderCreateSession.SAVE_ENTRY_KEY,
                     CREDENTIAL_ENTRY.mInnerMetricCode)
     );
 
diff --git a/services/credentials/java/com/android/server/credentials/metrics/ProviderSessionMetric.java b/services/credentials/java/com/android/server/credentials/metrics/ProviderSessionMetric.java
index 44d845e..c1f6b47 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/ProviderSessionMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/ProviderSessionMetric.java
@@ -20,6 +20,7 @@
 import static com.android.server.credentials.MetricUtilities.generateMetricKey;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.service.credentials.BeginCreateCredentialResponse;
 import android.service.credentials.BeginGetCredentialResponse;
 import android.service.credentials.CredentialEntry;
@@ -205,18 +206,22 @@
      *
      * @param response contains entries and data from the candidate provider responses
      * @param isAuthEntry indicates if this is an auth entry collection or not
+     * @param initialPhaseMetric for create flows, this helps identify the response type, which
+     *                           will identify the *type* of create flow, especially important in
+     *                           track 2. This is expected to be null in get flows.
      * @param <R> the response type associated with the API flow in progress
      */
-    public <R> void collectCandidateEntryMetrics(R response, boolean isAuthEntry) {
+    public <R> void collectCandidateEntryMetrics(R response, boolean isAuthEntry,
+            @Nullable InitialPhaseMetric initialPhaseMetric) {
         try {
             if (response instanceof BeginGetCredentialResponse) {
                 beginGetCredentialResponseCollectionCandidateEntryMetrics(
                         (BeginGetCredentialResponse) response, isAuthEntry);
             } else if (response instanceof BeginCreateCredentialResponse) {
                 beginCreateCredentialResponseCollectionCandidateEntryMetrics(
-                        (BeginCreateCredentialResponse) response);
+                        (BeginCreateCredentialResponse) response, initialPhaseMetric);
             } else {
-                Slog.i(TAG, "Your response type is unsupported for metric logging");
+                Slog.i(TAG, "Your response type is unsupported for candidate metric logging");
             }
         } catch (Exception e) {
             Slog.i(TAG, "Unexpected error during candidate entry metric logging: " + e);
@@ -245,7 +250,6 @@
             String entryKey = generateMetricKey(entry.getType(), DELTA_RESPONSES_CUT);
             responseCounts.put(entryKey, responseCounts.getOrDefault(entryKey, 0) + 1);
         });
-
         ResponseCollective responseCollective = new ResponseCollective(responseCounts, entryCounts);
         mCandidatePhasePerProviderMetric.setResponseCollective(responseCollective);
     }
@@ -262,19 +266,21 @@
     }
 
     private void beginCreateCredentialResponseCollectionCandidateEntryMetrics(
-            BeginCreateCredentialResponse response) {
+            BeginCreateCredentialResponse response, InitialPhaseMetric initialPhaseMetric) {
         Map<EntryEnum, Integer> entryCounts = new LinkedHashMap<>();
         var createEntries = response.getCreateEntries();
-        int numRemoteEntry = response.getRemoteCreateEntry() != null ? MetricUtilities.ZERO :
+        int numRemoteEntry = response.getRemoteCreateEntry() == null ? MetricUtilities.ZERO :
                 MetricUtilities.UNIT;
         int numCreateEntries = createEntries.size();
         entryCounts.put(EntryEnum.REMOTE_ENTRY, numRemoteEntry);
         entryCounts.put(EntryEnum.CREDENTIAL_ENTRY, numCreateEntries);
 
         Map<String, Integer> responseCounts = new LinkedHashMap<>();
-        responseCounts.put(MetricUtilities.DEFAULT_STRING, numCreateEntries);
-        // We don't store create response because it's directly related to the request
-        // We do still store the count, however
+        String[] requestStrings = initialPhaseMetric == null ? new String[0] :
+                initialPhaseMetric.getUniqueRequestStrings();
+        if (requestStrings.length > 0) {
+            responseCounts.put(requestStrings[0], initialPhaseMetric.getUniqueRequestCounts()[0]);
+        }
 
         ResponseCollective responseCollective = new ResponseCollective(responseCounts, entryCounts);
         mCandidatePhasePerProviderMetric.setResponseCollective(responseCollective);
diff --git a/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java b/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java
index 281f3cc..83b57c4 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/RequestSessionMetric.java
@@ -26,13 +26,17 @@
 import static com.android.server.credentials.MetricUtilities.logApiCalledCandidatePhase;
 import static com.android.server.credentials.MetricUtilities.logApiCalledFinalPhase;
 import static com.android.server.credentials.MetricUtilities.logApiCalledNoUidFinal;
+import static com.android.server.credentials.metrics.ApiName.GET_CREDENTIAL;
+import static com.android.server.credentials.metrics.ApiName.GET_CREDENTIAL_VIA_REGISTRY;
 
 import android.annotation.NonNull;
 import android.content.ComponentName;
+import android.credentials.CreateCredentialRequest;
 import android.credentials.GetCredentialRequest;
 import android.credentials.ui.UserSelectionDialogResult;
 import android.util.Slog;
 
+import com.android.server.credentials.MetricUtilities;
 import com.android.server.credentials.ProviderSession;
 
 import java.util.ArrayList;
@@ -112,7 +116,7 @@
             mInitialPhaseMetric.setCallerUid(mCallingUid);
             mInitialPhaseMetric.setApiName(metricCode);
         } catch (Exception e) {
-            Slog.i(TAG, "Unexpected error collecting initial metrics: " + e);
+            Slog.i(TAG, "Unexpected error collecting initial phase metric start info: " + e);
         }
     }
 
@@ -177,9 +181,12 @@
      *
      * @param origin indicates if an origin was passed in or not
      */
-    public void collectCreateFlowInitialMetricInfo(boolean origin) {
+    public void collectCreateFlowInitialMetricInfo(boolean origin,
+            CreateCredentialRequest request) {
         try {
             mInitialPhaseMetric.setOriginSpecified(origin);
+            mInitialPhaseMetric.setRequestCounts(Map.of(generateMetricKey(request.getType(),
+                    DELTA_RESPONSES_CUT), MetricUtilities.UNIT));
         } catch (Exception e) {
             Slog.i(TAG, "Unexpected error collecting create flow metric: " + e);
         }
@@ -195,7 +202,7 @@
                         0) + 1);
             });
         } catch (Exception e) {
-            Slog.i(TAG, "Unexpected error during get request metric logging: " + e);
+            Slog.i(TAG, "Unexpected error during get request count map metric logging: " + e);
         }
         return uniqueRequestCounts;
     }
@@ -210,7 +217,7 @@
             mInitialPhaseMetric.setOriginSpecified(request.getOrigin() != null);
             mInitialPhaseMetric.setRequestCounts(getRequestCountMap(request));
         } catch (Exception e) {
-            Slog.i(TAG, "Unexpected error collecting get flow metric: " + e);
+            Slog.i(TAG, "Unexpected error collecting get flow initial metric: " + e);
         }
     }
 
@@ -277,7 +284,7 @@
             mChosenProviderFinalPhaseMetric.setChosenProviderStatus(
                     finalStatus.getMetricCode());
         } catch (Exception e) {
-            Slog.i(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error during final phase provider status metric logging: " + e);
         }
     }
 
@@ -367,7 +374,11 @@
     public void logCandidatePhaseMetrics(Map<String, ProviderSession> providers) {
         try {
             logApiCalledCandidatePhase(providers, ++mSequenceCounter, mInitialPhaseMetric);
-            logApiCalledCandidateGetMetric(providers, mSequenceCounter);
+            if (mInitialPhaseMetric.getApiName() == GET_CREDENTIAL.getMetricCode()
+                    || mInitialPhaseMetric.getApiName() == GET_CREDENTIAL_VIA_REGISTRY
+                    .getMetricCode()) {
+                logApiCalledCandidateGetMetric(providers, mSequenceCounter);
+            }
         } catch (Exception e) {
             Slog.i(TAG, "Unexpected error during candidate metric emit: " + e);
         }
@@ -405,7 +416,7 @@
             }
             logApiCalledAuthenticationMetric(browsedAuthenticationMetric, ++mSequenceCounter);
         } catch (Exception e) {
-            Slog.i(TAG, "Unexpected error during metric logging: " + e);
+            Slog.i(TAG, "Unexpected error during auth entry metric emit: " + e);
         }
 
     }
diff --git a/services/credentials/java/com/android/server/credentials/metrics/shared/ResponseCollective.java b/services/credentials/java/com/android/server/credentials/metrics/shared/ResponseCollective.java
index 0958a84..ceb9571 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/shared/ResponseCollective.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/shared/ResponseCollective.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 
+import com.android.server.credentials.MetricUtilities;
 import com.android.server.credentials.metrics.EntryEnum;
 
 import java.util.Collections;
@@ -121,7 +122,7 @@
      * @return a count of this particular entry enum stored by this provider
      */
     public int getCountForEntry(EntryEnum e) {
-        return mEntryCounts.get(e);
+        return mEntryCounts.getOrDefault(e, MetricUtilities.ZERO);
     }
 
     /**
@@ -167,7 +168,7 @@
     public static <T> Map<T, Integer> combineTypeCountMaps(Map<T, Integer> first,
             Map<T, Integer> second) {
         for (T response : second.keySet()) {
-            first.merge(response, first.getOrDefault(response, 0), Integer::sum);
+            first.put(response, first.getOrDefault(response, 0) + second.get(response));
         }
         return first;
     }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
index 1322225..79c0349 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
@@ -27,17 +27,22 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.AppGlobals;
 import android.app.BroadcastOptions;
 import android.app.admin.DevicePolicyIdentifiers;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyState;
+import android.app.admin.IntentFilterPolicyKey;
 import android.app.admin.PolicyKey;
 import android.app.admin.PolicyUpdateReceiver;
 import android.app.admin.PolicyValue;
 import android.app.admin.TargetUser;
 import android.app.admin.UserRestrictionPolicyKey;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
@@ -45,6 +50,7 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.telephony.TelephonyManager;
@@ -599,6 +605,22 @@
     }
 
     /**
+     * Retrieves the values set for the provided {@code policyDefinition} by each admin.
+     */
+    @NonNull
+    <V> LinkedHashMap<EnforcingAdmin, PolicyValue<V>> getGlobalPoliciesSetByAdmins(
+            @NonNull PolicyDefinition<V> policyDefinition) {
+        Objects.requireNonNull(policyDefinition);
+
+        synchronized (mLock) {
+            if (!hasGlobalPolicyLocked(policyDefinition)) {
+                return new LinkedHashMap<>();
+            }
+            return getGlobalPolicyStateLocked(policyDefinition).getPoliciesSetByAdmins();
+        }
+    }
+
+    /**
      * Returns the policies set by the given admin that share the same
      * {@link PolicyKey#getIdentifier()} as the provided {@code policyDefinition}.
      *
@@ -1015,20 +1037,87 @@
     /**
      * Handles internal state related to packages getting updated.
      */
-    void handlePackageChanged(@Nullable String updatedPackage, int userId, boolean packageRemoved) {
-        if (updatedPackage == null) {
-            return;
-        }
-        if (packageRemoved) {
+    void handlePackageChanged(
+            @Nullable String updatedPackage, int userId, @Nullable String removedDpcPackage) {
+        Binder.withCleanCallingIdentity(() -> {
             Set<EnforcingAdmin> admins = getEnforcingAdminsOnUser(userId);
-            for (EnforcingAdmin admin : admins) {
-                if (admin.getPackageName().equals(updatedPackage)) {
-                    // remove policies for the uninstalled package
-                    removePoliciesForAdmin(admin);
+            if (removedDpcPackage != null) {
+                for (EnforcingAdmin admin : admins) {
+                    if (removedDpcPackage.equals(admin.getPackageName())) {
+                        removePoliciesForAdmin(admin);
+                        return;
+                    }
                 }
             }
-        } else {
-            updateDeviceAdminServiceOnPackageChanged(updatedPackage, userId);
+            for (EnforcingAdmin admin : admins) {
+                if (updatedPackage == null || updatedPackage.equals(admin.getPackageName())) {
+                    if (!isPackageInstalled(admin.getPackageName(), userId)) {
+                        Slogf.i(TAG, String.format(
+                                "Admin package %s not found for user %d, removing admin policies",
+                                admin.getPackageName(), userId));
+                        // remove policies for the uninstalled package
+                        removePoliciesForAdmin(admin);
+                        return;
+                    }
+                }
+            }
+            if (updatedPackage != null) {
+                updateDeviceAdminServiceOnPackageChanged(updatedPackage, userId);
+                removePersistentPreferredActivityPoliciesForPackage(updatedPackage, userId);
+            }
+        });
+    }
+
+    private void removePersistentPreferredActivityPoliciesForPackage(
+            @NonNull String packageName, int userId) {
+        Set<PolicyKey> policyKeys = getLocalPolicyKeysSetByAllAdmins(
+                PolicyDefinition.GENERIC_PERSISTENT_PREFERRED_ACTIVITY, userId);
+        for (PolicyKey key : policyKeys) {
+            if (!(key instanceof IntentFilterPolicyKey)) {
+                throw new IllegalStateException("PolicyKey for "
+                        + "PERSISTENT_PREFERRED_ACTIVITY is not of type "
+                        + "IntentFilterPolicyKey");
+            }
+            IntentFilterPolicyKey parsedKey =
+                    (IntentFilterPolicyKey) key;
+            IntentFilter intentFilter = Objects.requireNonNull(parsedKey.getIntentFilter());
+            PolicyDefinition<ComponentName> policyDefinition =
+                    PolicyDefinition.PERSISTENT_PREFERRED_ACTIVITY(intentFilter);
+            LinkedHashMap<EnforcingAdmin, PolicyValue<ComponentName>> policies =
+                    getLocalPoliciesSetByAdmins(
+                            policyDefinition,
+                            userId);
+            IPackageManager packageManager = AppGlobals.getPackageManager();
+            for (EnforcingAdmin admin : policies.keySet()) {
+                if (policies.get(admin).getValue() != null
+                        && policies.get(admin).getValue().getPackageName().equals(packageName)) {
+                    try {
+                        if (packageManager.getPackageInfo(packageName, 0, userId) == null
+                                || packageManager.getActivityInfo(
+                                        policies.get(admin).getValue(), 0, userId) == null) {
+                            Slogf.e(TAG, String.format(
+                                    "Persistent preferred activity in package %s not found for "
+                                            + "user %d, removing policy for admin",
+                                    packageName, userId));
+                            removeLocalPolicy(policyDefinition, admin, userId);
+                        }
+                    } catch (RemoteException re) {
+                        // Shouldn't happen.
+                        Slogf.wtf(TAG, "Error handling package changes", re);
+                    }
+                }
+            }
+        }
+    }
+
+    private boolean isPackageInstalled(String packageName, int userId) {
+        try {
+            return AppGlobals.getPackageManager().getPackageInfo(
+                    packageName, 0, userId) != null;
+        } catch (RemoteException re) {
+            // Shouldn't happen.
+            Slogf.wtf(TAG, "Error handling package changes", re);
+            return true;
         }
     }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 9d1c77d..6020711 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -232,7 +232,6 @@
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
 import static android.provider.DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER;
-import static android.provider.DeviceConfig.NAMESPACE_TELEPHONY;
 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
 import static android.provider.Settings.Secure.MANAGED_PROVISIONING_DPC_DOWNLOADED;
 import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
@@ -411,6 +410,7 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.UserManager.EnforcingUser;
 import android.os.UserManager.UserRestrictionSource;
 import android.os.storage.StorageManager;
 import android.permission.AdminPermissionControlParams;
@@ -876,10 +876,6 @@
     private static final String KEEP_PROFILES_RUNNING_FLAG = "enable_keep_profiles_running";
     public static final boolean DEFAULT_KEEP_PROFILES_RUNNING_FLAG = true;
 
-    private static final String ENABLE_WORK_PROFILE_TELEPHONY_FLAG =
-            "enable_work_profile_telephony";
-    private static final boolean DEFAULT_WORK_PROFILE_TELEPHONY_FLAG = false;
-
     // TODO(b/261999445) remove the flag after rollout.
     private static final String HEADLESS_FLAG = "headless";
     private static final boolean DEFAULT_HEADLESS_FLAG = true;
@@ -1389,6 +1385,7 @@
 
     private void handlePackagesChanged(@Nullable String packageName, int userHandle) {
         boolean removedAdmin = false;
+        String removedAdminPackage = null;
         if (VERBOSE_LOG) {
             Slogf.d(LOG_TAG, "Handling package changes package " + packageName
                     + " for user " + userHandle);
@@ -1411,6 +1408,7 @@
                                     "Admin package %s not found for user %d, removing active admin",
                                     packageName, userHandle));
                             removedAdmin = true;
+                            removedAdminPackage = adminPackage;
                             policy.mAdminList.remove(i);
                             policy.mAdminMap.remove(aa.info.getComponent());
                             pushActiveAdminPackagesLocked(userHandle);
@@ -1444,7 +1442,8 @@
                 startOwnerService(userHandle, "package-broadcast");
             }
             if (isPolicyEngineForFinanceFlagEnabled() || isPermissionCheckFlagEnabled()) {
-                mDevicePolicyEngine.handlePackageChanged(packageName, userHandle, removedAdmin);
+                mDevicePolicyEngine.handlePackageChanged(
+                        packageName, userHandle, removedAdminPackage);
             }
             // Persist updates if the removed package was an admin or delegate.
             if (removedAdmin || removedDelegate) {
@@ -2192,7 +2191,7 @@
 
     private void suspendAppsForQuietProfiles(boolean toSuspend) {
         PackageManagerInternal pmi = mInjector.getPackageManagerInternal();
-        List<UserInfo> users = mUserManager.getUsers();
+        List<UserInfo> users = mUserManagerInternal.getUsers(true /* excludeDying */);
         for (UserInfo user : users) {
             if (user.isManagedProfile() && user.isQuietModeEnabled()) {
                 pmi.setPackagesSuspendedForQuietMode(user.id, toSuspend);
@@ -3376,9 +3375,7 @@
                 onLockSettingsReady();
                 loadAdminDataAsync();
                 mOwners.systemReady();
-                if (isWorkProfileTelephonyEnabled()) {
-                    applyManagedSubscriptionsPolicyIfRequired();
-                }
+                applyManagedSubscriptionsPolicyIfRequired();
                 break;
             case SystemService.PHASE_ACTIVITY_MANAGER_READY:
                 synchronized (getLockObject()) {
@@ -3409,9 +3406,7 @@
             unregisterOnSubscriptionsChangedListener();
             int policyType = getManagedSubscriptionsPolicy().getPolicyType();
             if (policyType == ManagedSubscriptionsPolicy.TYPE_ALL_PERSONAL_SUBSCRIPTIONS) {
-                final int parentUserId = getProfileParentId(copeProfileUserId);
-                // By default, assign all current and future subs to system user on COPE devices.
-                registerListenerToAssignSubscriptionsToUser(parentUserId);
+                clearManagedSubscriptionsPolicy();
             } else if (policyType == ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS) {
                 // Add listener to assign all current and future subs to managed profile.
                 registerListenerToAssignSubscriptionsToUser(copeProfileUserId);
@@ -3541,7 +3536,9 @@
             deleteTransferOwnershipBundleLocked(metadata.userId);
         }
         updateSystemUpdateFreezePeriodsRecord(/* saveIfChanged */ true);
-        pushUserControlDisabledPackagesLocked(metadata.userId);
+        if (!isPolicyEngineForFinanceFlagEnabled()) {
+            pushUserControlDisabledPackagesLocked(metadata.userId);
+        }
     }
 
     private void maybeLogStart() {
@@ -7718,11 +7715,10 @@
         }
         mLockSettingsInternal.refreshStrongAuthTimeout(parentId);
 
-        if (isWorkProfileTelephonyEnabled()) {
-            clearManagedSubscriptionsPolicy();
-            clearLauncherShortcutOverrides();
-            updateTelephonyCrossProfileIntentFilters(parentId, UserHandle.USER_NULL, false);
-        }
+        clearManagedSubscriptionsPolicy();
+        clearLauncherShortcutOverrides();
+        updateTelephonyCrossProfileIntentFilters(parentId, UserHandle.USER_NULL, false);
+
         Slogf.i(LOG_TAG, "Cleaning up device-wide policies done.");
     }
 
@@ -10114,11 +10110,14 @@
         clearUserPoliciesLocked(userId);
         clearOverrideApnUnchecked();
         clearApplicationRestrictions(userId);
-        mInjector.getPackageManagerInternal().clearBlockUninstallForUser(userId);
+        if (!isPolicyEngineForFinanceFlagEnabled()) {
+            mInjector.getPackageManagerInternal().clearBlockUninstallForUser(userId);
+        }
 
         mOwners.clearDeviceOwner();
         mOwners.writeDeviceOwner();
 
+        updateAdminCanGrantSensorsPermissionCache(userId);
         clearDeviceOwnerUserRestriction(UserHandle.of(userId));
         mInjector.securityLogSetLoggingEnabledProperty(false);
         mSecurityLogMonitor.stop();
@@ -10966,8 +10965,13 @@
                 /* deviceOwnerUserId= */ deviceOwnerUserId, /* callingUserId*/ caller.getUserId(),
                 isAdb(caller), hasIncompatibleAccountsOrNonAdb);
         if (code != STATUS_OK) {
-            throw new IllegalStateException(computeProvisioningErrorStringLocked(code,
-                    deviceOwnerUserId, owner, showComponentOnError));
+            final String provisioningErrorStringLocked = computeProvisioningErrorStringLocked(code,
+                    deviceOwnerUserId, owner, showComponentOnError);
+            if (code == STATUS_HEADLESS_SYSTEM_USER_MODE_NOT_SUPPORTED) {
+                throw new ServiceSpecificException(code, provisioningErrorStringLocked);
+            } else {
+                throw new IllegalStateException(provisioningErrorStringLocked);
+            }
         }
     }
 
@@ -11021,6 +11025,9 @@
             case STATUS_HAS_PAIRED:
                 return "Not allowed to set the device owner because this device has already "
                         + "paired.";
+            case STATUS_HEADLESS_SYSTEM_USER_MODE_NOT_SUPPORTED:
+                return "Cannot provision an unsupported DPC into DO on a"
+                        + " headless device";
             default:
                 return "Unexpected @ProvisioningPreCondition: " + code;
         }
@@ -11334,11 +11341,10 @@
             synchronized (mSubscriptionsChangedListenerLock) {
                 pw.println("Subscription changed listener : " + mSubscriptionsChangedListener);
             }
-            pw.println("DPM Flag enable_work_profile_telephony : "
-                    + isWorkProfileTelephonyDevicePolicyManagerFlagEnabled());
-            pw.println("Telephony Flag enable_work_profile_telephony : "
-                    + isWorkProfileTelephonySubscriptionManagerFlagEnabled());
 
+            pw.println("DPM global setting ALLOW_WORK_PROFILE_TELEPHONY_FOR_NON_DPM_ROLE_HOLDERS : "
+                    + mInjector.settingsGlobalGetString(
+                    Global.ALLOW_WORK_PROFILE_TELEPHONY_FOR_NON_DPM_ROLE_HOLDERS));
             mHandler.post(() -> handleDump(pw));
             dumpResources(pw);
         }
@@ -11443,6 +11449,10 @@
                         || isDefaultDeviceOwner(caller) || isFinancedDeviceOwner(caller));
                 enforcingAdmin = getEnforcingAdminForCaller(who, callerPackageName);
             }
+            if (!isPackageInstalledForUser(activity.getPackageName(), userId)) {
+                // Fail early as packageManager doesn't persist the activity if its not installed.
+                return;
+            }
             mDevicePolicyEngine.setLocalPolicy(
                     PolicyDefinition.PERSISTENT_PREFERRED_ACTIVITY(filter),
                     enforcingAdmin,
@@ -11580,6 +11590,15 @@
             Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller)
                     || isProfileOwnerOfOrganizationOwnedDevice(caller));
         }
+
+        if (!parent && isManagedProfile(caller.getUserId())
+                && getManagedSubscriptionsPolicy().getPolicyType()
+                != ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS) {
+            throw new IllegalStateException(
+                    "Default sms application can only be set on the profile, when "
+                            + "ManagedSubscriptions policy is set");
+        }
+
         if (parent) {
             userId = getProfileParentId(mInjector.userHandleGetCallingUserId());
             mInjector.binderWithCleanCallingIdentity(() -> enforcePackageIsSystemPackage(
@@ -13376,14 +13395,8 @@
                 PolicyDefinition<Boolean> policyDefinition =
                         PolicyDefinition.getPolicyDefinitionForUserRestriction(key);
                 if (enabledFromThisOwner) {
-                    // TODO: Remove this special case - replace with breaking change to require
-                    //  setGlobally to disable ADB
-                    if (key.equals(UserManager.DISALLOW_DEBUGGING_FEATURES) && parent) {
-                        setGlobalUserRestrictionInternal(admin, key, /* enabled= */ true);
-                    } else {
-                        setLocalUserRestrictionInternal(
-                                admin, key, /* enabled= */ true, affectedUserId);
-                    }
+                    setLocalUserRestrictionInternal(
+                            admin, key, /* enabled= */ true, affectedUserId);
                 } else {
                     // Remove any local and global policy that was set by the admin
                     if (!policyDefinition.isLocalOnlyPolicy()) {
@@ -13901,7 +13914,6 @@
         CallerIdentity caller = getCallerIdentity(who, callerPackage);
         final int userId = parent ? getProfileParentId(caller.getUserId()) : caller.getUserId();
         if (isPolicyEngineForFinanceFlagEnabled()) {
-            // TODO: We need to ensure the delegate with DELEGATION_PACKAGE_ACCESS can do this
             enforcePermission(MANAGE_DEVICE_POLICY_PACKAGE_STATE, caller.getPackageName(), userId);
         } else {
             Preconditions.checkCallAuthorization((caller.hasAdminComponent()
@@ -15135,7 +15147,7 @@
             return;
         }
 
-        if ((flags == 0) || ((flags & ~(allowedFlags)) != 0)) {
+        if ((flags & ~(allowedFlags)) != 0) {
             throw new SecurityException(
                     "Permitted lock task features when managing a financed device: "
                             + "LOCK_TASK_FEATURE_SYSTEM_INFO, LOCK_TASK_FEATURE_KEYGUARD, "
@@ -15197,8 +15209,14 @@
 
     @Override
     public void setGlobalSetting(ComponentName who, String setting, String value) {
-        Objects.requireNonNull(who, "ComponentName is null");
         final CallerIdentity caller = getCallerIdentity(who);
+        if (Global.ALLOW_WORK_PROFILE_TELEPHONY_FOR_NON_DPM_ROLE_HOLDERS.equals(setting)) {
+            Preconditions.checkCallAuthorization(isCallerDevicePolicyManagementRoleHolder(caller));
+            mInjector.binderWithCleanCallingIdentity(
+                    () -> mInjector.settingsGlobalPutString(setting, value));
+            return;
+        }
+        Objects.requireNonNull(who, "ComponentName is null");
         Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller));
 
         DevicePolicyEventLogger
@@ -16066,8 +16084,8 @@
         }
 
         @Override
-        public List<String> getAllCrossProfilePackages() {
-            return DevicePolicyManagerService.this.getAllCrossProfilePackages();
+        public List<String> getAllCrossProfilePackages(int userId) {
+            return DevicePolicyManagerService.this.getAllCrossProfilePackages(userId);
         }
 
         @Override
@@ -16330,6 +16348,39 @@
                 return List.of(bundle);
             });
         }
+
+        public List<EnforcingUser> getUserRestrictionSources(String restriction,
+                @UserIdInt int userId) {
+            PolicyDefinition<Boolean> policy =
+                    PolicyDefinition.getPolicyDefinitionForUserRestriction(restriction);
+
+            Set<EnforcingAdmin> localAdmins =
+                    mDevicePolicyEngine.getLocalPoliciesSetByAdmins(policy, userId).keySet();
+
+            Set<EnforcingAdmin> globalAdmins =
+                    mDevicePolicyEngine.getGlobalPoliciesSetByAdmins(policy).keySet();
+
+            List<EnforcingUser> enforcingUsers = new ArrayList();
+            enforcingUsers.addAll(getEnforcingUsers(localAdmins));
+            enforcingUsers.addAll(getEnforcingUsers(globalAdmins));
+            return enforcingUsers;
+        }
+
+        private List<EnforcingUser> getEnforcingUsers(Set<EnforcingAdmin> admins) {
+            List<EnforcingUser> enforcingUsers = new ArrayList();
+            ComponentName deviceOwner = mOwners.getDeviceOwnerComponent();
+            for (EnforcingAdmin admin : admins) {
+                if (deviceOwner != null
+                        && deviceOwner.getPackageName().equals(admin.getPackageName())) {
+                    enforcingUsers.add(new EnforcingUser(admin.getUserId(),
+                            UserManager.RESTRICTION_SOURCE_DEVICE_OWNER));
+                } else {
+                    enforcingUsers.add(new EnforcingUser(admin.getUserId(),
+                            UserManager.RESTRICTION_SOURCE_PROFILE_OWNER));
+                }
+            }
+            return enforcingUsers;
+        }
     }
 
     private Intent createShowAdminSupportIntent(int userId) {
@@ -20286,7 +20337,7 @@
     }
 
     @Override
-    public List<String> getAllCrossProfilePackages() {
+    public List<String> getAllCrossProfilePackages(int userId) {
         if (!mHasFeature) {
             return Collections.emptyList();
         }
@@ -20295,10 +20346,10 @@
                 isSystemUid(caller) || isRootUid(caller) || hasCallingPermission(
                         permission.INTERACT_ACROSS_USERS) || hasCallingPermission(
                         permission.INTERACT_ACROSS_USERS_FULL) || hasPermissionForPreflight(
-                        caller, permission.INTERACT_ACROSS_PROFILES));
+                                                caller, permission.INTERACT_ACROSS_PROFILES));
 
         synchronized (getLockObject()) {
-            final List<ActiveAdmin> admins = getProfileOwnerAdminsForCurrentProfileGroup();
+            final List<ActiveAdmin> admins = getProfileOwnerAdminsForProfileGroup(userId);
             final List<String> packages = getCrossProfilePackagesForAdmins(admins);
 
             packages.addAll(getDefaultCrossProfilePackages());
@@ -20327,11 +20378,10 @@
         return new ArrayList<>(crossProfilePackages);
     }
 
-    private List<ActiveAdmin> getProfileOwnerAdminsForCurrentProfileGroup() {
+    private List<ActiveAdmin> getProfileOwnerAdminsForProfileGroup(int userId) {
         synchronized (getLockObject()) {
             final List<ActiveAdmin> admins = new ArrayList<>();
-            int[] users = mUserManager.getProfileIdsWithDisabled(
-                    mInjector.userHandleGetCallingUserId());
+            int[] users = mUserManager.getProfileIdsWithDisabled(userId);
             for (int i = 0; i < users.length; i++) {
                 final ComponentName componentName = getProfileOwnerAsUser(users[i]);
                 if (componentName != null) {
@@ -23791,26 +23841,6 @@
         suspendAppsForQuietProfiles(keepProfileRunning);
     }
 
-    private boolean isWorkProfileTelephonyEnabled() {
-        return isWorkProfileTelephonyDevicePolicyManagerFlagEnabled()
-                && isWorkProfileTelephonySubscriptionManagerFlagEnabled();
-    }
-
-    private boolean isWorkProfileTelephonyDevicePolicyManagerFlagEnabled() {
-        return DeviceConfig.getBoolean(NAMESPACE_DEVICE_POLICY_MANAGER,
-                ENABLE_WORK_PROFILE_TELEPHONY_FLAG, DEFAULT_WORK_PROFILE_TELEPHONY_FLAG);
-    }
-
-    private boolean isWorkProfileTelephonySubscriptionManagerFlagEnabled() {
-        final long ident = mInjector.binderClearCallingIdentity();
-        try {
-            return DeviceConfig.getBoolean(NAMESPACE_TELEPHONY, ENABLE_WORK_PROFILE_TELEPHONY_FLAG,
-                    false);
-        } finally {
-            mInjector.binderRestoreCallingIdentity(ident);
-        }
-    }
-
     @Override
     public void setOverrideKeepProfilesRunning(boolean enabled) {
         Preconditions.checkCallAuthorization(
@@ -23921,12 +23951,10 @@
 
     @Override
     public ManagedSubscriptionsPolicy getManagedSubscriptionsPolicy() {
-        if (isWorkProfileTelephonyEnabled()) {
-            synchronized (getLockObject()) {
-                ActiveAdmin admin = getProfileOwnerOfOrganizationOwnedDeviceLocked();
-                if (admin != null && admin.mManagedSubscriptionsPolicy != null) {
-                    return admin.mManagedSubscriptionsPolicy;
-                }
+        synchronized (getLockObject()) {
+            ActiveAdmin admin = getProfileOwnerOfOrganizationOwnedDeviceLocked();
+            if (admin != null && admin.mManagedSubscriptionsPolicy != null) {
+                return admin.mManagedSubscriptionsPolicy;
             }
         }
         return new ManagedSubscriptionsPolicy(
@@ -23935,10 +23963,14 @@
 
     @Override
     public void setManagedSubscriptionsPolicy(ManagedSubscriptionsPolicy policy) {
-        if (!isWorkProfileTelephonyEnabled()) {
+        CallerIdentity caller = getCallerIdentity();
+
+        if (!isCallerDevicePolicyManagementRoleHolder(caller)
+                && !Objects.equals(mInjector.settingsGlobalGetString(
+                        Global.ALLOW_WORK_PROFILE_TELEPHONY_FOR_NON_DPM_ROLE_HOLDERS), "1")) {
             throw new UnsupportedOperationException("This api is not enabled");
         }
-        CallerIdentity caller = getCallerIdentity();
+
         Preconditions.checkCallAuthorization(isProfileOwnerOfOrganizationOwnedDevice(caller),
                 "This policy can only be set by a profile owner on an organization-owned "
                         + "device.");
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 0c1c406..bb275e45 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -204,7 +204,15 @@
 
     @GuardedBy("mData")
     Set<Integer> getProfileOwnerUidsLocked() {
-        return mData.mProfileOwners.keySet();
+        Set<Integer> uids = new ArraySet<>();
+        for (int i = 0; i < mData.mProfileOwners.size(); i++) {
+            int userId = mData.mProfileOwners.keyAt(i);
+            OwnerInfo info = mData.mProfileOwners.valueAt(i);
+            uids.add(mPackageManagerInternal.getPackageUid(info.packageName,
+                    PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES,
+                    userId));
+        }
+        return uids;
     }
 
     String getDeviceOwnerPackageName() {
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 8f23ae4..4007672 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -34,6 +34,8 @@
 import android.os.UpdateEngine;
 import android.os.UpdateEngineCallback;
 import android.provider.DeviceConfig;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
 import android.util.Log;
 
 import com.android.internal.R;
@@ -332,8 +334,17 @@
         Context context = getContext();
         BackgroundThread.get().getThreadHandler().post(() -> {
             try {
+                int usageSetting = -1;
+                try {
+                    // Get "Usage & diagnostics" checkbox status. 1 is for enabled, 0 is for
+                    // disabled.
+                    usageSetting = Settings.Global.getInt(context.getContentResolver(), "multi_cb");
+                } catch (SettingNotFoundException e) {
+                    Log.i(LOG_TAG, "Usage setting not found: " + e.getMessage());
+                }
+
                 // Prepare profile report
-                String reportName = mIProfcollect.report() + ".zip";
+                String reportName = mIProfcollect.report(usageSetting) + ".zip";
 
                 if (!context.getResources().getBoolean(
                         R.bool.config_profcollectReportUploaderEnabled)) {
diff --git a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
index d128e68..4e46836 100644
--- a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
+++ b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
@@ -201,7 +201,7 @@
     }
 
     private void mockCrossProfileAppWhitelisted() {
-        when(mDevicePolicyManagerInternal.getAllCrossProfilePackages())
+        when(mDevicePolicyManagerInternal.getAllCrossProfilePackages(anyInt()))
                 .thenReturn(Lists.newArrayList(CROSS_PROFILE_APP_PACKAGE_NAME));
     }
 
@@ -662,7 +662,7 @@
     }
 
     private void mockCrossProfileAppNotWhitelisted() {
-        when(mDevicePolicyManagerInternal.getAllCrossProfilePackages())
+        when(mDevicePolicyManagerInternal.getAllCrossProfilePackages(anyInt()))
                 .thenReturn(new ArrayList<>());
     }
 
diff --git a/services/tests/PackageManagerServiceTests/host/Android.bp b/services/tests/PackageManagerServiceTests/host/Android.bp
index d9467a5..c7a71ee 100644
--- a/services/tests/PackageManagerServiceTests/host/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/Android.bp
@@ -39,7 +39,7 @@
         "PackageManagerServiceHostTestsIntentVerifyUtils",
         "block_device_writer_jar",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["device-tests"],
     data: [
         ":PackageManagerTestApex",
         ":PackageManagerTestApexApp",
diff --git a/services/tests/PackageManagerServiceTests/host/AndroidTest.xml b/services/tests/PackageManagerServiceTests/host/AndroidTest.xml
index 2382548..f594f6f 100644
--- a/services/tests/PackageManagerServiceTests/host/AndroidTest.xml
+++ b/services/tests/PackageManagerServiceTests/host/AndroidTest.xml
@@ -30,6 +30,7 @@
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="install-arg" value="-t" />
+        <option name="install-arg" value="-g" />
         <option name="test-file-name" value="PackageManagerServiceServerTests.apk" />
     </target_preparer>
 
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
index 6d3cdff..3200871 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
@@ -218,7 +218,6 @@
         AndroidPackage::isClearUserDataOnFailedRestoreAllowed,
         AndroidPackage::isAllowNativeHeapPointerTagging,
         AndroidPackage::isTaskReparentingAllowed,
-        AndroidPackage::isAllowUpdateOwnership,
         AndroidPackage::isBackupInForeground,
         AndroidPackage::isHardwareAccelerated,
         AndroidPackage::isSaveStateDisallowed,
diff --git a/services/tests/mockingservicestests/assets/AppOpsUpgradeTest/appops-version-3.xml b/services/tests/mockingservicestests/assets/AppOpsUpgradeTest/appops-version-3.xml
new file mode 100644
index 0000000..1363bf7
--- /dev/null
+++ b/services/tests/mockingservicestests/assets/AppOpsUpgradeTest/appops-version-3.xml
@@ -0,0 +1,801 @@
+<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<app-ops v="3">
+    <uid n="1001">
+        <op n="0" m="4" />
+        <op n="1" m="4" />
+        <op n="15" m="0" />
+        <op n="27" m="4" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="1002">
+        <op n="0" m="4" />
+        <op n="1" m="4" />
+        <op n="15" m="0" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10077">
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10079">
+        <op n="116" m="1" />
+    </uid>
+    <uid n="10080">
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10081">
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10086">
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10087">
+        <op n="59" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10090">
+        <op n="0" m="4" />
+        <op n="1" m="4" />
+    </uid>
+    <uid n="10096">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+    </uid>
+    <uid n="10112">
+        <op n="11" m="1" />
+        <op n="51" m="1" />
+        <op n="59" m="1" />
+        <op n="62" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10113">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="51" m="1" />
+        <op n="62" m="1" />
+    </uid>
+    <uid n="10114">
+        <op n="4" m="1" />
+    </uid>
+    <uid n="10115">
+        <op n="0" m="1" />
+    </uid>
+    <uid n="10116">
+        <op n="0" m="1" />
+    </uid>
+    <uid n="10117">
+        <op n="0" m="4" />
+        <op n="1" m="4" />
+        <op n="13" m="1" />
+        <op n="14" m="1" />
+        <op n="16" m="1" />
+        <op n="26" m="4" />
+        <op n="27" m="4" />
+    </uid>
+    <uid n="10118">
+        <op n="51" m="1" />
+    </uid>
+    <uid n="10119">
+        <op n="11" m="1" />
+        <op n="77" m="1" />
+        <op n="111" m="1" />
+    </uid>
+    <uid n="10120">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="4" m="1" />
+        <op n="6" m="1" />
+        <op n="7" m="1" />
+        <op n="11" m="1" />
+        <op n="13" m="1" />
+        <op n="26" m="1" />
+        <op n="27" m="1" />
+        <op n="54" m="1" />
+        <op n="59" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10121">
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10122">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="51" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10123">
+        <op n="0" m="4" />
+        <op n="1" m="4" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10124">
+        <op n="11" m="1" />
+        <op n="26" m="1" />
+    </uid>
+    <uid n="10125">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10127">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="26" m="4" />
+        <op n="27" m="4" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="65" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+        <op n="111" m="1" />
+    </uid>
+    <uid n="10129">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+    </uid>
+    <uid n="10130">
+        <op n="51" m="1" />
+    </uid>
+    <uid n="10131">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10132">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="26" m="1" />
+        <op n="27" m="1" />
+        <op n="69" m="1" />
+        <op n="79" m="1" />
+    </uid>
+    <uid n="10133">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10136">
+        <op n="0" m="1" />
+        <op n="4" m="1" />
+        <op n="77" m="1" />
+        <op n="87" m="1" />
+        <op n="111" m="1" />
+        <op n="114" m="1" />
+    </uid>
+    <uid n="10137">
+        <op n="62" m="1" />
+    </uid>
+    <uid n="10138">
+        <op n="26" m="4" />
+    </uid>
+    <uid n="10140">
+        <op n="26" m="4" />
+        <op n="27" m="4" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10141">
+        <op n="11" m="1" />
+        <op n="27" m="1" />
+        <op n="111" m="1" />
+    </uid>
+    <uid n="10142">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10144">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="4" m="1" />
+        <op n="11" m="1" />
+        <op n="27" m="4" />
+        <op n="111" m="1" />
+    </uid>
+    <uid n="10145">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10149">
+        <op n="11" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10150">
+        <op n="51" m="1" />
+    </uid>
+    <uid n="10151">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10152">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10154">
+        <op n="0" m="4" />
+        <op n="1" m="4" />
+        <op n="27" m="4" />
+    </uid>
+    <uid n="10155">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+    </uid>
+    <uid n="10157">
+        <op n="13" m="1" />
+    </uid>
+    <uid n="10158">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10160">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="11" m="1" />
+        <op n="26" m="4" />
+        <op n="27" m="4" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10161">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="11" m="1" />
+        <op n="51" m="1" />
+        <op n="77" m="1" />
+        <op n="87" m="1" />
+        <op n="111" m="1" />
+        <op n="114" m="1" />
+    </uid>
+    <uid n="10162">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="15" m="0" />
+        <op n="26" m="4" />
+        <op n="27" m="4" />
+        <op n="87" m="1" />
+        <op n="89" m="0" />
+    </uid>
+    <uid n="10163">
+        <op n="26" m="4" />
+        <op n="27" m="4" />
+        <op n="56" m="4" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10164">
+        <op n="26" m="1" />
+        <op n="27" m="4" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="69" m="1" />
+        <op n="79" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10169">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10170">
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10171">
+        <op n="26" m="1" />
+        <op n="51" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10172">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10173">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="23" m="0" />
+        <op n="26" m="1" />
+        <op n="51" m="1" />
+        <op n="62" m="1" />
+        <op n="65" m="1" />
+    </uid>
+    <uid n="10175">
+        <op n="0" m="1" />
+        <op n="11" m="1" />
+        <op n="26" m="1" />
+        <op n="27" m="1" />
+    </uid>
+    <uid n="10178">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="11" m="1" />
+        <op n="27" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10179">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="4" m="1" />
+        <op n="11" m="1" />
+        <op n="26" m="1" />
+        <op n="27" m="1" />
+        <op n="51" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="62" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10180">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10181">
+        <op n="4" m="1" />
+        <op n="11" m="1" />
+        <op n="26" m="1" />
+        <op n="27" m="1" />
+        <op n="59" m="1" />
+        <op n="62" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="1110181">
+        <op n="4" m="1" />
+        <op n="11" m="1" />
+        <op n="26" m="1" />
+        <op n="27" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+        <op n="107" m="2" />
+    </uid>
+    <uid n="10182">
+        <op n="27" m="4" />
+    </uid>
+    <uid n="10183">
+        <op n="11" m="1" />
+        <op n="26" m="4" />
+    </uid>
+    <uid n="10184">
+        <op n="4" m="1" />
+        <op n="11" m="1" />
+        <op n="13" m="1" />
+        <op n="26" m="1" />
+        <op n="27" m="4" />
+    </uid>
+    <uid n="10185">
+        <op n="8" m="1" />
+        <op n="59" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10187">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10189">
+        <op n="11" m="1" />
+        <op n="26" m="1" />
+        <op n="27" m="1" />
+        <op n="51" m="1" />
+    </uid>
+    <uid n="10190">
+        <op n="0" m="1" />
+        <op n="13" m="1" />
+    </uid>
+    <uid n="10191">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10192">
+        <op n="11" m="1" />
+        <op n="13" m="1" />
+        <op n="26" m="1" />
+        <op n="27" m="1" />
+        <op n="51" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10193">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10197">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10198">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="4" m="1" />
+        <op n="11" m="1" />
+        <op n="26" m="1" />
+        <op n="27" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="77" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+        <op n="90" m="1" />
+        <op n="107" m="0" />
+        <op n="111" m="1" />
+        <op n="133" m="0" />
+    </uid>
+    <uid n="10199">
+        <op n="4" m="1" />
+        <op n="11" m="1" />
+        <op n="26" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="62" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10200">
+        <op n="11" m="1" />
+        <op n="65" m="1" />
+        <op n="107" m="1" />
+        <op n="133" m="1" />
+    </uid>
+    <uid n="1110200">
+        <op n="11" m="1" />
+        <op n="65" m="1" />
+        <op n="107" m="2" />
+        <op n="133" m="2"/>
+    </uid>
+    <uid n="10201">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="4" m="1" />
+        <op n="11" m="1" />
+        <op n="51" m="1" />
+        <op n="62" m="1" />
+        <op n="84" m="0" />
+        <op n="86" m="0" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10206">
+        <op n="0" m="4" />
+        <op n="1" m="4" />
+        <op n="26" m="4" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10209">
+        <op n="11" m="1" />
+        <op n="51" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10210">
+        <op n="51" m="1" />
+    </uid>
+    <uid n="10212">
+        <op n="11" m="1" />
+        <op n="62" m="1" />
+    </uid>
+    <uid n="10214">
+        <op n="26" m="4" />
+    </uid>
+    <uid n="10216">
+        <op n="51" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10225">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="51" m="1" />
+        <op n="59" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10229">
+        <op n="11" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="62" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10231">
+        <op n="51" m="1" />
+    </uid>
+    <uid n="10232">
+        <op n="51" m="1" />
+    </uid>
+    <uid n="10234">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="11" m="1" />
+        <op n="13" m="1" />
+        <op n="20" m="1" />
+        <op n="26" m="1" />
+        <op n="27" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10235">
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10237">
+        <op n="0" m="4" />
+        <op n="1" m="4" />
+    </uid>
+    <uid n="10238">
+        <op n="26" m="4" />
+        <op n="27" m="4" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10240">
+        <op n="112" m="1" />
+    </uid>
+    <uid n="10241">
+        <op n="59" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10245">
+        <op n="13" m="1" />
+        <op n="51" m="1" />
+    </uid>
+    <uid n="10247">
+        <op n="0" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="0" />
+        <op n="90" m="1" />
+    </uid>
+    <uid n="10254">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10255">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10256">
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10258">
+        <op n="11" m="1" />
+    </uid>
+    <uid n="10260">
+        <op n="51" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <uid n="10262">
+        <op n="15" m="0" />
+    </uid>
+    <uid n="10266">
+        <op n="0" m="4" />
+    </uid>
+    <uid n="10267">
+        <op n="0" m="1" />
+        <op n="1" m="1" />
+        <op n="4" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="62" m="1" />
+        <op n="77" m="1" />
+        <op n="81" m="1" />
+        <op n="83" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+        <op n="107" m="2" />
+        <op n="111" m="1" />
+        <op n="133" m="2" />
+    </uid>
+    <uid n="10268">
+        <op n="4" m="1" />
+        <op n="11" m="1" />
+        <op n="62" m="1" />
+    </uid>
+    <uid n="10269">
+        <op n="11" m="1" />
+        <op n="26" m="1" />
+        <op n="27" m="1" />
+        <op n="59" m="1" />
+        <op n="60" m="1" />
+        <op n="85" m="1" />
+        <op n="87" m="1" />
+    </uid>
+    <pkg n="com.google.android.iwlan">
+        <uid n="0">
+            <op n="1" />
+            <op n="75" m="0" />
+        </uid>
+    </pkg>
+    <pkg n="com.android.phone">
+        <uid n="0">
+            <op n="1" />
+            <op n="75" m="0" />
+        </uid>
+    </pkg>
+    <pkg n="android">
+        <uid n="1000">
+            <op n="0">
+                <st n="214748364801" t="1670287941040" />
+            </op>
+            <op n="4">
+                <st n="214748364801" t="1670289665522" />
+            </op>
+            <op n="6">
+                <st n="214748364801" t="1670287946650" />
+            </op>
+            <op n="8">
+                <st n="214748364801" t="1670289624396" />
+            </op>
+            <op n="14">
+                <st n="214748364801" t="1670287951031" />
+            </op>
+            <op n="40">
+                <st n="214748364801" t="1670291786337" d="156" />
+            </op>
+            <op n="41">
+                <st id="SensorNotificationService" n="214748364801" t="1670287585567" d="4251183" />
+                <st id="CountryDetector" n="214748364801" t="1670287583306" d="6700" />
+            </op>
+            <op n="43">
+                <st n="214748364801" r="1670291755062" />
+            </op>
+            <op n="61">
+                <st n="214748364801" r="1670291754997" />
+            </op>
+            <op n="105">
+                <st n="214748364801" r="1670291473903" />
+                <st id="GnssService" n="214748364801" r="1670288044920" />
+            </op>
+            <op n="111">
+                <st n="214748364801" t="1670291441554" />
+            </op>
+        </uid>
+    </pkg>
+    <pkg n="com.android.server.telecom">
+        <uid n="1000">
+            <op n="6">
+                <st n="214748364801" t="1670287609092" />
+            </op>
+            <op n="111">
+                <st n="214748364801" t="1670287583728" />
+            </op>
+        </uid>
+    </pkg>
+    <pkg n="com.android.settings">
+        <uid n="1000">
+            <op n="43">
+                <st n="214748364801" r="1670291447349" />
+            </op>
+            <op n="105">
+                <st n="214748364801" r="1670291399231" />
+            </op>
+            <op n="111">
+                <st n="214748364801" t="1670291756910" />
+            </op>
+        </uid>
+    </pkg>
+    <pkg n="com.android.phone">
+        <uid n="1001">
+            <op n="15">
+                <st n="214748364801" t="1670287951022" />
+            </op>
+            <op n="40">
+                <st n="214748364801" t="1670291786177" />
+            </op>
+            <op n="105">
+                <st n="214748364801" r="1670291756403" />
+            </op>
+        </uid>
+    </pkg>
+    <pkg n="com.android.bluetooth">
+        <uid n="1002">
+            <op n="4">
+                <st n="214748364801" t="1670289671076" />
+            </op>
+            <op n="40">
+                <st n="214748364801" t="1670287585676" d="8" />
+            </op>
+            <op n="43">
+                <st n="214748364801" r="1670287585818" />
+            </op>
+            <op n="77">
+                <st n="214748364801" t="1670288037629" />
+            </op>
+            <op n="111">
+                <st n="214748364801" t="1670287592081" />
+            </op>
+        </uid>
+    </pkg>
+    <pkg n="com.android.vending">
+        <uid n="10136">
+            <op n="40">
+                <st n="429496729601" t="1670289621210" d="114" />
+                <st n="858993459201" t="1670289879730" d="349" />
+                <st n="1288490188801" t="1670287942622" d="937" />
+            </op>
+            <op n="43">
+                <st n="429496729601" r="1670289755305" />
+                <st n="858993459201" r="1670288019246" />
+                <st n="1073741824001" r="1670289571783" />
+                <st n="1288490188801" r="1670289373336" />
+            </op>
+            <op n="76">
+                <st n="429496729601" t="1670289748735" d="15991" />
+                <st n="858993459201" t="1670291395180" d="79201" />
+                <st n="1073741824001" t="1670291395168" d="12" />
+                <st n="1288490188801" t="1670291526029" d="3" />
+                <st n="1503238553601" t="1670291526032" d="310718" />
+            </op>
+            <op n="105">
+                <st n="429496729601" r="1670289538910" />
+                <st n="858993459201" r="1670288054519" />
+                <st n="1073741824001" r="1670287599379" />
+                <st n="1288490188801" r="1670289526854" />
+                <st n="1503238553601" r="1670289528242" />
+            </op>
+        </uid>
+    </pkg>
+    <pkg n="com.android.nfc">
+        <uid n="1027">
+            <op n="40">
+                <st n="214748364801" t="1670291786330" d="22" />
+            </op>
+        </uid>
+    </pkg>
+</app-ops>
\ No newline at end of file
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index f82d246..a614c4d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -37,6 +37,7 @@
 import static com.android.server.am.ProcessList.NETWORK_STATE_NO_CHANGE;
 import static com.android.server.am.ProcessList.NETWORK_STATE_UNBLOCK;
 
+import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.junit.Assert.assertEquals;
@@ -60,6 +61,7 @@
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
+import android.Manifest;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.BroadcastOptions;
@@ -82,13 +84,16 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
+import android.provider.DeviceConfig;
 import android.util.IntArray;
 import android.util.Log;
 import android.util.Pair;
 
 import androidx.test.filters.MediumTest;
 import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
 
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
 import com.android.server.LocalServices;
 import com.android.server.am.ActivityManagerService.StickyBroadcast;
 import com.android.server.am.ProcessList.IsolatedUidRange;
@@ -106,6 +111,7 @@
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -137,7 +143,9 @@
 
     private static final String TEST_EXTRA_KEY1 = "com.android.server.am.TEST_EXTRA_KEY1";
     private static final String TEST_EXTRA_VALUE1 = "com.android.server.am.TEST_EXTRA_VALUE1";
-
+    private static final String PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS =
+            "apply_sdk_sandbox_next_restrictions";
+    private static final String APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS = ":isSdkSandboxNext";
     private static final int TEST_UID = 11111;
     private static final int USER_ID = 666;
 
@@ -154,6 +162,7 @@
     };
 
     private static PackageManagerInternal sPackageManagerInternal;
+    private static ProcessList.ProcessListSettingsListener sProcessListSettingsListener;
 
     @BeforeClass
     public static void setUpOnce() {
@@ -181,7 +190,6 @@
     private ActivityManagerService mAms;
     private HandlerThread mHandlerThread;
     private TestHandler mHandler;
-
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -203,6 +211,15 @@
         mAms.mActivityTaskManager.initialize(null, null, mHandler.getLooper());
         mHandler.setRunnablesToIgnore(
                 List.of(mAms.mUidObserverController.getDispatchRunnableForTest()));
+
+        // Required for updating DeviceConfig.
+        InstrumentationRegistry.getInstrumentation()
+                .getUiAutomation()
+                .adoptShellPermissionIdentity(
+                Manifest.permission.READ_DEVICE_CONFIG,
+                Manifest.permission.WRITE_DEVICE_CONFIG);
+        sProcessListSettingsListener = mAms.mProcessList.getProcessListSettingsListener();
+        assertThat(sProcessListSettingsListener).isNotNull();
     }
 
     private void mockNoteOperation() {
@@ -216,6 +233,12 @@
     @After
     public void tearDown() {
         mHandlerThread.quit();
+        InstrumentationRegistry.getInstrumentation()
+            .getUiAutomation()
+            .dropShellPermissionIdentity();
+        if (sProcessListSettingsListener != null) {
+            sProcessListSettingsListener.unregisterObserver();
+        }
     }
 
     @SuppressWarnings("GuardedBy")
@@ -268,6 +291,77 @@
                 false); // expectNotify
     }
 
+    @SuppressWarnings("GuardedBy")
+    @SmallTest
+    @Test
+    public void defaultSdkSandboxNextRestrictions() throws Exception {
+        sProcessListSettingsListener.onPropertiesChanged(
+                new DeviceConfig.Properties(
+                DeviceConfig.NAMESPACE_ADSERVICES,
+                Map.of(PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS, "")));
+        assertThat(
+            sProcessListSettingsListener.applySdkSandboxRestrictionsNext())
+            .isFalse();
+    }
+
+    @SuppressWarnings("GuardedBy")
+    @SmallTest
+    @Test
+    public void doNotApplySdkSandboxNextRestrictions() throws Exception {
+        MockitoSession mockitoSession =
+                ExtendedMockito.mockitoSession().spyStatic(Process.class).startMocking();
+        try {
+            sProcessListSettingsListener.onPropertiesChanged(
+                    new DeviceConfig.Properties(
+                    DeviceConfig.NAMESPACE_ADSERVICES,
+                    Map.of(PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS, "false")));
+            assertThat(
+                sProcessListSettingsListener.applySdkSandboxRestrictionsNext())
+                .isFalse();
+            ExtendedMockito.doReturn(true).when(() -> Process.isSdkSandboxUid(anyInt()));
+            ApplicationInfo info = new ApplicationInfo();
+            info.packageName = "com.android.sdksandbox";
+            info.seInfo = "default:targetSdkVersion=34:complete";
+            final ProcessRecord appRec = new ProcessRecord(
+                    mAms, info, TAG, Process.FIRST_SDK_SANDBOX_UID,
+                    /* sdkSandboxClientPackageName= */ "com.example.client",
+                    /* definingUid= */ 0, /* definingProcessName= */ "");
+            assertThat(mAms.mProcessList.updateSeInfo(appRec)).doesNotContain(
+                    APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS);
+        } finally {
+            mockitoSession.finishMocking();
+        }
+    }
+    @SuppressWarnings("GuardedBy")
+    @SmallTest
+    @Test
+    public void applySdkSandboxNextRestrictions() throws Exception {
+        MockitoSession mockitoSession =
+                ExtendedMockito.mockitoSession().spyStatic(Process.class).startMocking();
+        try {
+            sProcessListSettingsListener.onPropertiesChanged(
+                    new DeviceConfig.Properties(
+                    DeviceConfig.NAMESPACE_ADSERVICES,
+                    Map.of(PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS, "true")));
+            assertThat(
+                sProcessListSettingsListener.applySdkSandboxRestrictionsNext())
+                .isTrue();
+            ExtendedMockito.doReturn(true).when(() -> Process.isSdkSandboxUid(anyInt()));
+            ApplicationInfo info = new ApplicationInfo();
+            info.packageName = "com.android.sdksandbox";
+            info.seInfo = "default:targetSdkVersion=34:complete";
+            final ProcessRecord appRec = new ProcessRecord(
+                    mAms, info, TAG, Process.FIRST_SDK_SANDBOX_UID,
+                    /* sdkSandboxClientPackageName= */ "com.example.client",
+                    /* definingUid= */ 0, /* definingProcessName= */ "");
+            assertThat(mAms.mProcessList.updateSeInfo(appRec)).contains(
+                    APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS);
+        } finally {
+            mockitoSession.finishMocking();
+        }
+    }
+
+
     private UidRecord addUidRecord(int uid) {
         final UidRecord uidRec = new UidRecord(uid, mAms);
         uidRec.procStateSeqWaitingForNetwork = 1;
@@ -648,24 +742,24 @@
 
         broadcastIntent(intent1, null, true);
         assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION1, TEST_USER),
-                StickyBroadcast.create(intent1, false));
+                StickyBroadcast.create(intent1, false, Process.myUid()));
         assertNull(mAms.getStickyBroadcasts(TEST_ACTION2, TEST_USER));
         assertNull(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER));
 
         broadcastIntent(intent2, options.toBundle(), true);
         assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION1, TEST_USER),
-                StickyBroadcast.create(intent1, false));
+                StickyBroadcast.create(intent1, false, Process.myUid()));
         assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION2, TEST_USER),
-                StickyBroadcast.create(intent2, true));
+                StickyBroadcast.create(intent2, true, Process.myUid()));
         assertNull(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER));
 
         broadcastIntent(intent3, null, true);
         assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION1, TEST_USER),
-                StickyBroadcast.create(intent1, false));
+                StickyBroadcast.create(intent1, false, Process.myUid()));
         assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION2, TEST_USER),
-                StickyBroadcast.create(intent2, true));
+                StickyBroadcast.create(intent2, true, Process.myUid()));
         assertStickyBroadcasts(mAms.getStickyBroadcasts(TEST_ACTION3, TEST_USER),
-                StickyBroadcast.create(intent3, false));
+                StickyBroadcast.create(intent3, false, Process.myUid()));
     }
 
     @SuppressWarnings("GuardedBy")
@@ -698,6 +792,9 @@
         if (a.deferUntilActive != b.deferUntilActive) {
             return false;
         }
+        if (a.originalCallingUid != b.originalCallingUid) {
+            return false;
+        }
         return true;
     }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
index 581fe4a..6bce71e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
@@ -77,6 +77,7 @@
 import android.os.BundleMerger;
 import android.os.DropBoxManager;
 import android.os.HandlerThread;
+import android.os.Process;
 import android.os.SystemClock;
 import android.os.TestLooperManager;
 import android.os.UserHandle;
@@ -327,6 +328,20 @@
     }
 
     @Test
+    public void testRunnableList_sameRunnableAt() {
+        doReturn(2L).when(mQueue1).getRunnableAt();
+        doReturn(2L).when(mQueue2).getRunnableAt();
+        doReturn(2L).when(mQueue3).getRunnableAt();
+        doReturn(2L).when(mQueue4).getRunnableAt();
+
+        mHead = insertIntoRunnableList(mHead, mQueue1);
+        mHead = insertIntoRunnableList(mHead, mQueue2);
+        mHead = insertIntoRunnableList(mHead, mQueue3);
+        mHead = insertIntoRunnableList(mHead, mQueue4);
+        assertRunnableList(List.of(mQueue1, mQueue2, mQueue3, mQueue4), mHead);
+    }
+
+    @Test
     public void testProcessQueue_Complex() {
         BroadcastProcessQueue red = mImpl.getOrCreateProcessQueue(PACKAGE_RED, TEST_UID);
         BroadcastProcessQueue green = mImpl.getOrCreateProcessQueue(PACKAGE_GREEN, TEST_UID);
@@ -537,6 +552,44 @@
         assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason());
     }
 
+    @Test
+    public void testRunnableAt_persistentProc() {
+        final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN,
+                getUidForPackage(PACKAGE_GREEN));
+
+        final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
+        final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick,
+                List.of(makeMockRegisteredReceiver()));
+        enqueueOrReplaceBroadcast(queue, timeTickRecord, 0);
+
+        assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime);
+        assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason());
+
+        doReturn(true).when(mProcess).isPersistent();
+        queue.setProcessAndUidState(mProcess, false, false);
+        assertThat(queue.getRunnableAt()).isLessThan(timeTickRecord.enqueueTime);
+        assertEquals(BroadcastProcessQueue.REASON_PERSISTENT, queue.getRunnableAtReason());
+
+        doReturn(false).when(mProcess).isPersistent();
+        queue.setProcessAndUidState(mProcess, false, false);
+        assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime);
+        assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason());
+    }
+
+    @Test
+    public void testRunnableAt_coreUid() {
+        final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
+                "com.android.bluetooth", Process.BLUETOOTH_UID);
+
+        final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
+        final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick,
+                List.of(makeMockRegisteredReceiver()));
+        enqueueOrReplaceBroadcast(queue, timeTickRecord, 0);
+
+        assertThat(queue.getRunnableAt()).isEqualTo(timeTickRecord.enqueueTime);
+        assertEquals(BroadcastProcessQueue.REASON_CORE_UID, queue.getRunnableAtReason());
+    }
+
     /**
      * Verify that a cached process that would normally be delayed becomes
      * immediately runnable when the given broadcast is enqueued.
@@ -923,6 +976,166 @@
                 List.of(musicVolumeChanged, alarmVolumeChanged, timeTick));
     }
 
+    @Test
+    public void testDeliveryGroupPolicy_diffReceivers() {
+        final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
+        final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
+        final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
+                .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
+                .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);
+
+        final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
+        final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
+        final Object blueReceiver = makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE);
+
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+                List.of(greenReceiver, blueReceiver), false));
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+                List.of(greenReceiver, redReceiver, blueReceiver), false));
+        final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
+                getUidForPackage(PACKAGE_GREEN));
+        final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
+                getUidForPackage(PACKAGE_RED));
+        final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
+                getUidForPackage(PACKAGE_BLUE));
+        verifyPendingRecords(greenQueue, List.of(screenOff));
+        verifyPendingRecords(redQueue, List.of(screenOff));
+        verifyPendingRecords(blueQueue, List.of(screenOff));
+
+        assertTrue(greenQueue.isEmpty());
+        assertTrue(redQueue.isEmpty());
+        assertTrue(blueQueue.isEmpty());
+
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+                List.of(greenReceiver, redReceiver, blueReceiver), false));
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+                List.of(greenReceiver, blueReceiver), false));
+        verifyPendingRecords(greenQueue, List.of(screenOn));
+        verifyPendingRecords(redQueue, List.of(screenOff));
+        verifyPendingRecords(blueQueue, List.of(screenOn));
+    }
+
+    @Test
+    public void testDeliveryGroupPolicy_ordered_diffReceivers() {
+        final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
+        final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
+        final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
+                .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
+                .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);
+
+        final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
+        final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
+        final Object blueReceiver = makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE);
+
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+                List.of(greenReceiver, blueReceiver), true));
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+                List.of(greenReceiver, redReceiver, blueReceiver), true));
+        final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
+                getUidForPackage(PACKAGE_GREEN));
+        final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
+                getUidForPackage(PACKAGE_RED));
+        final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
+                getUidForPackage(PACKAGE_BLUE));
+        verifyPendingRecords(greenQueue, List.of(screenOff));
+        verifyPendingRecords(redQueue, List.of(screenOff));
+        verifyPendingRecords(blueQueue, List.of(screenOff));
+
+        assertTrue(greenQueue.isEmpty());
+        assertTrue(redQueue.isEmpty());
+        assertTrue(blueQueue.isEmpty());
+
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+                List.of(greenReceiver, redReceiver, blueReceiver), true));
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+                List.of(greenReceiver, blueReceiver), true));
+        verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
+        verifyPendingRecords(redQueue, List.of(screenOff));
+        verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));
+    }
+
+    @Test
+    public void testDeliveryGroupPolicy_resultTo_diffReceivers() {
+        final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
+        final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
+        final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
+                .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
+                .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);
+
+        final Object greenReceiver = makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN);
+        final Object redReceiver = makeManifestReceiver(PACKAGE_RED, CLASS_RED);
+        final Object blueReceiver = makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE);
+        final IIntentReceiver resultTo = mock(IIntentReceiver.class);
+
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+                List.of(greenReceiver, blueReceiver), resultTo, false));
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+                List.of(greenReceiver, redReceiver, blueReceiver), resultTo, false));
+        final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
+                getUidForPackage(PACKAGE_GREEN));
+        final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
+                getUidForPackage(PACKAGE_RED));
+        final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
+                getUidForPackage(PACKAGE_BLUE));
+        verifyPendingRecords(greenQueue, List.of(screenOff));
+        verifyPendingRecords(redQueue, List.of(screenOff));
+        verifyPendingRecords(blueQueue, List.of(screenOff));
+
+        assertTrue(greenQueue.isEmpty());
+        assertTrue(redQueue.isEmpty());
+        assertTrue(blueQueue.isEmpty());
+
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+                List.of(greenReceiver, redReceiver, blueReceiver), resultTo, false));
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+                List.of(greenReceiver, blueReceiver), resultTo, false));
+        verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
+        verifyPendingRecords(redQueue, List.of(screenOff));
+        verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));
+    }
+
+    @Test
+    public void testDeliveryGroupPolicy_prioritized_diffReceivers() {
+        final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON);
+        final Intent screenOff = new Intent(Intent.ACTION_SCREEN_OFF);
+        final BroadcastOptions screenOnOffOptions = BroadcastOptions.makeBasic()
+                .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
+                .setDeliveryGroupMatchingKey("screenOnOff", Intent.ACTION_SCREEN_ON);
+
+        final Object greenReceiver = withPriority(
+                makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 10);
+        final Object redReceiver = withPriority(
+                makeManifestReceiver(PACKAGE_RED, CLASS_RED), 5);
+        final Object blueReceiver = withPriority(
+                makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE), 0);
+
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+                List.of(greenReceiver, blueReceiver), false));
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+                List.of(greenReceiver, redReceiver, blueReceiver), false));
+        final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN,
+                getUidForPackage(PACKAGE_GREEN));
+        final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED,
+                getUidForPackage(PACKAGE_RED));
+        final BroadcastProcessQueue blueQueue = mImpl.getProcessQueue(PACKAGE_BLUE,
+                getUidForPackage(PACKAGE_BLUE));
+        verifyPendingRecords(greenQueue, List.of(screenOff));
+        verifyPendingRecords(redQueue, List.of(screenOff));
+        verifyPendingRecords(blueQueue, List.of(screenOff));
+
+        assertTrue(greenQueue.isEmpty());
+        assertTrue(redQueue.isEmpty());
+        assertTrue(blueQueue.isEmpty());
+
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOff, screenOnOffOptions,
+                List.of(greenReceiver, redReceiver, blueReceiver), false));
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(screenOn, screenOnOffOptions,
+                List.of(greenReceiver, blueReceiver), false));
+        verifyPendingRecords(greenQueue, List.of(screenOff, screenOn));
+        verifyPendingRecords(redQueue, List.of(screenOff));
+        verifyPendingRecords(blueQueue, List.of(screenOff, screenOn));
+    }
+
     /**
      * Verify that sending a broadcast with DELIVERY_GROUP_POLICY_MERGED works as expected.
      */
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
index ad5f0d7..6365764 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
@@ -269,7 +269,9 @@
                     deliverRes = res;
                     break;
             }
+            res.setPendingStart(true);
             mHandlerThread.getThreadHandler().post(() -> {
+                res.setPendingStart(false);
                 synchronized (mAms) {
                     switch (behavior) {
                         case SUCCESS:
@@ -281,6 +283,10 @@
                             mActiveProcesses.remove(deliverRes);
                             mQueue.onApplicationTimeoutLocked(deliverRes);
                             break;
+                        case KILLED_WITHOUT_NOTIFY:
+                            mActiveProcesses.remove(res);
+                            res.setKilled(true);
+                            break;
                         default:
                             throw new UnsupportedOperationException();
                     }
@@ -310,6 +316,7 @@
         mConstants = new BroadcastConstants(Settings.Global.BROADCAST_FG_CONSTANTS);
         mConstants.TIMEOUT = 100;
         mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT = 0;
+        mConstants.PENDING_COLD_START_CHECK_INTERVAL_MILLIS = 500;
 
         mSkipPolicy = spy(new BroadcastSkipPolicy(mAms));
         doReturn(null).when(mSkipPolicy).shouldSkipMessage(any(), any());
@@ -381,6 +388,8 @@
         FAIL_TIMEOUT_PREDECESSOR,
         /** Process fails by immediately returning null */
         FAIL_NULL,
+        /** Process is killed without reporting to BroadcastQueue */
+        KILLED_WITHOUT_NOTIFY,
     }
 
     private enum ProcessBehavior {
@@ -522,6 +531,11 @@
         return info;
     }
 
+    static BroadcastFilter withPriority(BroadcastFilter filter, int priority) {
+        filter.setPriority(priority);
+        return filter;
+    }
+
     static ResolveInfo makeManifestReceiver(String packageName, String name) {
         return makeManifestReceiver(packageName, name, UserHandle.USER_SYSTEM);
     }
@@ -1261,6 +1275,46 @@
                 new ComponentName(PACKAGE_GREEN, CLASS_GREEN));
     }
 
+    /**
+     * Verify that when BroadcastQueue doesn't get notified when a process gets killed, it
+     * doesn't get stuck.
+     */
+    @Test
+    public void testKillWithoutNotify() throws Exception {
+        final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED);
+        final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE);
+
+        mNextProcessStartBehavior.set(ProcessStartBehavior.KILLED_WITHOUT_NOTIFY);
+
+        final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+        enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of(
+                withPriority(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN), 10),
+                withPriority(makeRegisteredReceiver(receiverBlueApp), 5),
+                withPriority(makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW), 0))));
+
+        final Intent timezone = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
+        enqueueBroadcast(makeBroadcastRecord(timezone, callerApp,
+                List.of(makeManifestReceiver(PACKAGE_ORANGE, CLASS_ORANGE))));
+
+        waitForIdle();
+        final ProcessRecord receiverGreenApp = mAms.getProcessRecordLocked(PACKAGE_GREEN,
+                getUidForPackage(PACKAGE_GREEN));
+        final ProcessRecord receiverYellowApp = mAms.getProcessRecordLocked(PACKAGE_YELLOW,
+                getUidForPackage(PACKAGE_YELLOW));
+        final ProcessRecord receiverOrangeApp = mAms.getProcessRecordLocked(PACKAGE_ORANGE,
+                getUidForPackage(PACKAGE_ORANGE));
+
+        if (mImpl == Impl.MODERN) {
+            // Modern queue does not retry sending a broadcast once any broadcast delivery fails.
+            assertNull(receiverGreenApp);
+        } else {
+            verifyScheduleReceiver(times(1), receiverGreenApp, airplane);
+        }
+        verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, airplane);
+        verifyScheduleReceiver(times(1), receiverYellowApp, airplane);
+        verifyScheduleReceiver(times(1), receiverOrangeApp, timezone);
+    }
+
     @Test
     public void testCold_Success() throws Exception {
         doCold(ProcessStartBehavior.SUCCESS);
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUpgradeTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUpgradeTest.java
index 5474c20..92d1118 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUpgradeTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUpgradeTest.java
@@ -17,6 +17,7 @@
 package com.android.server.appop;
 
 import static android.app.AppOpsManager.OP_SCHEDULE_EXACT_ALARM;
+import static android.app.AppOpsManager.OP_USE_FULL_SCREEN_INTENT;
 import static android.app.AppOpsManager._NUM_OP;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
@@ -31,6 +32,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.isA;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.never;
@@ -44,6 +46,7 @@
 import android.content.res.AssetManager;
 import android.os.Handler;
 import android.os.UserHandle;
+import android.permission.PermissionManager;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseArray;
@@ -87,6 +90,10 @@
             "AppOpsUpgradeTest/appops-unversioned.xml";
     private static final String APP_OPS_VERSION_1_ASSET_PATH =
             "AppOpsUpgradeTest/appops-version-1.xml";
+
+    private static final String APP_OPS_VERSION_3_ASSET_PATH =
+            "AppOpsUpgradeTest/appops-version-3.xml";
+
     private static final String APP_OPS_FILENAME = "appops-test.xml";
 
     private static final Context sContext = InstrumentationRegistry.getTargetContext();
@@ -105,6 +112,8 @@
     private PermissionManagerServiceInternal mPermissionManagerInternal;
     @Mock
     private Handler mHandler;
+    @Mock
+    private PermissionManager mPermissionManager;
 
     private Object mLock = new Object();
     private SparseArray<int[]> mSwitchedOps;
@@ -211,7 +220,7 @@
         }
     }
 
-    private static int getModeInFile(int uid) {
+    private static int getModeInFile(int uid, int op) {
         switch (uid) {
             case 10198:
                 return 0;
@@ -222,7 +231,7 @@
             case 1110181:
                 return 2;
             default:
-                return AppOpsManager.opToDefaultMode(OP_SCHEDULE_EXACT_ALARM);
+                return AppOpsManager.opToDefaultMode(op);
         }
     }
 
@@ -258,7 +267,7 @@
         for (int userId : userIds) {
             for (int appId : appIds) {
                 final int uid = UserHandle.getUid(userId, appId);
-                final int previousMode = getModeInFile(uid);
+                final int previousMode = getModeInFile(uid, OP_SCHEDULE_EXACT_ALARM);
 
                 final int expectedMode;
                 if (previousMode == AppOpsManager.opToDefaultMode(OP_SCHEDULE_EXACT_ALARM)) {
@@ -281,6 +290,55 @@
     }
 
     @Test
+    public void resetUseFullScreenIntent() {
+        extractAppOpsFile(APP_OPS_VERSION_3_ASSET_PATH);
+
+        String[] packageNames = {"p1", "package2", "pkg3", "package.4", "pkg-5", "pkg.6"};
+        int[] appIds = {10267, 10181, 10198, 10199, 10200, 4213};
+        int[] userIds = {0, 10, 11};
+        int flag = 0;
+
+        doReturn(userIds).when(mUserManagerInternal).getUserIds();
+
+        doReturn(packageNames).when(mPermissionManagerInternal).getAppOpPermissionPackages(
+                AppOpsManager.opToPermission(OP_USE_FULL_SCREEN_INTENT));
+
+        doReturn(mPermissionManager).when(mTestContext).getSystemService(PermissionManager.class);
+
+        doReturn(flag).when(mPackageManager).getPermissionFlags(
+                anyString(), anyString(), isA(UserHandle.class));
+
+        doAnswer(invocation -> {
+            String pkg = invocation.getArgument(0);
+            int index = ArrayUtils.indexOf(packageNames, pkg);
+            if (index < 0) {
+                return index;
+            }
+            int userId = invocation.getArgument(2);
+            return UserHandle.getUid(userId, appIds[index]);
+        }).when(mPackageManagerInternal).getPackageUid(anyString(), anyLong(), anyInt());
+
+        AppOpsCheckingServiceImpl testService = new AppOpsCheckingServiceImpl(sAppOpsFile, mLock,
+                mHandler, mTestContext, mSwitchedOps);
+        testService.readState();
+
+        synchronized (testService) {
+            testService.resetUseFullScreenIntentLocked();
+        }
+
+        for (int userId : userIds) {
+            for (int appId : appIds) {
+                final int uid = UserHandle.getUid(userId, appId);
+                final int expectedMode = AppOpsManager.opToDefaultMode(OP_USE_FULL_SCREEN_INTENT);
+                synchronized (testService) {
+                    int mode = testService.getUidMode(uid, OP_USE_FULL_SCREEN_INTENT);
+                    assertEquals(expectedMode, mode);
+                }
+            }
+        }
+    }
+
+    @Test
     public void upgradeFromNoFile() {
         assertFalse(sAppOpsFile.exists());
 
@@ -290,12 +348,14 @@
 
         doNothing().when(testService).upgradeRunAnyInBackgroundLocked();
         doNothing().when(testService).upgradeScheduleExactAlarmLocked();
+        doNothing().when(testService).resetUseFullScreenIntentLocked();
 
         // trigger upgrade
         testService.systemReady();
 
         verify(testService, never()).upgradeRunAnyInBackgroundLocked();
         verify(testService, never()).upgradeScheduleExactAlarmLocked();
+        verify(testService, never()).resetUseFullScreenIntentLocked();
 
         testService.writeState();
 
@@ -319,12 +379,14 @@
 
         doNothing().when(testService).upgradeRunAnyInBackgroundLocked();
         doNothing().when(testService).upgradeScheduleExactAlarmLocked();
+        doNothing().when(testService).resetUseFullScreenIntentLocked();
 
         // trigger upgrade
         testService.systemReady();
 
         verify(testService).upgradeRunAnyInBackgroundLocked();
         verify(testService).upgradeScheduleExactAlarmLocked();
+        verify(testService).resetUseFullScreenIntentLocked();
 
         testService.writeState();
         assertTrue(parser.parse());
@@ -344,12 +406,40 @@
 
         doNothing().when(testService).upgradeRunAnyInBackgroundLocked();
         doNothing().when(testService).upgradeScheduleExactAlarmLocked();
+        doNothing().when(testService).resetUseFullScreenIntentLocked();
 
         // trigger upgrade
         testService.systemReady();
 
         verify(testService, never()).upgradeRunAnyInBackgroundLocked();
         verify(testService).upgradeScheduleExactAlarmLocked();
+        verify(testService).resetUseFullScreenIntentLocked();
+
+        testService.writeState();
+        assertTrue(parser.parse());
+        assertEquals(AppOpsCheckingServiceImpl.CURRENT_VERSION, parser.mVersion);
+    }
+
+    @Test
+    public void resetFromVersion3() {
+        extractAppOpsFile(APP_OPS_VERSION_3_ASSET_PATH);
+        AppOpsDataParser parser = new AppOpsDataParser(sAppOpsFile);
+        assertTrue(parser.parse());
+        assertEquals(3, parser.mVersion);
+
+        AppOpsCheckingServiceImpl testService = spy(new AppOpsCheckingServiceImpl(sAppOpsFile,
+                mLock, mHandler, mTestContext, mSwitchedOps));
+        testService.readState();
+
+        doNothing().when(testService).upgradeRunAnyInBackgroundLocked();
+        doNothing().when(testService).upgradeScheduleExactAlarmLocked();
+        doNothing().when(testService).resetUseFullScreenIntentLocked();
+
+        testService.systemReady();
+
+        verify(testService, never()).upgradeRunAnyInBackgroundLocked();
+        verify(testService, never()).upgradeScheduleExactAlarmLocked();
+        verify(testService).resetUseFullScreenIntentLocked();
 
         testService.writeState();
         assertTrue(parser.parse());
diff --git a/services/tests/mockingservicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceMockingTest.java b/services/tests/mockingservicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceMockingTest.java
new file mode 100644
index 0000000..a885307
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceMockingTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.companion.virtual;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.Looper;
+import android.platform.test.annotations.Presubmit;
+import android.testing.TestableContext;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class VirtualDeviceManagerServiceMockingTest {
+    private static final int UID_1 = 0;
+    private static final int DEVICE_ID_1 = 42;
+    private static final int DEVICE_ID_2 = 43;
+
+    @Rule
+    public final TestableContext mContext = new TestableContext(
+            InstrumentationRegistry.getContext());
+
+    private VirtualDeviceManagerService mVdms;
+    private VirtualDeviceManagerInternal mLocalService;
+
+    @Before
+    public void setUp() {
+        mVdms = new VirtualDeviceManagerService(mContext);
+        mLocalService = mVdms.getLocalServiceInstance();
+    }
+
+    @Test
+    public void onAuthenticationPrompt_noDevices_noCrash() {
+        // This should not crash
+        mLocalService.onAuthenticationPrompt(UID_1);
+    }
+
+    @Test
+    public void onAuthenticationPrompt_oneDevice_showToastWhereUidIsRunningIsCalled() {
+        VirtualDeviceImpl device = mock(VirtualDeviceImpl.class);
+        mVdms.addVirtualDevice(device);
+
+        mLocalService.onAuthenticationPrompt(UID_1);
+
+        verify(device).showToastWhereUidIsRunning(eq(UID_1),
+                eq(R.string.app_streaming_blocked_message_for_fingerprint_dialog), anyInt(),
+                any(Looper.class));
+    }
+
+    @Test
+    public void onAuthenticationPrompt_twoDevices_showToastWhereUidIsRunningIsCalledOnBoth() {
+        VirtualDeviceImpl device1 = mock(VirtualDeviceImpl.class);
+        VirtualDeviceImpl device2 = mock(VirtualDeviceImpl.class);
+        when(device1.getDeviceId()).thenReturn(DEVICE_ID_1);
+        when(device2.getDeviceId()).thenReturn(DEVICE_ID_2);
+        mVdms.addVirtualDevice(device1);
+        mVdms.addVirtualDevice(device2);
+
+        mLocalService.onAuthenticationPrompt(UID_1);
+
+        verify(device1).showToastWhereUidIsRunning(eq(UID_1),
+                eq(R.string.app_streaming_blocked_message_for_fingerprint_dialog), anyInt(),
+                any(Looper.class));
+        verify(device2).showToastWhereUidIsRunning(eq(UID_1),
+                eq(R.string.app_streaming_blocked_message_for_fingerprint_dialog), anyInt(),
+                any(Looper.class));
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
index 9cd22dd..c5ff8cc 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
@@ -402,13 +402,15 @@
         JobStatus rescheduledJob = mService.getRescheduleJobForFailureLocked(originalJob,
                 JobParameters.STOP_REASON_DEVICE_STATE,
                 JobParameters.INTERNAL_STOP_REASON_DEVICE_THERMAL);
-        assertEquals(nowElapsed + initialBackoffMs, rescheduledJob.getEarliestRunTime());
+        assertEquals(JobStatus.NO_EARLIEST_RUNTIME, rescheduledJob.getEarliestRunTime());
         assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed());
 
         // failure = 0, systemStop = 2
         rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob,
                 JobParameters.STOP_REASON_DEVICE_STATE,
                 JobParameters.INTERNAL_STOP_REASON_PREEMPT);
+        assertEquals(JobStatus.NO_EARLIEST_RUNTIME, rescheduledJob.getEarliestRunTime());
+        assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed());
         // failure = 0, systemStop = 3
         rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob,
                 JobParameters.STOP_REASON_CONSTRAINT_CHARGING,
@@ -438,6 +440,13 @@
                 JobParameters.INTERNAL_STOP_REASON_SUCCESSFUL_FINISH);
         assertEquals(nowElapsed + 4 * initialBackoffMs, rescheduledJob.getEarliestRunTime());
         assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed());
+
+        // failure = 3, systemStop = 2 * SYSTEM_STOP_TO_FAILURE_RATIO
+        rescheduledJob = mService.getRescheduleJobForFailureLocked(rescheduledJob,
+                JobParameters.STOP_REASON_UNDEFINED,
+                JobParameters.INTERNAL_STOP_REASON_ANR);
+        assertEquals(nowElapsed + 5 * initialBackoffMs, rescheduledJob.getEarliestRunTime());
+        assertEquals(JobStatus.NO_LATEST_RUNTIME, rescheduledJob.getLatestRunTimeElapsed());
     }
 
     /**
diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
index 3d0163d..51e521d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
@@ -292,7 +292,8 @@
         verifyLastWallpaperData(testUserId, sDefaultWallpaperComponent);
         verifyCurrentSystemData(testUserId);
 
-        mService.setWallpaperComponent(sImageWallpaperComponentName, FLAG_SYSTEM, testUserId);
+        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
+                FLAG_SYSTEM, testUserId);
         verifyLastWallpaperData(testUserId, sImageWallpaperComponentName);
         verifyCurrentSystemData(testUserId);
 
@@ -321,7 +322,8 @@
 
         WallpaperManagerService.DisplayConnector connector =
                 mService.mLastWallpaper.connection.getDisplayConnectorOrCreate(DEFAULT_DISPLAY);
-        mService.setWallpaperComponent(sDefaultWallpaperComponent, FLAG_SYSTEM, testUserId);
+        mService.setWallpaperComponent(sDefaultWallpaperComponent, sContext.getOpPackageName(),
+                FLAG_SYSTEM, testUserId);
 
         verify(connector.mEngine).dispatchWallpaperCommand(
                 eq(COMMAND_REAPPLY), anyInt(), anyInt(), anyInt(), any());
@@ -465,7 +467,8 @@
     public void testGetAdjustedWallpaperColorsOnDimming() throws RemoteException {
         final int testUserId = USER_SYSTEM;
         mService.switchUser(testUserId, null);
-        mService.setWallpaperComponent(sDefaultWallpaperComponent, FLAG_SYSTEM, testUserId);
+        mService.setWallpaperComponent(sDefaultWallpaperComponent, sContext.getOpPackageName(),
+                FLAG_SYSTEM, testUserId);
         WallpaperData wallpaper = mService.getCurrentWallpaperData(FLAG_SYSTEM, testUserId);
 
         // Mock a wallpaper data with color hints that support dark text and dark theme
diff --git a/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java b/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java
index 01563e2..36a565e 100644
--- a/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/DropboxRateLimiterTest.java
@@ -140,19 +140,19 @@
         // Repeated crashes after the last reset being rate limited should be restricted faster.
         assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
 
-        // We now need to wait 61 minutes for the buffer should be empty again.
-        mClock.setOffsetMillis(83 * 60 * 1000);
+        // We now need to wait 21 minutes for the buffer should be empty again.
+        mClock.setOffsetMillis(43 * 60 * 1000);
         assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
 
-        // After yet another 61 minutes, this time without triggering rate limiting, the strict
+        // After yet another 21 minutes, this time without triggering rate limiting, the strict
         // limiting should be turnd off.
-        mClock.setOffsetMillis(144 * 60 * 1000);
+        mClock.setOffsetMillis(64 * 60 * 1000);
         assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
         assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
 
         // As rate limiting was not triggered in the last reset, after another 11 minutes the
         // buffer should still act as normal.
-        mClock.setOffsetMillis(155 * 60 * 1000);
+        mClock.setOffsetMillis(75 * 60 * 1000);
         // The first 6 entries should not be rate limited.
         assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
         assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit());
diff --git a/services/tests/servicestests/src/com/android/server/am/FgsLoggerTest.java b/services/tests/servicestests/src/com/android/server/am/FgsLoggerTest.java
index 44d6dec..f5005fd 100644
--- a/services/tests/servicestests/src/com/android/server/am/FgsLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/FgsLoggerTest.java
@@ -26,6 +26,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
@@ -41,7 +42,6 @@
 
 import org.junit.Before;
 import org.junit.Test;
-import org.mockito.AdditionalMatchers;
 
 /**
  * Test class for {@link ForegroundServiceTypeLoggerModule}.
@@ -61,10 +61,10 @@
         mFgsLogger = spy(logger);
         doNothing().when(mFgsLogger)
                 .logFgsApiEvent(any(ServiceRecord.class),
-                        anyInt(), anyInt(), any(int[].class), any(long[].class));
+                        anyInt(), anyInt(), anyInt(), anyLong());
         doNothing().when(mFgsLogger)
                 .logFgsApiEventWithNoFgs(anyInt(),
-                        anyInt(), any(int[].class), any(long[].class));
+                        anyInt(), anyInt(), anyLong());
     }
 
     @Test
@@ -73,10 +73,10 @@
         record.foregroundServiceType = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
         mFgsLogger.logForegroundServiceStart(1, 1, record);
         mFgsLogger.logForegroundServiceApiEventBegin(1, 1, 1, "aPackageHasNoName");
-        int[] expectedTypes = {1};
+        int expectedTypes = 1;
         verify(mFgsLogger).logFgsApiEvent(any(ServiceRecord.class),
                 eq(FGS_STATE_CHANGED_API_CALL), eq(FGS_API_BEGIN_WITH_FGS),
-                AdditionalMatchers.aryEq(expectedTypes), any(long[].class));
+                eq(expectedTypes), anyLong());
         reset(mFgsLogger);
         mFgsLogger.logForegroundServiceApiEventEnd(1, 1, 1);
 
@@ -85,7 +85,7 @@
         mFgsLogger.logForegroundServiceStop(1, record);
         verify(mFgsLogger).logFgsApiEvent(any(ServiceRecord.class),
                 eq(FGS_STATE_CHANGED_API_CALL), eq(FGS_API_END_WITH_FGS),
-                AdditionalMatchers.aryEq(expectedTypes), any(long[].class));
+                eq(expectedTypes), anyLong());
     }
 
     @Test
@@ -97,10 +97,10 @@
         resetAndVerifyZeroInteractions();
 
         mFgsLogger.logForegroundServiceStart(1, 1, record);
-        int[] expectedTypes = {1};
+        int expectedTypes = 1;
         verify(mFgsLogger).logFgsApiEvent(any(ServiceRecord.class),
                 eq(FGS_STATE_CHANGED_API_CALL), eq(FGS_API_BEGIN_WITH_FGS),
-                AdditionalMatchers.aryEq(expectedTypes), any(long[].class));
+                eq(expectedTypes), anyLong());
         reset(mFgsLogger);
         mFgsLogger.logForegroundServiceApiEventEnd(1, 1, 1);
 
@@ -109,7 +109,7 @@
         mFgsLogger.logForegroundServiceStop(1, record);
         verify(mFgsLogger).logFgsApiEvent(any(ServiceRecord.class),
                 eq(FGS_STATE_CHANGED_API_CALL), eq(FGS_API_END_WITH_FGS),
-                AdditionalMatchers.aryEq(expectedTypes), any(long[].class));
+                eq(expectedTypes), anyLong());
     }
 
     @Test
@@ -122,12 +122,12 @@
 
         resetAndVerifyZeroInteractions();
 
-        int[] expectedTypes = {1};
+        int expectedTypes = 1;
 
         mFgsLogger.logForegroundServiceStart(1, 1, record);
         verify(mFgsLogger).logFgsApiEvent(any(ServiceRecord.class),
                 eq(FGS_STATE_CHANGED_API_CALL), eq(FGS_API_BEGIN_WITH_FGS),
-                AdditionalMatchers.aryEq(expectedTypes), any(long[].class));
+                eq(expectedTypes), anyLong());
         reset(mFgsLogger);
         mFgsLogger.logForegroundServiceStop(1, record);
 
@@ -135,7 +135,7 @@
 
         mFgsLogger.logForegroundServiceApiEventEnd(FOREGROUND_SERVICE_API_TYPE_CAMERA, 1, 1);
         verify(mFgsLogger).logFgsApiEventWithNoFgs(eq(1), eq(FGS_API_END_WITHOUT_FGS),
-                AdditionalMatchers.aryEq(expectedTypes), any(long[].class));
+                eq(expectedTypes), anyLong());
     }
 
     @Test
@@ -176,15 +176,15 @@
         // now we should see exactly one call logged
         // and this should be the very first call
         // we also try to verify the time as being the very first call
-        int[] expectedTypes = {1};
-        long[] expectedTimestamp = {timeStamp};
+        int expectedTypes = 1;
+        long expectedTimestamp = timeStamp;
 
         verify(mFgsLogger, times(1))
                 .logFgsApiEvent(any(ServiceRecord.class),
                         eq(FGS_STATE_CHANGED_API_CALL),
                         eq(FGS_API_BEGIN_WITH_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes),
-                        AdditionalMatchers.aryEq(expectedTimestamp));
+                        eq(expectedTypes),
+                        eq(expectedTimestamp));
         reset(mFgsLogger);
         // now we do multiple stops
         // only the last one should be logged
@@ -201,11 +201,11 @@
         mFgsLogger.logForegroundServiceApiEventEnd(FOREGROUND_SERVICE_API_TYPE_CAMERA, 1, 1);
         timeStamp = mFgsLogger.logForegroundServiceApiEventEnd(FOREGROUND_SERVICE_API_TYPE_CAMERA,
                 1, 1);
-        expectedTimestamp[0] = timeStamp;
+        expectedTimestamp = timeStamp;
         verify(mFgsLogger, times(1))
                 .logFgsApiEventWithNoFgs(eq(1), eq(FGS_API_END_WITHOUT_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes),
-                        AdditionalMatchers.aryEq(expectedTimestamp));
+                        eq(expectedTypes),
+                        eq(expectedTimestamp));
     }
 
     @Test
@@ -239,15 +239,15 @@
         // now we should see exactly one call logged
         // and this should be the very first call
         // we also try to verify the time as being the very first call
-        int[] expectedTypes = {1};
-        long[] expectedTimestamp = {timeStamp};
+        int expectedTypes = 1;
+        long expectedTimestamp = timeStamp;
 
         verify(mFgsLogger, times(1))
                 .logFgsApiEvent(any(ServiceRecord.class),
                         eq(FGS_STATE_CHANGED_API_CALL),
                         eq(FGS_API_BEGIN_WITH_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes),
-                        AdditionalMatchers.aryEq(expectedTimestamp));
+                        eq(expectedTypes),
+                        eq(expectedTimestamp));
         reset(mFgsLogger);
         // now we do multiple stops
         // only the last one should be logged
@@ -269,11 +269,11 @@
                 1, 1);
         mFgsLogger.logForegroundServiceApiEventEnd(FOREGROUND_SERVICE_API_TYPE_CAMERA, 1, 1);
         mFgsLogger.logForegroundServiceApiEventEnd(FOREGROUND_SERVICE_API_TYPE_CAMERA, 1, 1);
-        expectedTimestamp[0] = timeStamp;
+        expectedTimestamp = timeStamp;
         verify(mFgsLogger, times(1))
                 .logFgsApiEventWithNoFgs(eq(1), eq(FGS_API_END_WITHOUT_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes),
-                        AdditionalMatchers.aryEq(expectedTimestamp));
+                        eq(expectedTypes),
+                        eq(expectedTimestamp));
     }
 
     @Test
@@ -304,15 +304,15 @@
         // now we should see exactly one call logged
         // and this should be the very first call
         // we also try to verify the time as being the very first call
-        int[] expectedTypes = {1};
-        long[] expectedTimestamp = {timeStamp};
+        int expectedTypes = 1;
+        long expectedTimestamp = timeStamp;
 
         verify(mFgsLogger, times(1))
                 .logFgsApiEvent(any(ServiceRecord.class),
                         eq(FGS_STATE_CHANGED_API_CALL),
                         eq(FGS_API_BEGIN_WITH_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes),
-                        AdditionalMatchers.aryEq(expectedTimestamp));
+                        eq(expectedTypes),
+                        eq(expectedTimestamp));
         reset(mFgsLogger);
         mFgsLogger.logForegroundServiceApiEventBegin(FOREGROUND_SERVICE_API_TYPE_CAMERA, 1, 1,
                 "aPackageHasNoName");
@@ -338,11 +338,11 @@
                 1, 1);
         mFgsLogger.logForegroundServiceApiEventEnd(FOREGROUND_SERVICE_API_TYPE_CAMERA, 1, 1);
         mFgsLogger.logForegroundServiceApiEventEnd(FOREGROUND_SERVICE_API_TYPE_CAMERA, 1, 1);
-        expectedTimestamp[0] = timeStamp;
+        expectedTimestamp = timeStamp;
         verify(mFgsLogger, times(1))
                 .logFgsApiEventWithNoFgs(eq(1), eq(FGS_API_END_WITHOUT_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes),
-                        AdditionalMatchers.aryEq(expectedTimestamp));
+                        eq(expectedTypes),
+                        eq(expectedTimestamp));
     }
 
     @Test
@@ -375,15 +375,15 @@
         // now we should see exactly one call logged
         // and this should be the very first call
         // we also try to verify the time as being the very first call
-        int[] expectedTypes = {1};
-        long[] expectedTimestamp = {timeStamp};
+        int expectedTypes = 1;
+        long expectedTimestamp = timeStamp;
 
         verify(mFgsLogger, times(1))
                 .logFgsApiEvent(any(ServiceRecord.class),
                         eq(FGS_STATE_CHANGED_API_CALL),
                         eq(FGS_API_BEGIN_WITH_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes),
-                        AdditionalMatchers.aryEq(expectedTimestamp));
+                        eq(expectedTypes),
+                        eq(expectedTimestamp));
         reset(mFgsLogger);
         mFgsLogger.logForegroundServiceApiEventBegin(FOREGROUND_SERVICE_API_TYPE_CAMERA, 1, 1,
                 "aPackageHasNoName");
@@ -410,16 +410,16 @@
         timeStamp = mFgsLogger.logForegroundServiceApiEventEnd(1, 1, 1);
         mFgsLogger.logForegroundServiceApiEventEnd(FOREGROUND_SERVICE_API_TYPE_CAMERA, 1, 1);
         mFgsLogger.logForegroundServiceApiEventEnd(FOREGROUND_SERVICE_API_TYPE_CAMERA, 1, 1);
-        expectedTimestamp[0] = timeStamp;
+        expectedTimestamp = timeStamp;
         verify(mFgsLogger, times(1))
                 .logFgsApiEventWithNoFgs(eq(1), eq(FGS_API_END_WITHOUT_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes),
-                        AdditionalMatchers.aryEq(expectedTimestamp));
+                        eq(expectedTypes),
+                        eq(expectedTimestamp));
     }
 
     @Test
     public void testMultipleUid() throws InterruptedException {
-        int[] expectedTypes = {1};
+        int expectedTypes = 1;
         ServiceRecord record = ServiceRecord.newEmptyInstanceForTest(null);
         record.foregroundServiceType = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
         ActivityManagerService ams = mock(ActivityManagerService.class);
@@ -477,7 +477,7 @@
                 .logFgsApiEvent(any(ServiceRecord.class),
                         eq(FGS_STATE_CHANGED_API_CALL),
                         eq(FGS_API_BEGIN_WITH_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes), any(long[].class));
+                        eq(expectedTypes), anyLong());
         reset(mFgsLogger);
         mFgsLogger.logForegroundServiceApiEventBegin(FOREGROUND_SERVICE_API_TYPE_CAMERA, 1, 1,
                 "aPackageHasNoName");
@@ -511,16 +511,16 @@
         mFgsLogger.logForegroundServiceApiEventEnd(FOREGROUND_SERVICE_API_TYPE_CAMERA, 2, 1);
         timeStamp2 = mFgsLogger.logForegroundServiceApiEventEnd(FOREGROUND_SERVICE_API_TYPE_CAMERA,
                 2, 1);
-        long[] expectedTimestamp = {timeStamp};
-        long[] expectedTimestamp2 = {timeStamp2};
+        long expectedTimestamp = timeStamp;
+        long expectedTimestamp2 = timeStamp2;
         verify(mFgsLogger, times(1))
                 .logFgsApiEventWithNoFgs(eq(1), eq(FGS_API_END_WITHOUT_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes),
-                        AdditionalMatchers.aryEq(expectedTimestamp));
+                        eq(expectedTypes),
+                        eq(expectedTimestamp));
         verify(mFgsLogger, times(1))
                 .logFgsApiEventWithNoFgs(eq(2), eq(FGS_API_END_WITHOUT_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes),
-                        AdditionalMatchers.aryEq(expectedTimestamp2));
+                        eq(expectedTypes),
+                        eq(expectedTimestamp2));
     }
 
     @Test
@@ -551,15 +551,15 @@
         // now we should see exactly one call logged
         // and this should be the very first call
         // we also try to verify the time as being the very first call
-        int[] expectedTypes = {1};
-        long[] expectedTimestamp = {timeStamp};
+        int expectedTypes = 1;
+        long expectedTimestamp = timeStamp;
 
         verify(mFgsLogger, times(1))
                 .logFgsApiEvent(any(ServiceRecord.class),
                         eq(FGS_STATE_CHANGED_API_CALL),
                         eq(FGS_API_BEGIN_WITH_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes),
-                        AdditionalMatchers.aryEq(expectedTimestamp));
+                        eq(expectedTypes),
+                        eq(expectedTimestamp));
         reset(mFgsLogger);
         mFgsLogger.logForegroundServiceApiEventBegin(FOREGROUND_SERVICE_API_TYPE_CAMERA, 1, 1,
                 "aPackageHasNoName");
@@ -590,13 +590,13 @@
         // now we do multiple stops
         // only the last one should be logged
         mFgsLogger.logForegroundServiceStop(1, record);
-        expectedTimestamp[0] = timeStamp;
+        expectedTimestamp = timeStamp;
         verify(mFgsLogger, times(1))
                 .logFgsApiEvent(any(ServiceRecord.class),
                         eq(FGS_STATE_CHANGED_API_CALL),
                         eq(FGS_API_END_WITH_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes),
-                        AdditionalMatchers.aryEq(expectedTimestamp));
+                        eq(expectedTypes),
+                        eq(expectedTimestamp));
     }
 
     @Test
@@ -610,16 +610,25 @@
         long timestamp2 = mFgsLogger.logForegroundServiceApiEventBegin(
                 FOREGROUND_SERVICE_API_TYPE_MICROPHONE,
                 1, 1, "aPackageHasNoName");
-        int[] expectedTypes = {1, FOREGROUND_SERVICE_API_TYPE_MICROPHONE};
-        long[] expectedTimestamp = {timestamp1, timestamp2};
+        int expectedTypes = 1;
+        int expectedType2 = FOREGROUND_SERVICE_API_TYPE_MICROPHONE;
+        long expectedTimestamp = timestamp1;
+        long expectedTimestamp2 = timestamp2;
         mFgsLogger.logForegroundServiceStart(1, 1, record);
 
         verify(mFgsLogger, times(1))
                 .logFgsApiEvent(any(ServiceRecord.class),
                         eq(FGS_STATE_CHANGED_API_CALL),
                         eq(FGS_API_BEGIN_WITH_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes),
-                        AdditionalMatchers.aryEq(expectedTimestamp));
+                        eq(expectedTypes),
+                        eq(expectedTimestamp));
+
+        verify(mFgsLogger, times(1))
+                .logFgsApiEvent(any(ServiceRecord.class),
+                        eq(FGS_STATE_CHANGED_API_CALL),
+                        eq(FGS_API_BEGIN_WITH_FGS),
+                        eq(expectedType2),
+                        eq(expectedTimestamp2));
 
         reset(mFgsLogger);
         resetAndVerifyZeroInteractions();
@@ -632,28 +641,34 @@
 
         mFgsLogger.logForegroundServiceStop(1, record);
 
-        expectedTimestamp[0] = timestamp1;
-        expectedTimestamp[1] = timestamp2;
+        expectedTimestamp = timestamp1;
+        expectedTimestamp2 = timestamp2;
 
         verify(mFgsLogger, times(1))
                 .logFgsApiEvent(any(ServiceRecord.class),
                         eq(FGS_STATE_CHANGED_API_CALL),
                         eq(FGS_API_END_WITH_FGS),
-                        AdditionalMatchers.aryEq(expectedTypes),
-                        AdditionalMatchers.aryEq(expectedTimestamp));
+                        eq(expectedTypes),
+                        eq(expectedTimestamp));
+        verify(mFgsLogger, times(1))
+                .logFgsApiEvent(any(ServiceRecord.class),
+                        eq(FGS_STATE_CHANGED_API_CALL),
+                        eq(FGS_API_END_WITH_FGS),
+                        eq(expectedType2),
+                        eq(expectedTimestamp2));
 
     }
 
     private void resetAndVerifyZeroInteractions() {
         doNothing().when(mFgsLogger)
                 .logFgsApiEvent(any(ServiceRecord.class),
-                        anyInt(), anyInt(), any(int[].class), any(long[].class));
+                        anyInt(), anyInt(), anyInt(), anyLong());
         doNothing().when(mFgsLogger)
-                .logFgsApiEventWithNoFgs(anyInt(), anyInt(), any(int[].class), any(long[].class));
+                .logFgsApiEventWithNoFgs(anyInt(), anyInt(), anyInt(), anyLong());
         verify(mFgsLogger, times(0))
                 .logFgsApiEvent(any(ServiceRecord.class),
-                        anyInt(), anyInt(), any(int[].class), any(long[].class));
+                        anyInt(), anyInt(), anyInt(), anyLong());
         verify(mFgsLogger, times(0))
-                .logFgsApiEventWithNoFgs(anyInt(), anyInt(), any(int[].class), any(long[].class));
+                .logFgsApiEventWithNoFgs(anyInt(), anyInt(), anyInt(), anyLong());
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index 317fd58..dccacb4 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -58,6 +58,7 @@
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doCallRealMethod;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -103,11 +104,13 @@
 import com.android.server.pm.UserJourneyLogger;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.pm.UserManagerService;
+import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.WindowManagerService;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -187,6 +190,7 @@
             doNothing().when(mInjector).activityManagerOnUserStopped(anyInt());
             doNothing().when(mInjector).clearBroadcastQueueForUser(anyInt());
             doNothing().when(mInjector).taskSupervisorRemoveUser(anyInt());
+            doNothing().when(mInjector).lockDeviceNowAndWaitForKeyguardShown();
             mockIsUsersOnSecondaryDisplaysEnabled(false);
             // All UserController params are set to default.
 
@@ -951,6 +955,45 @@
                 .systemServiceManagerOnUserCompletedEvent(eq(user2), eq(event2a));
     }
 
+    @Test
+    public void testStallUserSwitchUntilTheKeyguardIsShown() throws Exception {
+        // enable user switch ui, because keyguard is only shown then
+        mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
+                /* maxRunningUsers= */ 3, /* delayUserDataLocking= */ false);
+
+        // mock the device to be secure in order to expect the keyguard to be shown
+        when(mInjector.mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(true);
+
+        // call real lockDeviceNowAndWaitForKeyguardShown method for this test
+        doCallRealMethod().when(mInjector).lockDeviceNowAndWaitForKeyguardShown();
+
+        // call startUser on a thread because we're expecting it to be blocked
+        Thread threadStartUser = new Thread(()-> {
+            mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
+        });
+        threadStartUser.start();
+
+        // make sure the switch is stalled...
+        Thread.sleep(2000);
+        // by checking REPORT_USER_SWITCH_MSG is not sent yet
+        assertNull(mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG));
+        // and the thread is still alive
+        assertTrue(threadStartUser.isAlive());
+
+        // mock send the keyguard shown event
+        ArgumentCaptor<ActivityTaskManagerInternal.ScreenObserver> captor = ArgumentCaptor.forClass(
+                ActivityTaskManagerInternal.ScreenObserver.class);
+        verify(mInjector.mActivityTaskManagerInternal).registerScreenObserver(captor.capture());
+        captor.getValue().onKeyguardStateChanged(true);
+
+        // verify the switch now moves on...
+        Thread.sleep(1000);
+        // by checking REPORT_USER_SWITCH_MSG is sent
+        assertNotNull(mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG));
+        // and the thread is finished
+        assertFalse(threadStartUser.isAlive());
+    }
+
     private void setUpAndStartUserInBackground(int userId) throws Exception {
         setUpUser(userId, 0);
         mUserController.startUser(userId, USER_START_MODE_BACKGROUND);
@@ -1092,6 +1135,7 @@
         private final IStorageManager mStorageManagerMock;
         private final UserManagerInternal mUserManagerInternalMock;
         private final WindowManagerService mWindowManagerMock;
+        private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
         private final KeyguardManager mKeyguardManagerMock;
         private final LockPatternUtils mLockPatternUtilsMock;
 
@@ -1111,6 +1155,7 @@
             mUserManagerMock = mock(UserManagerService.class);
             mUserManagerInternalMock = mock(UserManagerInternal.class);
             mWindowManagerMock = mock(WindowManagerService.class);
+            mActivityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
             mStorageManagerMock = mock(IStorageManager.class);
             mKeyguardManagerMock = mock(KeyguardManager.class);
             when(mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(true);
@@ -1172,6 +1217,11 @@
         }
 
         @Override
+        ActivityTaskManagerInternal getActivityTaskManagerInternal() {
+            return mActivityTaskManagerInternal;
+        }
+
+        @Override
         KeyguardManager getKeyguardManager() {
             return mKeyguardManagerMock;
         }
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
index 85d159c..f88afe7 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
@@ -58,6 +58,8 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.R;
+import com.android.server.LocalServices;
+import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -102,6 +104,8 @@
     IFaceService mFaceService;
     @Mock
     AppOpsManager mAppOpsManager;
+    @Mock
+    private VirtualDeviceManagerInternal mVdmInternal;
     @Captor
     private ArgumentCaptor<List<FingerprintSensorPropertiesInternal>> mFingerprintPropsCaptor;
     @Captor
@@ -115,6 +119,8 @@
                 "1:4:15", // ID1:Iris:Strong
                 "2:8:15", // ID2:Face:Strong
         };
+        LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
+        LocalServices.addService(VirtualDeviceManagerInternal.class, mVdmInternal);
 
         when(mResources.getIntArray(eq(R.array.config_udfps_sensor_props))).thenReturn(new int[0]);
         when(mResources.getBoolean(eq(R.bool.config_is_powerbutton_fps))).thenReturn(false);
@@ -152,7 +158,8 @@
 
         verify(mBiometricService, never()).registerAuthenticator(
                 anyInt(),
-                any(),
+                anyInt(),
+                anyInt(),
                 any());
     }
 
@@ -272,6 +279,47 @@
     }
 
     @Test
+    public void testAuthenticate_noVdmInternalService_noCrash() throws Exception {
+        LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
+        mAuthService = new AuthService(mContext, mInjector);
+        mAuthService.onStart();
+
+        final Binder token = new Binder();
+
+        // This should not crash
+        mAuthService.mImpl.authenticate(
+                token,
+                0, /* sessionId */
+                0, /* userId */
+                mReceiver,
+                TEST_OP_PACKAGE_NAME,
+                new PromptInfo());
+        waitForIdle();
+    }
+
+    @Test
+    public void testAuthenticate_callsVirtualDeviceManagerOnAuthenticationPrompt()
+            throws Exception {
+        mAuthService = new AuthService(mContext, mInjector);
+        mAuthService.onStart();
+
+        final Binder token = new Binder();
+
+        mAuthService.mImpl.authenticate(
+                token,
+                0, /* sessionId */
+                0, /* userId */
+                mReceiver,
+                TEST_OP_PACKAGE_NAME,
+                new PromptInfo());
+        waitForIdle();
+
+        ArgumentCaptor<Integer> uidCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mVdmInternal).onAuthenticationPrompt(uidCaptor.capture());
+        assertEquals((int) (uidCaptor.getValue()), Binder.getCallingUid());
+    }
+
+    @Test
     public void testAuthenticate_throwsWhenUsingTestConfigurations() {
         final PromptInfo promptInfo = mock(PromptInfo.class);
         when(promptInfo.containsPrivateApiConfigurations()).thenReturn(false);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
index 26a3ae1..4268eb9 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
@@ -45,14 +45,13 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.hardware.biometrics.BiometricManager.Authenticators;
+import android.hardware.biometrics.ComponentInfoInternal;
 import android.hardware.biometrics.IBiometricAuthenticator;
 import android.hardware.biometrics.IBiometricSensorReceiver;
 import android.hardware.biometrics.IBiometricServiceReceiver;
 import android.hardware.biometrics.IBiometricSysuiReceiver;
 import android.hardware.biometrics.PromptInfo;
 import android.hardware.biometrics.SensorProperties;
-import android.hardware.face.FaceSensorProperties;
-import android.hardware.face.FaceSensorPropertiesInternal;
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintSensorProperties;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
@@ -232,7 +231,14 @@
     public void testMultiAuth_singleSensor_fingerprintSensorStartsAfterDialogAnimationCompletes()
             throws Exception {
         setupFingerprint(0 /* id */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
-        testMultiAuth_fingerprintSensorStartsAfterUINotifies();
+        testMultiAuth_fingerprintSensorStartsAfterUINotifies(true /* startFingerprintNow */);
+    }
+
+    @Test
+    public void testMultiAuth_singleSensor_fingerprintSensorDoesNotStartAfterDialogAnimationCompletes()
+            throws Exception {
+        setupFingerprint(0 /* id */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
+        testMultiAuth_fingerprintSensorStartsAfterUINotifies(false /* startFingerprintNow */);
     }
 
     @Test
@@ -240,10 +246,18 @@
             throws Exception {
         setupFingerprint(0 /* id */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
         setupFace(1 /* id */, false, mock(IBiometricAuthenticator.class));
-        testMultiAuth_fingerprintSensorStartsAfterUINotifies();
+        testMultiAuth_fingerprintSensorStartsAfterUINotifies(true /* startFingerprintNow */);
     }
 
-    public void testMultiAuth_fingerprintSensorStartsAfterUINotifies()
+    @Test
+    public void testMultiAuth_fingerprintSensorDoesNotStartAfterDialogAnimationCompletes()
+            throws Exception {
+        setupFingerprint(0 /* id */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
+        setupFace(1 /* id */, false, mock(IBiometricAuthenticator.class));
+        testMultiAuth_fingerprintSensorStartsAfterUINotifies(false /* startFingerprintNow */);
+    }
+
+    public void testMultiAuth_fingerprintSensorStartsAfterUINotifies(boolean startFingerprintNow)
             throws Exception {
         final long operationId = 123;
         final int userId = 10;
@@ -283,13 +297,21 @@
         // fingerprint sensor does not start even if all cookies are received
         assertEquals(STATE_AUTH_STARTED, session.getState());
         verify(mStatusBarService).showAuthenticationDialog(any(), any(), any(),
-                anyBoolean(), anyBoolean(), anyInt(), anyLong(), any(), anyLong(), anyInt());
+                anyBoolean(), anyBoolean(), anyInt(), anyLong(), any(), anyLong());
 
         // Notify AuthSession that the UI is shown. Then, fingerprint sensor should be started.
-        session.onDialogAnimatedIn();
+        session.onDialogAnimatedIn(startFingerprintNow);
         assertEquals(STATE_AUTH_STARTED_UI_SHOWING, session.getState());
-        assertEquals(BiometricSensor.STATE_AUTHENTICATING,
+        assertEquals(startFingerprintNow ? BiometricSensor.STATE_AUTHENTICATING
+                        : BiometricSensor.STATE_COOKIE_RETURNED,
                 session.mPreAuthInfo.eligibleSensors.get(fingerprintSensorId).getSensorState());
+
+        // start fingerprint sensor if it was delayed
+        if (!startFingerprintNow) {
+            session.onStartFingerprint();
+            assertEquals(BiometricSensor.STATE_AUTHENTICATING,
+                    session.mPreAuthInfo.eligibleSensors.get(fingerprintSensorId).getSensorState());
+        }
     }
 
     @Test
@@ -317,14 +339,14 @@
         verify(impl, never()).startPreparedClient(anyInt());
 
         // First invocation should start the client monitor.
-        session.onDialogAnimatedIn();
+        session.onDialogAnimatedIn(true /* startFingerprintNow */);
         assertEquals(STATE_AUTH_STARTED_UI_SHOWING, session.getState());
         verify(impl).startPreparedClient(anyInt());
 
         // Subsequent invocations should not start the client monitor again.
-        session.onDialogAnimatedIn();
-        session.onDialogAnimatedIn();
-        session.onDialogAnimatedIn();
+        session.onDialogAnimatedIn(true /* startFingerprintNow */);
+        session.onDialogAnimatedIn(false /* startFingerprintNow */);
+        session.onDialogAnimatedIn(true /* startFingerprintNow */);
         assertEquals(STATE_AUTH_STARTED_UI_SHOWING, session.getState());
         verify(impl, times(1)).startPreparedClient(anyInt());
     }
@@ -490,16 +512,9 @@
         IBiometricAuthenticator fingerprintAuthenticator = mock(IBiometricAuthenticator.class);
         when(fingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
         when(fingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
-
-        final FingerprintSensorPropertiesInternal props = new FingerprintSensorPropertiesInternal(
-                id, SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
-                List.of() /* componentInfo */, type,
-                false /* resetLockoutRequiresHardwareAuthToken */);
-        mFingerprintSensorProps.add(props);
-
-        mSensors.add(new BiometricSensor(mContext,
+        mSensors.add(new BiometricSensor(mContext, id,
                 TYPE_FINGERPRINT /* modality */,
-                props,
+                Authenticators.BIOMETRIC_STRONG /* strength */,
                 fingerprintAuthenticator) {
             @Override
             boolean confirmationAlwaysRequired(int userId) {
@@ -512,6 +527,21 @@
             }
         });
 
+        final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
+        componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
+                "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
+                "00000001" /* serialNumber */, "" /* softwareVersion */));
+        componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */,
+                "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
+                "vendor/version/revision" /* softwareVersion */));
+
+        mFingerprintSensorProps.add(new FingerprintSensorPropertiesInternal(id,
+                SensorProperties.STRENGTH_STRONG,
+                5 /* maxEnrollmentsPerUser */,
+                componentInfo,
+                type,
+                false /* resetLockoutRequiresHardwareAuthToken */));
+
         when(mSettingObserver.getEnabledForApps(anyInt())).thenReturn(true);
     }
 
@@ -519,13 +549,9 @@
             IBiometricAuthenticator authenticator) throws RemoteException {
         when(authenticator.isHardwareDetected(any())).thenReturn(true);
         when(authenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
-        mSensors.add(new BiometricSensor(mContext,
+        mSensors.add(new BiometricSensor(mContext, id,
                 TYPE_FACE /* modality */,
-                new FaceSensorPropertiesInternal(id,
-                        SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
-                        List.of() /* componentInfo */, FaceSensorProperties.TYPE_UNKNOWN,
-                        true /* supportsFace Detection */, true /* supportsSelfIllumination */,
-                        false /* resetLockoutRequiresHardwareAuthToken */),
+                Authenticators.BIOMETRIC_STRONG /* strength */,
                 authenticator) {
             @Override
             boolean confirmationAlwaysRequired(int userId) {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index 46fa3ab..67be376 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -18,7 +18,6 @@
 
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
 import static android.hardware.biometrics.BiometricManager.Authenticators;
-import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_DEFAULT;
 import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
 import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
 
@@ -70,11 +69,7 @@
 import android.hardware.biometrics.IBiometricSysuiReceiver;
 import android.hardware.biometrics.PromptInfo;
 import android.hardware.display.DisplayManagerGlobal;
-import android.hardware.face.FaceSensorProperties;
-import android.hardware.face.FaceSensorPropertiesInternal;
 import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.FingerprintSensorProperties;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -124,7 +119,6 @@
 
     private static final int SENSOR_ID_FINGERPRINT = 0;
     private static final int SENSOR_ID_FACE = 1;
-    private FingerprintSensorPropertiesInternal mFingerprintProps;
 
     private BiometricService mBiometricService;
 
@@ -207,11 +201,6 @@
         };
 
         when(mInjector.getConfiguration(any())).thenReturn(config);
-
-        mFingerprintProps = new FingerprintSensorPropertiesInternal(SENSOR_ID_FINGERPRINT,
-                STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */, List.of() /* componentInfo */,
-                FingerprintSensorProperties.TYPE_UNKNOWN,
-                false /* resetLockoutRequiresHardwareAuthToken */);
     }
 
     @Test
@@ -322,8 +311,7 @@
                 anyInt() /* userId */,
                 anyLong() /* operationId */,
                 eq(TEST_PACKAGE_NAME),
-                eq(TEST_REQUEST_ID),
-                eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
+                eq(TEST_REQUEST_ID));
     }
 
     @Test
@@ -347,7 +335,8 @@
 
         mBiometricService = new BiometricService(mContext, mInjector);
         mBiometricService.onStart();
-        mBiometricService.mImpl.registerAuthenticator(TYPE_FINGERPRINT, mFingerprintProps,
+        mBiometricService.mImpl.registerAuthenticator(0 /* id */,
+                TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
                 mFingerprintAuthenticator);
 
         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
@@ -407,8 +396,7 @@
                 anyInt() /* userId */,
                 anyLong() /* operationId */,
                 eq(TEST_PACKAGE_NAME),
-                eq(TEST_REQUEST_ID),
-                eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
+                eq(TEST_REQUEST_ID));
     }
 
     @Test
@@ -419,7 +407,8 @@
 
         mBiometricService = new BiometricService(mContext, mInjector);
         mBiometricService.onStart();
-        mBiometricService.mImpl.registerAuthenticator(TYPE_FINGERPRINT, mFingerprintProps,
+        mBiometricService.mImpl.registerAuthenticator(0 /* id */,
+                TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
                 mFingerprintAuthenticator);
 
         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
@@ -525,7 +514,7 @@
         assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
 
         // startPreparedClient invoked
-        mBiometricService.mAuthSession.onDialogAnimatedIn();
+        mBiometricService.mAuthSession.onDialogAnimatedIn(true /* startFingerprintNow */);
         verify(mBiometricService.mSensors.get(0).impl)
                 .startPreparedClient(cookieCaptor.getValue());
 
@@ -539,8 +528,7 @@
                 anyInt() /* userId */,
                 anyLong() /* operationId */,
                 eq(TEST_PACKAGE_NAME),
-                eq(TEST_REQUEST_ID),
-                eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
+                eq(TEST_REQUEST_ID));
 
         // Hardware authenticated
         final byte[] HAT = generateRandomHAT();
@@ -596,8 +584,7 @@
                 anyInt() /* userId */,
                 anyLong() /* operationId */,
                 eq(TEST_PACKAGE_NAME),
-                eq(TEST_REQUEST_ID),
-                eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
+                eq(TEST_REQUEST_ID));
     }
 
     @Test
@@ -761,8 +748,7 @@
                 anyInt() /* userId */,
                 anyLong() /* operationId */,
                 anyString(),
-                anyLong() /* requestId */,
-                eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
+                anyLong() /* requestId */);
     }
 
     @Test
@@ -863,8 +849,7 @@
                 anyInt() /* userId */,
                 anyLong() /* operationId */,
                 eq(TEST_PACKAGE_NAME),
-                eq(TEST_REQUEST_ID),
-                eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
+                eq(TEST_REQUEST_ID));
     }
 
     @Test
@@ -944,8 +929,7 @@
                 anyInt() /* userId */,
                 anyLong() /* operationId */,
                 eq(TEST_PACKAGE_NAME),
-                eq(TEST_REQUEST_ID),
-                eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
+                eq(TEST_REQUEST_ID));
     }
 
     @Test
@@ -1351,13 +1335,9 @@
 
         for (int i = 0; i < testCases.length; i++) {
             final BiometricSensor sensor =
-                    new BiometricSensor(mContext,
+                    new BiometricSensor(mContext, 0 /* id */,
                             TYPE_FINGERPRINT,
-                            new FingerprintSensorPropertiesInternal(i /* id */,
-                                    Utils.authenticatorStrengthToPropertyStrength(testCases[i][0]),
-                                    5 /* maxEnrollmentsPerUser */, List.of() /* componentInfo */,
-                                    FingerprintSensorProperties.TYPE_UNKNOWN,
-                                    false /* resetLockoutRequiresHardwareAuthToken */),
+                            testCases[i][0],
                             mock(IBiometricAuthenticator.class)) {
                         @Override
                         boolean confirmationAlwaysRequired(int userId) {
@@ -1385,7 +1365,8 @@
         when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any()))
                 .thenReturn(true);
         when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
-        mBiometricService.mImpl.registerAuthenticator(TYPE_FINGERPRINT, mFingerprintProps,
+        mBiometricService.mImpl.registerAuthenticator(0 /* testId */,
+                TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
                 mFingerprintAuthenticator);
 
         verify(mBiometricService.mBiometricStrengthController).updateStrengths();
@@ -1396,14 +1377,15 @@
         mBiometricService = new BiometricService(mContext, mInjector);
         mBiometricService.onStart();
 
+        final int testId = 0;
+
         when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt())).thenReturn(true);
 
         when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any()))
                 .thenReturn(true);
         when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
-
-        final int testId = SENSOR_ID_FINGERPRINT;
-        mBiometricService.mImpl.registerAuthenticator(TYPE_FINGERPRINT, mFingerprintProps,
+        mBiometricService.mImpl.registerAuthenticator(testId /* id */,
+                TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
                 mFingerprintAuthenticator);
 
         // Downgrade the authenticator
@@ -1443,8 +1425,7 @@
                 anyInt() /* userId */,
                 anyLong() /* operationId */,
                 eq(TEST_PACKAGE_NAME),
-                eq(requestId),
-                eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
+                eq(requestId));
 
         // Requesting strong and credential, when credential is setup
         resetReceivers();
@@ -1467,8 +1448,7 @@
                 anyInt() /* userId */,
                 anyLong() /* operationId */,
                 eq(TEST_PACKAGE_NAME),
-                eq(requestId),
-                eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
+                eq(requestId));
 
         // Un-downgrading the authenticator allows successful strong auth
         for (BiometricSensor sensor : mBiometricService.mSensors) {
@@ -1493,8 +1473,7 @@
                 anyInt() /* userId */,
                 anyLong() /* operationId */,
                 eq(TEST_PACKAGE_NAME),
-                eq(requestId),
-                eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
+                eq(requestId));
     }
 
     @Test(expected = IllegalStateException.class)
@@ -1503,9 +1482,11 @@
         mBiometricService.onStart();
 
         mBiometricService.mImpl.registerAuthenticator(
-                2 /* modality */, mFingerprintProps, mFingerprintAuthenticator);
+                0 /* id */, 2 /* modality */, 15 /* strength */,
+                mFingerprintAuthenticator);
         mBiometricService.mImpl.registerAuthenticator(
-                2 /* modality */, mFingerprintProps, mFingerprintAuthenticator);
+                0 /* id */, 2 /* modality */, 15 /* strength */,
+                mFingerprintAuthenticator);
     }
 
     @Test(expected = IllegalArgumentException.class)
@@ -1515,7 +1496,9 @@
         mBiometricService.onStart();
 
         mBiometricService.mImpl.registerAuthenticator(
-                2 /* modality */, mFingerprintProps, null /* authenticator */);
+                0 /* id */, 2 /* modality */,
+                Authenticators.BIOMETRIC_STRONG /* strength */,
+                null /* authenticator */);
     }
 
     @Test
@@ -1526,13 +1509,8 @@
 
         for (String s : mInjector.getConfiguration(null)) {
             SensorConfig config = new SensorConfig(s);
-            mBiometricService.mImpl.registerAuthenticator(config.modality,
-                    new FingerprintSensorPropertiesInternal(config.id,
-                            Utils.authenticatorStrengthToPropertyStrength(config.strength),
-                            5 /* maxEnrollmentsPerUser */, List.of() /* componentInfo */,
-                            FingerprintSensorProperties.TYPE_UNKNOWN,
-                            false /* resetLockoutRequiresHardwareAuthToken */),
-                    mFingerprintAuthenticator);
+            mBiometricService.mImpl.registerAuthenticator(config.id, config.modality,
+                config.strength, mFingerprintAuthenticator);
         }
     }
 
@@ -1656,12 +1634,7 @@
             when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
             when(mFingerprintAuthenticator.getLockoutModeForUser(anyInt()))
                     .thenReturn(LockoutTracker.LOCKOUT_NONE);
-            mBiometricService.mImpl.registerAuthenticator(modality,
-                    new FingerprintSensorPropertiesInternal(SENSOR_ID_FINGERPRINT,
-                            Utils.authenticatorStrengthToPropertyStrength(strength),
-                            5 /* maxEnrollmentsPerUser */, List.of() /* componentInfo */,
-                            FingerprintSensorProperties.TYPE_UNKNOWN,
-                            false /* resetLockoutRequiresHardwareAuthToken */),
+            mBiometricService.mImpl.registerAuthenticator(SENSOR_ID_FINGERPRINT, modality, strength,
                     mFingerprintAuthenticator);
         }
 
@@ -1670,13 +1643,7 @@
             when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true);
             when(mFaceAuthenticator.getLockoutModeForUser(anyInt()))
                     .thenReturn(LockoutTracker.LOCKOUT_NONE);
-            mBiometricService.mImpl.registerAuthenticator(modality,
-                    new FaceSensorPropertiesInternal(SENSOR_ID_FACE,
-                            Utils.authenticatorStrengthToPropertyStrength(strength),
-                            5 /* maxEnrollmentsPerUser */, List.of() /* componentInfo */,
-                            FaceSensorProperties.TYPE_UNKNOWN, true /* supportsFace Detection */,
-                            true /* supportsSelfIllumination */,
-                            false /* resetLockoutRequiresHardwareAuthToken */),
+            mBiometricService.mImpl.registerAuthenticator(SENSOR_ID_FACE, modality, strength,
                     mFaceAuthenticator);
         }
     }
@@ -1699,27 +1666,15 @@
                 when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any()))
                         .thenReturn(true);
                 when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
-                mBiometricService.mImpl.registerAuthenticator(modality,
-                        new FingerprintSensorPropertiesInternal(SENSOR_ID_FINGERPRINT,
-                                Utils.authenticatorStrengthToPropertyStrength(strength),
-                                5 /* maxEnrollmentsPerUser */, List.of() /* componentInfo */,
-                                FingerprintSensorProperties.TYPE_UNKNOWN,
-                                false /* resetLockoutRequiresHardwareAuthToken */),
-                        mFingerprintAuthenticator);
+                mBiometricService.mImpl.registerAuthenticator(SENSOR_ID_FINGERPRINT, modality,
+                        strength, mFingerprintAuthenticator);
             }
 
             if ((modality & BiometricAuthenticator.TYPE_FACE) != 0) {
                 when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
                 when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true);
-                mBiometricService.mImpl.registerAuthenticator(modality,
-                        new FaceSensorPropertiesInternal(SENSOR_ID_FACE,
-                                Utils.authenticatorStrengthToPropertyStrength(strength),
-                                5 /* maxEnrollmentsPerUser */, List.of() /* componentInfo */,
-                                FaceSensorProperties.TYPE_UNKNOWN,
-                                true /* supportsFace Detection */,
-                                true /* supportsSelfIllumination */,
-                                false /* resetLockoutRequiresHardwareAuthToken */),
-                        mFaceAuthenticator);
+                mBiometricService.mImpl.registerAuthenticator(SENSOR_ID_FACE, modality,
+                        strength, mFaceAuthenticator);
             }
         }
     }
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java
index f7539bd..ee5ab92 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java
@@ -16,9 +16,6 @@
 
 package com.android.server.biometrics;
 
-import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
-import static android.hardware.biometrics.SensorProperties.STRENGTH_WEAK;
-
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
@@ -30,13 +27,9 @@
 import android.annotation.NonNull;
 import android.content.Context;
 import android.hardware.biometrics.BiometricAuthenticator;
+import android.hardware.biometrics.BiometricManager.Authenticators;
 import android.hardware.biometrics.IBiometricAuthenticator;
 import android.hardware.biometrics.IInvalidationCallback;
-import android.hardware.biometrics.SensorPropertiesInternal;
-import android.hardware.face.FaceSensorProperties;
-import android.hardware.face.FaceSensorPropertiesInternal;
-import android.hardware.fingerprint.FingerprintSensorProperties;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
@@ -49,7 +42,6 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
-import java.util.List;
 
 @Presubmit
 @SmallTest
@@ -67,54 +59,26 @@
     public void testCallbackReceived_whenAllStrongSensorsInvalidated() throws Exception {
         final IBiometricAuthenticator authenticator1 = mock(IBiometricAuthenticator.class);
         when(authenticator1.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
-        final TestSensor sensor1 = new TestSensor(mContext,
-                BiometricAuthenticator.TYPE_FINGERPRINT,
-                new FingerprintSensorPropertiesInternal(0 /* id */,
-                        STRENGTH_STRONG,
-                        5 /* maxEnrollmentsPerUser */,
-                        List.of() /* componentInfo */,
-                        FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
-                        false /* resetLockoutRequiresHardwareAuthToken */),
+        final TestSensor sensor1 = new TestSensor(mContext, 0 /* id */,
+                BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
                 authenticator1);
 
         final IBiometricAuthenticator authenticator2 = mock(IBiometricAuthenticator.class);
         when(authenticator2.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
-        final TestSensor sensor2 = new TestSensor(mContext,
-                BiometricAuthenticator.TYPE_FINGERPRINT,
-                new FingerprintSensorPropertiesInternal(1 /* id */,
-                        STRENGTH_STRONG,
-                        5 /* maxEnrollmentsPerUser */,
-                        List.of() /* componentInfo */,
-                        FingerprintSensorProperties.TYPE_REAR,
-                        false /* resetLockoutRequiresHardwareAuthToken */),
+        final TestSensor sensor2 = new TestSensor(mContext, 1 /* id */,
+                BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
                 authenticator2);
 
         final IBiometricAuthenticator authenticator3 = mock(IBiometricAuthenticator.class);
         when(authenticator3.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
-        final TestSensor sensor3 = new TestSensor(mContext,
-                BiometricAuthenticator.TYPE_FACE,
-                new FaceSensorPropertiesInternal(2 /* id */,
-                        STRENGTH_STRONG,
-                        5 /* maxEnrollmentsPerUser */,
-                        List.of() /* componentInfo */,
-                        FaceSensorProperties.TYPE_RGB,
-                        true /* supportsFace Detection */,
-                        true /* supportsSelfIllumination */,
-                        false /* resetLockoutRequiresHardwareAuthToken */),
+        final TestSensor sensor3 = new TestSensor(mContext, 2 /* id */,
+                BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG,
                 authenticator3);
 
         final IBiometricAuthenticator authenticator4 = mock(IBiometricAuthenticator.class);
         when(authenticator4.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
-        final TestSensor sensor4 = new TestSensor(mContext,
-                BiometricAuthenticator.TYPE_FACE,
-                new FaceSensorPropertiesInternal(3 /* id */,
-                        STRENGTH_WEAK,
-                        5 /* maxEnrollmentsPerUser */,
-                        List.of() /* componentInfo */,
-                        FaceSensorProperties.TYPE_IR,
-                        true /* supportsFace Detection */,
-                        true /* supportsSelfIllumination */,
-                        false /* resetLockoutRequiresHardwareAuthToken */),
+        final TestSensor sensor4 = new TestSensor(mContext, 3 /* id */,
+                BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_WEAK,
                 authenticator4);
 
         final ArrayList<BiometricSensor> sensors = new ArrayList<>();
@@ -149,9 +113,9 @@
 
     private static class TestSensor extends BiometricSensor {
 
-        TestSensor(@NonNull Context context, int modality, @NonNull SensorPropertiesInternal props,
+        TestSensor(@NonNull Context context, int id, int modality, int strength,
                 @NonNull IBiometricAuthenticator impl) {
-            super(context, modality, props, impl);
+            super(context, id, modality, strength, impl);
         }
 
         @Override
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceRegistryTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceRegistryTest.java
index d3f04df..903ed90 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceRegistryTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceRegistryTest.java
@@ -17,6 +17,8 @@
 package com.android.server.biometrics.sensors.face;
 
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
+import static android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_STRONG;
+import static android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_WEAK;
 import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
 import static android.hardware.biometrics.SensorProperties.STRENGTH_WEAK;
 
@@ -68,7 +70,9 @@
     @Mock
     private ServiceProvider mProvider2;
     @Captor
-    private ArgumentCaptor<FaceSensorPropertiesInternal> mPropsCaptor;
+    private ArgumentCaptor<Integer> mIdCaptor;
+    @Captor
+    private ArgumentCaptor<Integer> mStrengthCaptor;
 
     private FaceSensorPropertiesInternal mProvider1Props;
     private FaceSensorPropertiesInternal mProvider2Props;
@@ -78,13 +82,13 @@
     public void setup() {
         mProvider1Props = new FaceSensorPropertiesInternal(SENSOR_ID_1,
                 STRENGTH_WEAK, 5 /* maxEnrollmentsPerUser */,
-                List.of() /* componentInfo */, FaceSensorProperties.TYPE_RGB,
+                List.of(), FaceSensorProperties.TYPE_RGB,
                 true /* supportsFace Detection */,
                 true /* supportsSelfIllumination */,
                 false /* resetLockoutRequiresHardwareAuthToken */);
         mProvider2Props = new FaceSensorPropertiesInternal(SENSOR_ID_2,
                 STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
-                List.of() /* componentInfo */, FaceSensorProperties.TYPE_IR,
+                List.of(), FaceSensorProperties.TYPE_IR,
                 true /* supportsFace Detection */,
                 true /* supportsSelfIllumination */,
                 false /* resetLockoutRequiresHardwareAuthToken */);
@@ -103,9 +107,10 @@
         assertThat(mRegistry.getProviders()).containsExactly(mProvider1, mProvider2);
         assertThat(mRegistry.getAllProperties()).containsExactly(mProvider1Props, mProvider2Props);
         verify(mBiometricService, times(2)).registerAuthenticator(
-                eq(TYPE_FACE), mPropsCaptor.capture(), any());
-        assertThat(mPropsCaptor.getAllValues())
-                .containsExactly(mProvider1Props, mProvider2Props);
+                mIdCaptor.capture(), eq(TYPE_FACE), mStrengthCaptor.capture(), any());
+        assertThat(mIdCaptor.getAllValues()).containsExactly(SENSOR_ID_1, SENSOR_ID_2);
+        assertThat(mStrengthCaptor.getAllValues())
+                .containsExactly(BIOMETRIC_WEAK, BIOMETRIC_STRONG);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java
index c26eee9..ade3e82 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.same;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.hardware.biometrics.common.AuthenticateReason;
@@ -34,6 +35,7 @@
 import android.os.IBinder;
 import android.os.PowerManager;
 import android.os.RemoteException;
+import android.os.Vibrator;
 import android.platform.test.annotations.Presubmit;
 import android.testing.TestableContext;
 
@@ -75,6 +77,8 @@
     @Mock
     private IBinder mToken;
     @Mock
+    private Vibrator mVibrator;
+    @Mock
     private ClientMonitorCallbackConverter mClientMonitorCallbackConverter;
     @Mock
     private BiometricLogger mBiometricLogger;
@@ -94,6 +98,8 @@
 
     @Before
     public void setup() {
+        mContext.addMockSystemService(Vibrator.class, mVibrator);
+
         when(mBiometricContext.updateContext(any(), anyBoolean())).thenAnswer(
                 i -> i.getArgument(0));
     }
@@ -147,6 +153,16 @@
         verify(mBiometricContext).unsubscribe(same(mOperationContextCaptor.getValue()));
     }
 
+    @Test
+    public void doesNotPlayHapticOnInteractionDetected() throws Exception {
+        final FaceDetectClient client = createClient();
+        client.start(mCallback);
+        client.onInteractionDetected();
+        client.stopHalOperation();
+
+        verifyZeroInteractions(mVibrator);
+    }
+
     private FaceDetectClient createClient() throws RemoteException {
         return createClient(100 /* version */);
     }
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java
index 25bd9bc..be9f52e 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java
@@ -17,12 +17,14 @@
 package com.android.server.biometrics.sensors.face.aidl;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -41,6 +43,7 @@
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.sensors.AuthSessionCoordinator;
+import com.android.server.biometrics.sensors.BaseClientMonitor;
 import com.android.server.biometrics.sensors.BiometricScheduler;
 import com.android.server.biometrics.sensors.LockoutCache;
 import com.android.server.biometrics.sensors.LockoutResetDispatcher;
@@ -82,6 +85,10 @@
     private AuthSessionCoordinator mAuthSessionCoordinator;
     @Mock
     FaceProvider mFaceProvider;
+    @Mock
+    BaseClientMonitor mClientMonitor;
+    @Mock
+    AidlSession mCurrentSession;
 
     private final TestLooper mLooper = new TestLooper();
     private final LockoutCache mLockoutCache = new LockoutCache();
@@ -161,6 +168,39 @@
         assertNull(sensor.getSessionForUser(USER_ID));
     }
 
+    @Test
+    public void onBinderDied_cancelNonInterruptableClient() {
+        mLooper.dispatchAll();
+
+        when(mCurrentSession.getUserId()).thenReturn(USER_ID);
+        when(mClientMonitor.getTargetUserId()).thenReturn(USER_ID);
+        when(mClientMonitor.isInterruptable()).thenReturn(false);
+
+        final SensorProps sensorProps = new SensorProps();
+        sensorProps.commonProps = new CommonProps();
+        sensorProps.commonProps.sensorId = 1;
+        final FaceSensorPropertiesInternal internalProp = new FaceSensorPropertiesInternal(
+                sensorProps.commonProps.sensorId, sensorProps.commonProps.sensorStrength,
+                sensorProps.commonProps.maxEnrollmentsPerUser, null,
+                sensorProps.sensorType, sensorProps.supportsDetectInteraction,
+                sensorProps.halControlsPreview, false /* resetLockoutRequiresChallenge */);
+        final Sensor sensor = new Sensor("SensorTest", mFaceProvider, mContext, null,
+                internalProp, mLockoutResetDispatcher, mBiometricContext, mCurrentSession);
+        mScheduler = (UserAwareBiometricScheduler) sensor.getScheduler();
+        sensor.mCurrentSession = new AidlSession(0, mock(ISession.class),
+                USER_ID, mHalCallback);
+
+        mScheduler.scheduleClientMonitor(mClientMonitor);
+
+        assertNotNull(mScheduler.getCurrentClient());
+
+        sensor.onBinderDied();
+
+        verify(mClientMonitor).cancel();
+        assertNull(sensor.getSessionForUser(USER_ID));
+        assertNull(mScheduler.getCurrentClient());
+    }
+
     private void verifyNotLocked() {
         assertEquals(LockoutTracker.LOCKOUT_NONE, mLockoutCache.getLockoutModeForUser(USER_ID));
         verify(mLockoutResetDispatcher).notifyLockoutResetCallbacks(eq(SENSOR_ID));
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistryTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistryTest.java
index 6e09069..13c3f64 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistryTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistryTest.java
@@ -17,6 +17,8 @@
 package com.android.server.biometrics.sensors.fingerprint;
 
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
+import static android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_STRONG;
+import static android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_WEAK;
 import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
 import static android.hardware.biometrics.SensorProperties.STRENGTH_WEAK;
 
@@ -68,7 +70,9 @@
     @Mock
     private ServiceProvider mProvider2;
     @Captor
-    private ArgumentCaptor<FingerprintSensorPropertiesInternal> mPropsCaptor;
+    private ArgumentCaptor<Integer> mIdCaptor;
+    @Captor
+    private ArgumentCaptor<Integer> mStrengthCaptor;
 
     private FingerprintSensorPropertiesInternal mProvider1Props;
     private FingerprintSensorPropertiesInternal mProvider2Props;
@@ -78,11 +82,11 @@
     public void setup() {
         mProvider1Props = new FingerprintSensorPropertiesInternal(SENSOR_ID_1,
                 STRENGTH_WEAK, 5 /* maxEnrollmentsPerUser */,
-                List.of() /* componentInfo */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
+                List.of(), FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
                 false /* resetLockoutRequiresHardwareAuthToken */);
         mProvider2Props = new FingerprintSensorPropertiesInternal(SENSOR_ID_2,
                 STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */,
-                List.of() /* componentInfo */, FingerprintSensorProperties.TYPE_UNKNOWN,
+                List.of(), FingerprintSensorProperties.TYPE_UNKNOWN,
                 false /* resetLockoutRequiresHardwareAuthToken */);
 
         when(mProvider1.getSensorProperties()).thenReturn(List.of(mProvider1Props));
@@ -99,9 +103,10 @@
         assertThat(mRegistry.getProviders()).containsExactly(mProvider1, mProvider2);
         assertThat(mRegistry.getAllProperties()).containsExactly(mProvider1Props, mProvider2Props);
         verify(mBiometricService, times(2)).registerAuthenticator(
-                eq(TYPE_FINGERPRINT), mPropsCaptor.capture(), any());
-        assertThat(mPropsCaptor.getAllValues())
-                .containsExactly(mProvider1Props, mProvider2Props);
+                mIdCaptor.capture(), eq(TYPE_FINGERPRINT), mStrengthCaptor.capture(), any());
+        assertThat(mIdCaptor.getAllValues()).containsExactly(SENSOR_ID_1, SENSOR_ID_2);
+        assertThat(mStrengthCaptor.getAllValues())
+                .containsExactly(BIOMETRIC_WEAK, BIOMETRIC_STRONG);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
index 1089c07..2aa62d9 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
@@ -27,6 +27,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static junit.framework.Assert.assertEquals;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -44,6 +46,7 @@
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
 import android.hardware.fingerprint.IFingerprintServiceReceiver;
+import android.os.Binder;
 import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
@@ -54,8 +57,10 @@
 
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.internal.util.test.FakeSettingsProviderRule;
+import com.android.server.LocalServices;
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
+import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -103,6 +108,8 @@
     private IFingerprintServiceReceiver mServiceReceiver;
     @Mock
     private IBinder mToken;
+    @Mock
+    private VirtualDeviceManagerInternal mVdmInternal;
 
     @Captor
     private ArgumentCaptor<FingerprintAuthenticateOptions> mAuthenticateOptionsCaptor;
@@ -110,21 +117,22 @@
     private final FingerprintSensorPropertiesInternal mSensorPropsDefault =
             new FingerprintSensorPropertiesInternal(ID_DEFAULT, STRENGTH_STRONG,
                     2 /* maxEnrollmentsPerUser */,
-                    List.of() /* componentInfo */,
+                    List.of(),
                     TYPE_REAR,
                     false /* resetLockoutRequiresHardwareAuthToken */);
     private final FingerprintSensorPropertiesInternal mSensorPropsVirtual =
             new FingerprintSensorPropertiesInternal(ID_VIRTUAL, STRENGTH_STRONG,
                     2 /* maxEnrollmentsPerUser */,
-                    List.of() /* componentInfo */,
+                    List.of(),
                     TYPE_UDFPS_OPTICAL,
                     false /* resetLockoutRequiresHardwareAuthToken */);
-    @Captor
-    private ArgumentCaptor<FingerprintSensorPropertiesInternal> mPropsCaptor;
     private FingerprintService mService;
 
     @Before
     public void setup() throws Exception {
+        LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
+        LocalServices.addService(VirtualDeviceManagerInternal.class, mVdmInternal);
+
         when(mFingerprintDefault.getSensorProperties()).thenReturn(List.of(mSensorPropsDefault));
         when(mFingerprintVirtual.getSensorProperties()).thenReturn(List.of(mSensorPropsVirtual));
         when(mFingerprintDefault.containsSensor(anyInt()))
@@ -168,8 +176,7 @@
         mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
         waitForRegistration();
 
-        verify(mIBiometricService).registerAuthenticator(anyInt(), mPropsCaptor.capture(), any());
-        assertThat(mPropsCaptor.getAllValues()).containsExactly(mSensorPropsDefault);
+        verify(mIBiometricService).registerAuthenticator(eq(ID_DEFAULT), anyInt(), anyInt(), any());
     }
 
     @Test
@@ -181,8 +188,7 @@
         mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
         waitForRegistration();
 
-        verify(mIBiometricService).registerAuthenticator(anyInt(), mPropsCaptor.capture(), any());
-        assertThat(mPropsCaptor.getAllValues()).containsExactly(mSensorPropsVirtual);
+        verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
     }
 
     @Test
@@ -192,8 +198,7 @@
         mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
         waitForRegistration();
 
-        verify(mIBiometricService).registerAuthenticator(anyInt(), mPropsCaptor.capture(), any());
-        assertThat(mPropsCaptor.getAllValues()).containsExactly(mSensorPropsVirtual);
+        verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
     }
 
     private void waitForRegistration() throws Exception {
@@ -225,6 +230,36 @@
         verifyNoAuthenticate(mFingerprintVirtual);
     }
 
+    @Test
+    public void testAuthenticate_noVdmInternalService_noCrash() throws Exception {
+        initServiceWithAndWait(NAME_DEFAULT, NAME_VIRTUAL);
+        LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
+
+        final long operationId = 2;
+
+        // This should not crash
+        mService.mServiceWrapper.authenticate(mToken, operationId, mServiceReceiver,
+                new FingerprintAuthenticateOptions.Builder()
+                        .setSensorId(SENSOR_ID_ANY)
+                        .build());
+    }
+
+    @Test
+    public void testAuthenticate_callsVirtualDeviceManagerOnAuthenticationPrompt()
+            throws Exception {
+        initServiceWithAndWait(NAME_DEFAULT, NAME_VIRTUAL);
+
+        final long operationId = 2;
+        mService.mServiceWrapper.authenticate(mToken, operationId, mServiceReceiver,
+                new FingerprintAuthenticateOptions.Builder()
+                        .setSensorId(SENSOR_ID_ANY)
+                        .build());
+
+        ArgumentCaptor<Integer> uidCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mVdmInternal).onAuthenticationPrompt(uidCaptor.capture());
+        assertEquals((int) (uidCaptor.getValue()), Binder.getCallingUid());
+    }
+
 
     private FingerprintAuthenticateOptions verifyAuthenticateWithNewRequestId(
             FingerprintProvider provider, long operationId) {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java
index 0c13466..15d7601 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java
@@ -17,17 +17,23 @@
 package com.android.server.biometrics.sensors.fingerprint.aidl;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.hardware.biometrics.IBiometricService;
+import android.hardware.biometrics.common.CommonProps;
+import android.hardware.biometrics.face.SensorProps;
 import android.hardware.biometrics.fingerprint.ISession;
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.os.Handler;
 import android.os.test.TestLooper;
 import android.platform.test.annotations.Presubmit;
@@ -37,11 +43,13 @@
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.sensors.AuthSessionCoordinator;
+import com.android.server.biometrics.sensors.BaseClientMonitor;
 import com.android.server.biometrics.sensors.BiometricScheduler;
 import com.android.server.biometrics.sensors.LockoutCache;
 import com.android.server.biometrics.sensors.LockoutResetDispatcher;
 import com.android.server.biometrics.sensors.LockoutTracker;
 import com.android.server.biometrics.sensors.UserAwareBiometricScheduler;
+import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -76,6 +84,14 @@
     private BiometricContext mBiometricContext;
     @Mock
     private AuthSessionCoordinator mAuthSessionCoordinator;
+    @Mock
+    FingerprintProvider mFingerprintProvider;
+    @Mock
+    GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
+    @Mock
+    private AidlSession mCurrentSession;
+    @Mock
+    private BaseClientMonitor mClientMonitor;
 
     private final TestLooper mLooper = new TestLooper();
     private final LockoutCache mLockoutCache = new LockoutCache();
@@ -130,6 +146,40 @@
         verifyNotLocked();
     }
 
+    @Test
+    public void onBinderDied_cancelNonInterruptableClient() {
+        mLooper.dispatchAll();
+
+        when(mCurrentSession.getUserId()).thenReturn(USER_ID);
+        when(mClientMonitor.getTargetUserId()).thenReturn(USER_ID);
+        when(mClientMonitor.isInterruptable()).thenReturn(false);
+
+        final SensorProps sensorProps = new SensorProps();
+        sensorProps.commonProps = new CommonProps();
+        sensorProps.commonProps.sensorId = 1;
+        final FingerprintSensorPropertiesInternal internalProp = new
+                FingerprintSensorPropertiesInternal(
+                        sensorProps.commonProps.sensorId, sensorProps.commonProps.sensorStrength,
+                        sensorProps.commonProps.maxEnrollmentsPerUser, null,
+                        sensorProps.sensorType, false /* resetLockoutRequiresHardwareAuthToken */);
+        final Sensor sensor = new Sensor("SensorTest", mFingerprintProvider, mContext,
+                null /* handler */, internalProp, mLockoutResetDispatcher,
+                mGestureAvailabilityDispatcher, mBiometricContext, mCurrentSession);
+        mScheduler = (UserAwareBiometricScheduler) sensor.getScheduler();
+        sensor.mCurrentSession = new AidlSession(0, mock(ISession.class),
+                USER_ID, mHalCallback);
+
+        mScheduler.scheduleClientMonitor(mClientMonitor);
+
+        assertNotNull(mScheduler.getCurrentClient());
+
+        sensor.onBinderDied();
+
+        verify(mClientMonitor).cancel();
+        assertNull(sensor.getSessionForUser(USER_ID));
+        assertNull(mScheduler.getCurrentClient());
+    }
+
     private void verifyNotLocked() {
         assertEquals(LockoutTracker.LOCKOUT_NONE, mLockoutCache.getLockoutModeForUser(USER_ID));
         verify(mLockoutResetDispatcher).notifyLockoutResetCallbacks(eq(SENSOR_ID));
diff --git a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionServiceTest.java
index ccddb2fd..1475537 100644
--- a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionServiceTest.java
@@ -75,7 +75,7 @@
         callMetadataSyncData.addCall(call);
         mSyncConnectionService.mCrossDeviceSyncControllerCallback.processContextSyncMessage(
                 /* associationId= */ 0, callMetadataSyncData);
-        verify(mMockTelecomManager, times(1)).addNewIncomingCall(any(), any());
+        verify(mMockTelecomManager, times(0)).addNewIncomingCall(any(), any());
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java
index 5a0646c..6a939ab 100644
--- a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java
@@ -23,6 +23,7 @@
 import android.telecom.Call;
 import android.telecom.ParcelableCall;
 import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
 import android.testing.AndroidTestingRunner;
 
 import androidx.test.InstrumentationRegistry;
@@ -45,7 +46,7 @@
     @Test
     public void updateCallDetails_uninitialized() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                InstrumentationRegistry.getTargetContext(),
                 mUninitializedCallDetails, /* callAudioState= */ null);
         assertWithMessage("Wrong status").that(crossDeviceCall.getStatus())
                 .isEqualTo(android.companion.Telecom.Call.UNKNOWN_STATUS);
@@ -55,7 +56,7 @@
     @Test
     public void updateCallDetails_ringing() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                InstrumentationRegistry.getTargetContext(),
                 mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(createCallDetails(Call.STATE_RINGING,
                 Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE));
@@ -70,7 +71,7 @@
     @Test
     public void updateCallDetails_ongoing() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                InstrumentationRegistry.getTargetContext(),
                 mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(createCallDetails(Call.STATE_ACTIVE,
                 Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE));
@@ -85,7 +86,7 @@
     @Test
     public void updateCallDetails_holding() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                InstrumentationRegistry.getTargetContext(),
                 mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(createCallDetails(Call.STATE_HOLDING,
                 Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE));
@@ -99,7 +100,7 @@
     @Test
     public void updateCallDetails_cannotHold() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                InstrumentationRegistry.getTargetContext(),
                 mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(
                 createCallDetails(Call.STATE_ACTIVE, Call.Details.CAPABILITY_MUTE));
@@ -113,7 +114,7 @@
     @Test
     public void updateCallDetails_cannotMute() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                InstrumentationRegistry.getTargetContext(),
                 mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(
                 createCallDetails(Call.STATE_ACTIVE, Call.Details.CAPABILITY_HOLD));
@@ -127,7 +128,7 @@
     @Test
     public void updateCallDetails_transitionRingingToOngoing() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                InstrumentationRegistry.getTargetContext(),
                 mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(createCallDetails(Call.STATE_RINGING,
                 Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE));
@@ -150,7 +151,7 @@
     @Test
     public void updateSilencedIfRinging_ringing_silenced() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                InstrumentationRegistry.getTargetContext(),
                 mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(createCallDetails(Call.STATE_RINGING,
                 Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE));
@@ -165,7 +166,7 @@
     @Test
     public void updateSilencedIfRinging_notRinging_notSilenced() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                InstrumentationRegistry.getTargetContext(),
                 mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.updateCallDetails(createCallDetails(Call.STATE_ACTIVE,
                 Call.Details.CAPABILITY_HOLD | Call.Details.CAPABILITY_MUTE));
@@ -179,12 +180,11 @@
     }
 
     @Test
-    public void getReadableCallerId_enterpriseCall_adminBlocked_ott() {
+    public void getReadableCallerId_enterpriseCall_adminBlocked_hasContact() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                InstrumentationRegistry.getTargetContext(),
                 mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.mIsEnterprise = true;
-        crossDeviceCall.mIsOtt = true;
         crossDeviceCall.updateCallDetails(
                 createCallDetails(Call.STATE_ACTIVE, /* capabilities= */ 0));
 
@@ -195,76 +195,74 @@
     }
 
     @Test
-    public void getReadableCallerId_enterpriseCall_adminUnblocked_ott() {
+    public void getReadableCallerId_enterpriseCall_adminUnblocked_hasContact() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                InstrumentationRegistry.getTargetContext(),
                 mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.mIsEnterprise = true;
-        crossDeviceCall.mIsOtt = true;
         crossDeviceCall.updateCallDetails(
                 createCallDetails(Call.STATE_ACTIVE, /* capabilities= */ 0));
 
         final String result = crossDeviceCall.getReadableCallerId(false);
 
         assertWithMessage("Wrong caller id").that(result)
+                .isEqualTo(CONTACT_DISPLAY_NAME);
+    }
+
+    @Test
+    public void getReadableCallerId_enterpriseCall_adminBlocked_noContact() {
+        final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
+                InstrumentationRegistry.getTargetContext(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
+        crossDeviceCall.mIsEnterprise = true;
+        crossDeviceCall.updateCallDetails(
+                createCallDetails(Call.STATE_ACTIVE, /* capabilities= */ 0, /* hasContactName= */
+                        false));
+
+        final String result = crossDeviceCall.getReadableCallerId(true);
+
+        assertWithMessage("Wrong caller id").that(result)
+                .isEqualTo(CALLER_DISPLAY_NAME);
+    }
+
+    @Test
+    public void getReadableCallerId_nonEnterpriseCall_adminBlocked_noContact() {
+        final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
+                InstrumentationRegistry.getTargetContext(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
+        crossDeviceCall.mIsEnterprise = false;
+        crossDeviceCall.updateCallDetails(
+                createCallDetails(Call.STATE_ACTIVE, /* capabilities= */ 0, /* hasContactName= */
+                        false));
+
+        final String result = crossDeviceCall.getReadableCallerId(true);
+
+        assertWithMessage("Wrong caller id").that(result)
+                .isEqualTo(CALLER_DISPLAY_NAME);
+    }
+
+    @Test
+    public void getReadableCallerId_nonEnterpriseCall_adminUnblocked_noContact() {
+        final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
+                InstrumentationRegistry.getTargetContext(),
+                mUninitializedCallDetails, /* callAudioState= */ null);
+        crossDeviceCall.mIsEnterprise = false;
+        crossDeviceCall.updateCallDetails(
+                createCallDetails(Call.STATE_ACTIVE, /* capabilities= */ 0, /* hasContactName= */
+                        false));
+
+        final String result = crossDeviceCall.getReadableCallerId(false);
+
+        assertWithMessage("Wrong caller id").that(result)
                 .isEqualTo(CALLER_DISPLAY_NAME);
     }
 
     @Test
-    public void getReadableCallerId_enterpriseCall_adminBlocked_pstn() {
+    public void getReadableCallerId_nonEnterpriseCall_adminBlocked_hasContact() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
-                mUninitializedCallDetails, /* callAudioState= */ null);
-        crossDeviceCall.mIsEnterprise = true;
-        crossDeviceCall.mIsOtt = false;
-        crossDeviceCall.updateCallDetails(
-                createCallDetails(Call.STATE_ACTIVE, /* capabilities= */ 0));
-
-        final String result = crossDeviceCall.getReadableCallerId(true);
-
-        assertWithMessage("Wrong caller id").that(result)
-                .isEqualTo(CALLER_DISPLAY_NAME);
-    }
-
-    @Test
-    public void getReadableCallerId_nonEnterpriseCall_adminBlocked_ott() {
-        final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                InstrumentationRegistry.getTargetContext(),
                 mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.mIsEnterprise = false;
-        crossDeviceCall.mIsOtt = true;
-        crossDeviceCall.updateCallDetails(
-                createCallDetails(Call.STATE_ACTIVE, /* capabilities= */ 0));
-
-        final String result = crossDeviceCall.getReadableCallerId(true);
-
-        assertWithMessage("Wrong caller id").that(result)
-                .isEqualTo(CALLER_DISPLAY_NAME);
-    }
-
-    @Test
-    public void getReadableCallerId_nonEnterpriseCall_adminUnblocked_ott() {
-        final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
-                mUninitializedCallDetails, /* callAudioState= */ null);
-        crossDeviceCall.mIsEnterprise = false;
-        crossDeviceCall.mIsOtt = true;
-        crossDeviceCall.updateCallDetails(
-                createCallDetails(Call.STATE_ACTIVE, /* capabilities= */ 0));
-
-        final String result = crossDeviceCall.getReadableCallerId(false);
-
-        assertWithMessage("Wrong caller id").that(result)
-                .isEqualTo(CALLER_DISPLAY_NAME);
-    }
-
-    @Test
-    public void getReadableCallerId_nonEnterpriseCall_adminBlocked_pstn() {
-        final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
-                mUninitializedCallDetails, /* callAudioState= */ null);
-        crossDeviceCall.mIsEnterprise = false;
-        crossDeviceCall.mIsOtt = false;
         crossDeviceCall.updateCallDetails(
                 createCallDetails(Call.STATE_ACTIVE, /* capabilities= */ 0));
 
@@ -275,12 +273,11 @@
     }
 
     @Test
-    public void getReadableCallerId_nonEnterpriseCall_adminUnblocked_pstn() {
+    public void getReadableCallerId_nonEnterpriseCall_adminUnblocked_hasContact() {
         final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
-                InstrumentationRegistry.getTargetContext().getPackageManager(),
+                InstrumentationRegistry.getTargetContext(),
                 mUninitializedCallDetails, /* callAudioState= */ null);
         crossDeviceCall.mIsEnterprise = false;
-        crossDeviceCall.mIsOtt = false;
         crossDeviceCall.updateCallDetails(
                 createCallDetails(Call.STATE_ACTIVE, /* capabilities= */ 0));
 
@@ -291,10 +288,17 @@
     }
 
     private Call.Details createCallDetails(int state, int capabilities) {
+        return createCallDetails(state, capabilities, /* hasContactName= */ true);
+    }
+
+    private Call.Details createCallDetails(int state, int capabilities, boolean hasContactName) {
         final ParcelableCall.ParcelableCallBuilder parcelableCallBuilder =
                 new ParcelableCall.ParcelableCallBuilder();
         parcelableCallBuilder.setCallerDisplayName(CALLER_DISPLAY_NAME);
-        parcelableCallBuilder.setContactDisplayName(CONTACT_DISPLAY_NAME);
+        if (hasContactName) {
+            parcelableCallBuilder.setContactDisplayName(CONTACT_DISPLAY_NAME);
+        }
+        parcelableCallBuilder.setCallerDisplayNamePresentation(TelecomManager.PRESENTATION_ALLOWED);
         parcelableCallBuilder.setCapabilities(capabilities);
         parcelableCallBuilder.setState(state);
         parcelableCallBuilder.setConferenceableCallIds(Collections.emptyList());
diff --git a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java
index 33e7cd2..7688fcb 100644
--- a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -211,4 +212,62 @@
         verify(mMockTelecomManager, times(1)).registerPhoneAccount(any());
         verify(mMockTelecomManager, times(1)).unregisterPhoneAccount(any());
     }
+
+    @Test
+    public void updateCalls_newCall() {
+        final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
+        call.setId("123abc");
+        call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
+        final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
+        callMetadataSyncData.addCall(call);
+        final CrossDeviceSyncController.CallManager callManager =
+                new CrossDeviceSyncController.CallManager(mMockContext,
+                        new CrossDeviceSyncController.PhoneAccountManager(mMockContext));
+        callManager.updateCalls(/* associationId= */ 0, callMetadataSyncData);
+        verify(mMockTelecomManager, times(1)).addNewIncomingCall(any(), any());
+    }
+
+    @Test
+    public void updateCalls_newCall_noFacilitator() {
+        final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
+        call.setId("123abc");
+        final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
+        callMetadataSyncData.addCall(call);
+        final CrossDeviceSyncController.CallManager callManager =
+                new CrossDeviceSyncController.CallManager(mMockContext,
+                        new CrossDeviceSyncController.PhoneAccountManager(mMockContext));
+        callManager.updateCalls(/* associationId= */ 0, callMetadataSyncData);
+        verify(mMockTelecomManager, times(0)).addNewIncomingCall(any(), any());
+    }
+
+    @Test
+    public void updateCalls_existingCall() {
+        final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
+        call.setId("123abc");
+        final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
+        callMetadataSyncData.addCall(call);
+        final CrossDeviceSyncController.CallManager callManager =
+                new CrossDeviceSyncController.CallManager(mMockContext,
+                        new CrossDeviceSyncController.PhoneAccountManager(mMockContext));
+        callManager.mCallIds.put(/* associationId= */ 0, Set.of(call.getId()));
+        callManager.updateCalls(/* associationId= */ 0, callMetadataSyncData);
+        verify(mMockTelecomManager, never()).addNewIncomingCall(any(), any());
+    }
+
+    @Test
+    public void updateCalls_removedCall() {
+        final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
+        call.setId("123abc");
+        final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
+        callMetadataSyncData.addCall(call);
+        final CrossDeviceSyncController.CallManager callManager =
+                new CrossDeviceSyncController.CallManager(mMockContext,
+                        new CrossDeviceSyncController.PhoneAccountManager(mMockContext));
+        callManager.mCallIds.put(/* associationId= */ 0, Set.of(call.getId(), "fakeCallId"));
+        callManager.updateCalls(/* associationId= */ 0, callMetadataSyncData);
+        verify(mMockTelecomManager, never()).addNewIncomingCall(any(), any());
+        assertWithMessage("Hasn't removed the id of the removed call")
+                .that(callManager.mCallIds)
+                .containsExactly(/* associationId= */ 0, Set.of(call.getId()));
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/credentials/MetricUtilitiesTest.java b/services/tests/servicestests/src/com/android/server/credentials/MetricUtilitiesTest.java
new file mode 100644
index 0000000..b46f1a6
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/credentials/MetricUtilitiesTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.credentials;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.credentials.metrics.InitialPhaseMetric;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Given the secondary-system nature of the MetricUtilities, we expect absolutely nothing to
+ * throw an error. If one presents itself, that is problematic.
+ *
+ * atest FrameworksServicesTests:com.android.server.credentials.MetricUtilitiesTest
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class MetricUtilitiesTest {
+
+    @Test
+    public void logApiCalledInitialPhase_nullInitPhaseMetricAndNegativeSequence_success() {
+        MetricUtilities.logApiCalledInitialPhase(null, -1);
+    }
+
+    @Test
+    public void logApiCalledInitialPhase_invalidInitPhaseMetricAndPositiveSequence_success() {
+        MetricUtilities.logApiCalledInitialPhase(new InitialPhaseMetric(-1), 1);
+    }
+
+    @Test
+    public void logApiCalledInitialPhase_validInitPhaseMetric_success() {
+        InitialPhaseMetric validInitPhaseMetric = new InitialPhaseMetric(
+                MetricUtilities.getHighlyUniqueInteger());
+        MetricUtilities.logApiCalledInitialPhase(validInitPhaseMetric, 1);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/credentials/metrics/ApiNameTest.java b/services/tests/servicestests/src/com/android/server/credentials/metrics/ApiNameTest.java
new file mode 100644
index 0000000..8093b18
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/credentials/metrics/ApiNameTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.credentials.metrics;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ApiNameTest {
+
+    @Test
+    public void getMetricCode_matchesWestWorldMetricCode_success() {
+        // com.android.os is only visible in cts tests, so we need to mimic it for server side unit
+        // tests. aidegen can identify it but builds will not. Thus, this is the workaround.
+        Set<Integer> expectedApiNames = new HashSet<>();
+        for (int i = 0; i < 10; i++) {
+            expectedApiNames.add(i);
+        }
+        Set<Integer> actualServerApiNames = Arrays.stream(ApiName.values())
+                .map(ApiName::getMetricCode).collect(Collectors.toSet());
+
+        assertThat(actualServerApiNames).containsExactlyElementsIn(expectedApiNames);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/credentials/metrics/ApiStatusTest.java b/services/tests/servicestests/src/com/android/server/credentials/metrics/ApiStatusTest.java
new file mode 100644
index 0000000..3bf4814
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/credentials/metrics/ApiStatusTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.credentials.metrics;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ApiStatusTest {
+
+    @Test
+    public void getMetricCode_matchesWestWorldMetricCode_success() {
+        Set<Integer> expectedApiStatus = new HashSet<>();
+        for (int i = 1; i < 5; i++) {
+            expectedApiStatus.add(i);
+        }
+        Set<Integer> actualServerApiStatus = Arrays.stream(ApiStatus.values())
+                .map(ApiStatus::getMetricCode).collect(Collectors.toSet());
+
+        assertThat(actualServerApiStatus).containsExactlyElementsIn(expectedApiStatus);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/credentials/metrics/EntryEnumTest.java b/services/tests/servicestests/src/com/android/server/credentials/metrics/EntryEnumTest.java
new file mode 100644
index 0000000..3104cc2
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/credentials/metrics/EntryEnumTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.credentials.metrics;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class EntryEnumTest {
+
+    @Test
+    public void getMetricCode_matchesWestWorldMetricCode_success() {
+        Set<Integer> expectedEntryEnum = new HashSet<>();
+        for (int i = 0; i < 5; i++) {
+            expectedEntryEnum.add(i);
+        }
+        Set<Integer> actualServerEntryEnum = Arrays.stream(EntryEnum.values())
+                .map(EntryEnum::getMetricCode).collect(Collectors.toSet());
+
+        assertThat(actualServerEntryEnum).containsExactlyElementsIn(expectedEntryEnum);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
index 4d06855..6684150 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
@@ -75,6 +75,10 @@
     private static final DeviceState UNSUPPORTED_DEVICE_STATE =
             new DeviceState(255, "UNSUPPORTED", 0 /* flags */);
 
+    private static final int[] SUPPORTED_DEVICE_STATE_IDENTIFIERS =
+            new int[]{DEFAULT_DEVICE_STATE.getIdentifier(), OTHER_DEVICE_STATE.getIdentifier(),
+                    DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP.getIdentifier()};
+
     private static final int FAKE_PROCESS_ID = 100;
 
     private TestDeviceStatePolicy mPolicy;
@@ -88,6 +92,11 @@
         mProvider = new TestDeviceStateProvider();
         mPolicy = new TestDeviceStatePolicy(mProvider);
         mSysPropSetter = new TestSystemPropertySetter();
+        setupDeviceStateManagerService();
+        flushHandler(); // Flush the handler to ensure the initial values are committed.
+    }
+
+    private void setupDeviceStateManagerService() {
         mService = new DeviceStateManagerService(InstrumentationRegistry.getContext(), mPolicy,
                 mSysPropSetter);
 
@@ -97,8 +106,6 @@
         when(mService.mActivityTaskManagerInternal.getTopApp())
                 .thenReturn(mWindowProcessController);
         when(mWindowProcessController.getPid()).thenReturn(FAKE_PROCESS_ID);
-
-        flushHandler(); // Flush the handler to ensure the initial values are committed.
     }
 
     private void flushHandler() {
@@ -264,14 +271,26 @@
     public void getDeviceStateInfo() throws RemoteException {
         DeviceStateInfo info = mService.getBinderService().getDeviceStateInfo();
         assertNotNull(info);
-        assertArrayEquals(info.supportedStates,
-                new int[] { DEFAULT_DEVICE_STATE.getIdentifier(),
-                        OTHER_DEVICE_STATE.getIdentifier(),
-                        DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP.getIdentifier()});
+        assertArrayEquals(info.supportedStates, SUPPORTED_DEVICE_STATE_IDENTIFIERS);
         assertEquals(info.baseState, DEFAULT_DEVICE_STATE.getIdentifier());
         assertEquals(info.currentState, DEFAULT_DEVICE_STATE.getIdentifier());
     }
 
+    @Test
+    public void getDeviceStateInfo_baseStateAndCommittedStateNotSet() throws RemoteException {
+        // Create a provider and a service without an initial base state.
+        mProvider = new TestDeviceStateProvider(null /* initialState */);
+        mPolicy = new TestDeviceStatePolicy(mProvider);
+        setupDeviceStateManagerService();
+        flushHandler(); // Flush the handler to ensure the initial values are committed.
+
+        DeviceStateInfo info = mService.getBinderService().getDeviceStateInfo();
+
+        assertArrayEquals(info.supportedStates, SUPPORTED_DEVICE_STATE_IDENTIFIERS);
+        assertEquals(info.baseState, INVALID_DEVICE_STATE);
+        assertEquals(info.currentState, INVALID_DEVICE_STATE);
+    }
+
     @FlakyTest(bugId = 223153452)
     @Test
     public void registerCallback() throws RemoteException {
@@ -325,6 +344,21 @@
     }
 
     @Test
+    public void registerCallback_initialValueUnavailable() throws RemoteException {
+        // Create a provider and a service without an initial base state.
+        mProvider = new TestDeviceStateProvider(null /* initialState */);
+        mPolicy = new TestDeviceStatePolicy(mProvider);
+        setupDeviceStateManagerService();
+        flushHandler(); // Flush the handler to ensure the initial values are committed.
+
+        TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
+        mService.getBinderService().registerCallback(callback);
+        flushHandler();
+        // The callback should never be called when the base state is not set yet.
+        assertNull(callback.getLastNotifiedInfo());
+    }
+
+    @Test
     public void requestState() throws RemoteException {
         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
         mService.getBinderService().registerCallback(callback);
@@ -939,8 +973,18 @@
                 DEFAULT_DEVICE_STATE,
                 OTHER_DEVICE_STATE,
                 DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP};
+
+        @Nullable private final DeviceState mInitialState;
         private Listener mListener;
 
+        private TestDeviceStateProvider() {
+            this(DEFAULT_DEVICE_STATE);
+        }
+
+        private TestDeviceStateProvider(@Nullable DeviceState initialState) {
+            mInitialState = initialState;
+        }
+
         @Override
         public void setListener(Listener listener) {
             if (mListener != null) {
@@ -950,7 +994,9 @@
             mListener = listener;
             mListener.onSupportedDeviceStatesChanged(mSupportedDeviceStates,
                     SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED);
-            mListener.onStateChanged(mSupportedDeviceStates[0].getIdentifier());
+            if (mInitialState != null) {
+                mListener.onStateChanged(mInitialState.getIdentifier());
+            }
         }
 
         public void notifySupportedDeviceStates(DeviceState[] supportedDeviceStates) {
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
index 8981160..021f2d1 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
@@ -323,6 +323,61 @@
     }
 
     @Test
+    public void testMultipleBrightnessEvents() {
+        final float brightnessOne = 0.2f;
+        final float brightnessTwo = 0.4f;
+        final float brightnessThree = 0.6f;
+        final float brightnessFour = 0.3f;
+        final String displayId = "1234";
+        final float[] luxValues = new float[]{1.0f};
+
+        startTracker(mTracker);
+        final long sensorTime = TimeUnit.NANOSECONDS.toMillis(mInjector.elapsedRealtimeNanos());
+        final long sensorTime2 = sensorTime + TimeUnit.SECONDS.toMillis(20);
+        final long sensorTime3 = sensorTime2 + TimeUnit.SECONDS.toMillis(30);
+        final long sensorTime4 = sensorTime3 + TimeUnit.SECONDS.toMillis(40);
+        final long originalTime = mInjector.currentTimeMillis();
+
+        mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2));
+        notifyBrightnessChanged(mTracker, brightnessOne, displayId, luxValues,
+                new long[] {sensorTime});
+
+        mInjector.incrementTime(TimeUnit.SECONDS.toMillis(20));
+        notifyBrightnessChanged(mTracker, brightnessTwo, displayId, luxValues,
+                new long[] {sensorTime2});
+
+        mInjector.incrementTime(TimeUnit.SECONDS.toMillis(30));
+        notifyBrightnessChanged(mTracker, brightnessThree, displayId, luxValues,
+                new long[] {sensorTime3});
+
+        mInjector.incrementTime(TimeUnit.SECONDS.toMillis(40));
+        notifyBrightnessChanged(mTracker, brightnessFour, displayId, luxValues,
+                new long[] {sensorTime4});
+        mTracker.stop();
+        List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
+        assertEquals(4, events.size());
+        BrightnessChangeEvent eventOne = events.get(0);
+        assertEquals(brightnessOne, eventOne.brightness, FLOAT_DELTA);
+        assertEquals(originalTime,
+                eventOne.luxTimestamps[0]);
+
+        BrightnessChangeEvent eventTwo = events.get(1);
+        assertEquals(brightnessTwo, eventTwo.brightness, FLOAT_DELTA);
+        assertEquals(originalTime + TimeUnit.SECONDS.toMillis(20),
+                eventTwo.luxTimestamps[0]);
+
+        BrightnessChangeEvent eventThree = events.get(2);
+        assertEquals(brightnessThree, eventThree.brightness, FLOAT_DELTA);
+        assertEquals(originalTime + TimeUnit.SECONDS.toMillis(50),
+                eventThree.luxTimestamps[0]);
+
+        BrightnessChangeEvent eventFour = events.get(3);
+        assertEquals(brightnessFour, eventFour.brightness, FLOAT_DELTA);
+        assertEquals(originalTime + TimeUnit.SECONDS.toMillis(90),
+                eventFour.luxTimestamps[0]);
+    }
+
+    @Test
     public void testBrightnessFullPopulatedEvent() {
         final int initialBrightness = 230;
         final int brightness = 130;
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index acfc073..a6c5737 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -220,6 +220,11 @@
             return new int[]{};
         }
 
+        @Override
+        int[] getHdrOutputTypesWithLatency() {
+            return new int[]{Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION};
+        }
+
         boolean getHdrOutputConversionSupport() {
             return true;
         }
@@ -1079,7 +1084,7 @@
         verify(mMockProjectionService, atLeastOnce()).setContentRecordingSession(
                 mContentRecordingSessionCaptor.capture(), nullable(IMediaProjection.class));
         ContentRecordingSession session = mContentRecordingSessionCaptor.getValue();
-        assertThat(session.isWaitingToRecord()).isTrue();
+        assertThat(session.isWaitingForConsent()).isTrue();
     }
 
     @Test
@@ -1114,7 +1119,7 @@
         assertThat(session.getContentToRecord()).isEqualTo(RECORD_CONTENT_DISPLAY);
         assertThat(session.getVirtualDisplayId()).isEqualTo(displayId);
         assertThat(session.getDisplayToRecord()).isEqualTo(displayToRecord);
-        assertThat(session.isWaitingToRecord()).isFalse();
+        assertThat(session.isWaitingForConsent()).isFalse();
     }
 
     @Test
@@ -1862,6 +1867,44 @@
         assertEquals(mode.getPreferredHdrOutputType(), mPreferredHdrOutputType);
     }
 
+    @Test
+    public void testHdrConversionMode_withMinimalPostProcessing() {
+        DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
+        DisplayManagerService.BinderService displayManagerBinderService =
+                displayManager.new BinderService();
+        registerDefaultDisplays(displayManager);
+        displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
+        FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager,
+                new float[]{60f, 30f, 20f});
+        int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
+                displayDevice);
+
+        final HdrConversionMode mode = new HdrConversionMode(
+                HdrConversionMode.HDR_CONVERSION_FORCE,
+                Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION);
+        displayManager.setHdrConversionModeInternal(mode);
+        assertEquals(mode, displayManager.getHdrConversionModeSettingInternal());
+
+        displayManager.setMinimalPostProcessingAllowed(true);
+        displayManager.setDisplayPropertiesInternal(displayId, false /* hasContent */,
+                30.0f /* requestedRefreshRate */,
+                displayDevice.getDisplayDeviceInfoLocked().modeId /* requestedModeId */,
+                30.0f /* requestedMinRefreshRate */, 120.0f /* requestedMaxRefreshRate */,
+                true /* preferMinimalPostProcessing */, false /* disableHdrConversion */,
+                true /* inTraversal */);
+
+        assertEquals(new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_PASSTHROUGH),
+                displayManager.getHdrConversionModeInternal());
+
+        displayManager.setDisplayPropertiesInternal(displayId, false /* hasContent */,
+                30.0f /* requestedRefreshRate */,
+                displayDevice.getDisplayDeviceInfoLocked().modeId /* requestedModeId */,
+                30.0f /* requestedMinRefreshRate */, 120.0f /* requestedMaxRefreshRate */,
+                false /* preferMinimalPostProcessing */, false /* disableHdrConversion */,
+                true /* inTraversal */);
+        assertEquals(mode, displayManager.getHdrConversionModeInternal());
+    }
+
     private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled)
             throws Exception {
         DisplayManagerService displayManager =
diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
index f6cf571..30ff8ba 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
@@ -17,6 +17,7 @@
 package com.android.server.display;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.any;
@@ -191,6 +192,19 @@
     }
 
     @Test
+    public void testUpdateLayoutLimitedRefreshRate_setsDirtyFlag() {
+        SurfaceControl.RefreshRateRange layoutLimitedRefreshRate =
+                new SurfaceControl.RefreshRateRange(0, 120);
+        assertFalse(mLogicalDisplay.isDirtyLocked());
+
+        mLogicalDisplay.updateLayoutLimitedRefreshRateLocked(layoutLimitedRefreshRate);
+        assertTrue(mLogicalDisplay.isDirtyLocked());
+
+        mLogicalDisplay.updateLocked(mDeviceRepo);
+        assertFalse(mLogicalDisplay.isDirtyLocked());
+    }
+
+    @Test
     public void testUpdateRefreshRateThermalThrottling() {
         SparseArray<SurfaceControl.RefreshRateRange> refreshRanges = new SparseArray<>();
         refreshRanges.put(0, new SurfaceControl.RefreshRateRange(0, 120));
@@ -207,6 +221,45 @@
     }
 
     @Test
+    public void testUpdateRefreshRateThermalThrottling_setsDirtyFlag() {
+        SparseArray<SurfaceControl.RefreshRateRange> refreshRanges = new SparseArray<>();
+        refreshRanges.put(0, new SurfaceControl.RefreshRateRange(0, 120));
+        assertFalse(mLogicalDisplay.isDirtyLocked());
+
+        mLogicalDisplay.updateThermalRefreshRateThrottling(refreshRanges);
+        assertTrue(mLogicalDisplay.isDirtyLocked());
+
+        mLogicalDisplay.updateLocked(mDeviceRepo);
+        assertFalse(mLogicalDisplay.isDirtyLocked());
+    }
+
+    @Test
+    public void testUpdateDisplayGroupIdLocked() {
+        int newId = 999;
+        DisplayInfo info1 = mLogicalDisplay.getDisplayInfoLocked();
+        mLogicalDisplay.updateDisplayGroupIdLocked(newId);
+        DisplayInfo info2 = mLogicalDisplay.getDisplayInfoLocked();
+        // Display info should only be updated when updateLocked is called
+        assertEquals(info2, info1);
+
+        mLogicalDisplay.updateLocked(mDeviceRepo);
+        DisplayInfo info3 = mLogicalDisplay.getDisplayInfoLocked();
+        assertNotEquals(info3, info2);
+        assertEquals(newId, info3.displayGroupId);
+    }
+
+    @Test
+    public void testUpdateDisplayGroupIdLocked_setsDirtyFlag() {
+        assertFalse(mLogicalDisplay.isDirtyLocked());
+
+        mLogicalDisplay.updateDisplayGroupIdLocked(99);
+        assertTrue(mLogicalDisplay.isDirtyLocked());
+
+        mLogicalDisplay.updateLocked(mDeviceRepo);
+        assertFalse(mLogicalDisplay.isDirtyLocked());
+    }
+
+    @Test
     public void testSetThermalBrightnessThrottlingDataId() {
         String brightnessThrottlingDataId = "throttling_data_id";
         DisplayInfo info1 = mLogicalDisplay.getDisplayInfoLocked();
@@ -220,4 +273,15 @@
         assertNotEquals(info3, info2);
         assertEquals(brightnessThrottlingDataId, info3.thermalBrightnessThrottlingDataId);
     }
+
+    @Test
+    public void testSetThermalBrightnessThrottlingDataId_setsDirtyFlag() {
+        assertFalse(mLogicalDisplay.isDirtyLocked());
+
+        mLogicalDisplay.setThermalBrightnessThrottlingDataIdLocked("99");
+        assertTrue(mLogicalDisplay.isDirtyLocked());
+
+        mLogicalDisplay.updateLocked(mDeviceRepo);
+        assertFalse(mLogicalDisplay.isDirtyLocked());
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index 0e6b412..39930bc 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -92,6 +92,7 @@
     private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
     private HdmiPortInfo[] mHdmiPortInfo;
     private ArrayList<Integer> mLocalDeviceTypes = new ArrayList<>();
+    private static final int PORT_ID_EARC_SUPPORTED = 3;
 
     @Before
     public void setUp() throws Exception {
@@ -148,7 +149,7 @@
                         .setEarcSupported(false)
                         .build();
         mHdmiPortInfo[2] =
-                new HdmiPortInfo.Builder(3, HdmiPortInfo.PORT_INPUT, 0x2000)
+                new HdmiPortInfo.Builder(PORT_ID_EARC_SUPPORTED, HdmiPortInfo.PORT_INPUT, 0x2000)
                         .setCecSupported(true)
                         .setMhlSupported(false)
                         .setArcSupported(true)
@@ -1129,6 +1130,23 @@
     }
 
     @Test
+    public void disableEarc_noEarcLocalDevice_enableArc() {
+        mHdmiControlServiceSpy.clearEarcLocalDevice();
+        mHdmiControlServiceSpy.addEarcLocalDevice(
+                new HdmiEarcLocalDeviceTx(mHdmiControlServiceSpy));
+        mHdmiControlServiceSpy.setEarcEnabled(HdmiControlManager.EARC_FEATURE_DISABLED);
+        mTestLooper.dispatchAll();
+        assertThat(mHdmiControlServiceSpy.getEarcLocalDevice()).isNull();
+
+        Mockito.clearInvocations(mHdmiControlServiceSpy);
+        mHdmiControlServiceSpy.handleEarcStateChange(Constants.HDMI_EARC_STATUS_ARC_PENDING,
+                PORT_ID_EARC_SUPPORTED);
+        verify(mHdmiControlServiceSpy, times(1))
+                .notifyEarcStatusToAudioService(eq(false), eq(new ArrayList<>()));
+        verify(mHdmiControlServiceSpy, times(1)).startArcAction(eq(true), any());
+    }
+
+    @Test
     public void disableCec_doNotClearEarcLocalDevice() {
         mHdmiControlServiceSpy.clearEarcLocalDevice();
         mHdmiControlServiceSpy.addEarcLocalDevice(
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockscreenFrpTest.java b/services/tests/servicestests/src/com/android/server/locksettings/LockscreenFrpTest.java
index 2b49b8a..a242cde 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockscreenFrpTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockscreenFrpTest.java
@@ -23,6 +23,8 @@
 import static com.android.internal.widget.LockPatternUtils.USER_FRP;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.app.PropertyInvalidatedCache;
 import android.app.admin.DevicePolicyManager;
@@ -38,8 +40,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.nio.ByteBuffer;
 
-/** Test setting a lockscreen credential and then verify it under USER_FRP */
+/** Tests that involve the Factory Reset Protection (FRP) credential. */
 @SmallTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
@@ -148,4 +151,68 @@
                 mService.verifyCredential(newPin("1234"), USER_FRP, 0 /* flags */)
                         .getResponseCode());
     }
+
+    // The FRP block that gets written by the current version of Android must still be accepted by
+    // old versions of Android.  This test tries to detect non-forward-compatible changes in
+    // PasswordData#toBytes(), which would break that.
+    @Test
+    public void testFrpBlock_isForwardsCompatible() {
+        mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
+        PersistentData data = mStorage.readPersistentDataBlock();
+        ByteBuffer buffer = ByteBuffer.wrap(data.payload);
+
+        final int credentialType = buffer.getInt();
+        assertEquals(CREDENTIAL_TYPE_PIN, credentialType);
+
+        final byte scryptLogN = buffer.get();
+        assertTrue(scryptLogN >= 0);
+
+        final byte scryptLogR = buffer.get();
+        assertTrue(scryptLogR >= 0);
+
+        final byte scryptLogP = buffer.get();
+        assertTrue(scryptLogP >= 0);
+
+        final int saltLength = buffer.getInt();
+        assertTrue(saltLength > 0);
+        final byte[] salt = new byte[saltLength];
+        buffer.get(salt);
+
+        final int passwordHandleLength = buffer.getInt();
+        assertTrue(passwordHandleLength > 0);
+        final byte[] passwordHandle = new byte[passwordHandleLength];
+        buffer.get(passwordHandle);
+    }
+
+    @Test
+    public void testFrpBlock_inBadAndroid14FormatIsAutomaticallyFixed() {
+        mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
+
+        // Write a "bad" FRP block with PasswordData beginning with the bytes [0, 2].
+        byte[] badPasswordData = new byte[] {
+                0, 2, /* version 2 */
+                0, 3, /* CREDENTIAL_TYPE_PIN */
+                11, /* scryptLogN */
+                22, /* scryptLogR */
+                33, /* scryptLogP */
+                0, 0, 0, 5, /* salt.length */
+                1, 2, -1, -2, 55, /* salt */
+                0, 0, 0, 6, /* passwordHandle.length */
+                2, 3, -2, -3, 44, 1, /* passwordHandle */
+                0, 0, 0, 6, /* pinLength */
+        };
+        mStorage.writePersistentDataBlock(PersistentData.TYPE_SP_GATEKEEPER, PRIMARY_USER_ID, 0,
+                badPasswordData);
+
+        // Execute the code that should fix the FRP block.
+        assertFalse(mStorage.getBoolean("migrated_frp2", false, 0));
+        mService.migrateOldDataAfterSystemReady();
+        assertTrue(mStorage.getBoolean("migrated_frp2", false, 0));
+
+        // Verify that the FRP block has been fixed.
+        PersistentData data = mStorage.readPersistentDataBlock();
+        assertEquals(PersistentData.TYPE_SP_GATEKEEPER, data.type);
+        ByteBuffer buffer = ByteBuffer.wrap(data.payload);
+        assertEquals(CREDENTIAL_TYPE_PIN, buffer.getInt());
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index bfb6b0f1..ce0347d 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -23,6 +23,7 @@
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
 import static com.android.internal.widget.LockPatternUtils.PIN_LENGTH_UNAVAILABLE;
 
 import static org.junit.Assert.assertEquals;
@@ -625,11 +626,9 @@
     }
 
     @Test
-    public void testPasswordDataV2VersionCredentialTypePin_deserialize() {
-        // Test that we can deserialize existing PasswordData and don't inadvertently change the
-        // wire format.
+    public void testDeserializePasswordData_forPinWithLengthAvailable() {
         byte[] serialized = new byte[] {
-                0, 2, 0, 2, /* CREDENTIAL_TYPE_PASSWORD_OR_PIN */
+                0, 0, 0, 3, /* CREDENTIAL_TYPE_PIN */
                 11, /* scryptLogN */
                 22, /* scryptLogR */
                 33, /* scryptLogP */
@@ -637,25 +636,24 @@
                 1, 2, -1, -2, 55, /* salt */
                 0, 0, 0, 6, /* passwordHandle.length */
                 2, 3, -2, -3, 44, 1, /* passwordHandle */
-                0, 0, 0, 5, /* pinLength */
+                0, 0, 0, 6, /* pinLength */
         };
+        assertFalse(PasswordData.isBadFormatFromAndroid14Beta(serialized));
         PasswordData deserialized = PasswordData.fromBytes(serialized);
 
         assertEquals(11, deserialized.scryptLogN);
         assertEquals(22, deserialized.scryptLogR);
         assertEquals(33, deserialized.scryptLogP);
-        assertEquals(5, deserialized.pinLength);
-        assertEquals(CREDENTIAL_TYPE_PASSWORD_OR_PIN, deserialized.credentialType);
+        assertEquals(CREDENTIAL_TYPE_PIN, deserialized.credentialType);
         assertArrayEquals(PAYLOAD, deserialized.salt);
         assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
+        assertEquals(6, deserialized.pinLength);
     }
 
     @Test
-    public void testPasswordDataV2VersionNegativePinLengthNoCredential_deserialize() {
-        // Test that we can deserialize existing PasswordData and don't inadvertently change the
-        // wire format.
+    public void testDeserializePasswordData_forPinWithLengthExplicitlyUnavailable() {
         byte[] serialized = new byte[] {
-                0, 2, -1, -1, /* CREDENTIAL_TYPE_NONE */
+                0, 0, 0, 3, /* CREDENTIAL_TYPE_PIN */
                 11, /* scryptLogN */
                 22, /* scryptLogR */
                 33, /* scryptLogP */
@@ -663,23 +661,53 @@
                 1, 2, -1, -2, 55, /* salt */
                 0, 0, 0, 6, /* passwordHandle.length */
                 2, 3, -2, -3, 44, 1, /* passwordHandle */
-                -1, -1, -1, -2, /* pinLength */
+                -1, -1, -1, -1, /* pinLength */
         };
         PasswordData deserialized = PasswordData.fromBytes(serialized);
 
         assertEquals(11, deserialized.scryptLogN);
         assertEquals(22, deserialized.scryptLogR);
         assertEquals(33, deserialized.scryptLogP);
-        assertEquals(-2, deserialized.pinLength);
-        assertEquals(CREDENTIAL_TYPE_NONE, deserialized.credentialType);
+        assertEquals(CREDENTIAL_TYPE_PIN, deserialized.credentialType);
         assertArrayEquals(PAYLOAD, deserialized.salt);
         assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
+        assertEquals(PIN_LENGTH_UNAVAILABLE, deserialized.pinLength);
     }
 
     @Test
-    public void testPasswordDataV1VersionNoCredential_deserialize() {
-        // Test that we can deserialize existing PasswordData and don't inadvertently change the
-        // wire format.
+    public void testDeserializePasswordData_forPinWithVersionNumber() {
+        // Test deserializing a PasswordData that has a version number in the first two bytes.
+        // Files like this were created by some Android 14 beta versions.  This version number was a
+        // mistake and should be ignored by the deserializer.
+        byte[] serialized = new byte[] {
+                0, 2, /* version 2 */
+                0, 3, /* CREDENTIAL_TYPE_PIN */
+                11, /* scryptLogN */
+                22, /* scryptLogR */
+                33, /* scryptLogP */
+                0, 0, 0, 5, /* salt.length */
+                1, 2, -1, -2, 55, /* salt */
+                0, 0, 0, 6, /* passwordHandle.length */
+                2, 3, -2, -3, 44, 1, /* passwordHandle */
+                0, 0, 0, 6, /* pinLength */
+        };
+        assertTrue(PasswordData.isBadFormatFromAndroid14Beta(serialized));
+        PasswordData deserialized = PasswordData.fromBytes(serialized);
+
+        assertEquals(11, deserialized.scryptLogN);
+        assertEquals(22, deserialized.scryptLogR);
+        assertEquals(33, deserialized.scryptLogP);
+        assertEquals(CREDENTIAL_TYPE_PIN, deserialized.credentialType);
+        assertArrayEquals(PAYLOAD, deserialized.salt);
+        assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
+        assertEquals(6, deserialized.pinLength);
+    }
+
+    @Test
+    public void testDeserializePasswordData_forNoneCred() {
+        // Test that a PasswordData that uses CREDENTIAL_TYPE_NONE and lacks the PIN length field
+        // can be deserialized.  Files like this were created by Android 13 and earlier.  Android 14
+        // and later no longer create PasswordData for CREDENTIAL_TYPE_NONE.
         byte[] serialized = new byte[] {
                 -1, -1, -1, -1, /* CREDENTIAL_TYPE_NONE */
                 11, /* scryptLogN */
@@ -695,16 +723,17 @@
         assertEquals(11, deserialized.scryptLogN);
         assertEquals(22, deserialized.scryptLogR);
         assertEquals(33, deserialized.scryptLogP);
-        assertEquals(PIN_LENGTH_UNAVAILABLE, deserialized.pinLength);
         assertEquals(CREDENTIAL_TYPE_NONE, deserialized.credentialType);
         assertArrayEquals(PAYLOAD, deserialized.salt);
         assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
+        assertEquals(PIN_LENGTH_UNAVAILABLE, deserialized.pinLength);
     }
 
     @Test
-    public void testPasswordDataV1VersionCredentialTypePin_deserialize() {
-        // Test that we can deserialize existing PasswordData and don't inadvertently change the
-        // wire format.
+    public void testDeserializePasswordData_forPasswordOrPin() {
+        // Test that a PasswordData that uses CREDENTIAL_TYPE_PASSWORD_OR_PIN and lacks the PIN
+        // length field can be deserialized.  Files like this were created by Android 10 and
+        // earlier.  Android 11 eliminated CREDENTIAL_TYPE_PASSWORD_OR_PIN.
         byte[] serialized = new byte[] {
                 0, 0, 0, 2, /* CREDENTIAL_TYPE_PASSWORD_OR_PIN */
                 11, /* scryptLogN */
@@ -720,10 +749,10 @@
         assertEquals(11, deserialized.scryptLogN);
         assertEquals(22, deserialized.scryptLogR);
         assertEquals(33, deserialized.scryptLogP);
-        assertEquals(PIN_LENGTH_UNAVAILABLE, deserialized.pinLength);
         assertEquals(CREDENTIAL_TYPE_PASSWORD_OR_PIN, deserialized.credentialType);
         assertArrayEquals(PAYLOAD, deserialized.salt);
         assertArrayEquals(PAYLOAD2, deserialized.passwordHandle);
+        assertEquals(PIN_LENGTH_UNAVAILABLE, deserialized.pinLength);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
index 275533f..b91a6cb 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
@@ -139,7 +139,7 @@
         doReturn(mPackageManager).when(mContext).getPackageManager();
 
         mClock = new OffsettableClock.Stopped();
-        mWaitingDisplaySession.setWaitingToRecord(true);
+        mWaitingDisplaySession.setWaitingForConsent(true);
         mWaitingDisplaySession.setVirtualDisplayId(5);
 
         mAppInfo.targetSdkVersion = 32;
@@ -484,7 +484,7 @@
                 mSessionCaptor.capture());
         // Examine latest value.
         final ContentRecordingSession capturedSession = mSessionCaptor.getValue();
-        assertThat(capturedSession.isWaitingToRecord()).isFalse();
+        assertThat(capturedSession.isWaitingForConsent()).isFalse();
         assertThat(capturedSession.getVirtualDisplayId()).isEqualTo(INVALID_DISPLAY);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserJourneyLoggerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserJourneyLoggerTest.java
index 20e2692..bfd4072 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserJourneyLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserJourneyLoggerTest.java
@@ -27,6 +27,7 @@
 import static com.android.server.pm.UserJourneyLogger.EVENT_STATE_NONE;
 import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_GRANT_ADMIN;
 import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_CREATE;
+import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_LIFECYCLE;
 import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_REMOVE;
 import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_START;
 import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_STOP;
@@ -499,6 +500,27 @@
                 0x00000402, ERROR_CODE_UNSPECIFIED, 3);
     }
 
+    @Test
+    public void testUserLifecycleJourney() {
+        final long startTime = System.currentTimeMillis();
+        final UserJourneyLogger.UserJourneySession session = mUserJourneyLogger
+                .startSessionForDelayedJourney(10, USER_JOURNEY_USER_LIFECYCLE, startTime);
+
+
+        final UserLifecycleJourneyReportedCaptor report = new UserLifecycleJourneyReportedCaptor();
+        final UserInfo targetUser = new UserInfo(10, "test target user",
+                UserInfo.FLAG_ADMIN | UserInfo.FLAG_FULL);
+        mUserJourneyLogger.logDelayedUserJourneyFinishWithError(0, targetUser,
+                USER_JOURNEY_USER_LIFECYCLE, ERROR_CODE_UNSPECIFIED);
+
+
+        report.captureAndAssert(mUserJourneyLogger, session.mSessionId,
+                USER_JOURNEY_USER_LIFECYCLE, 0, 10,
+                FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__FULL_SECONDARY,
+                0x00000402, ERROR_CODE_UNSPECIFIED, 1);
+        assertThat(report.mElapsedTime.getValue() > 0L).isTrue();
+    }
+
     static class UserLifecycleJourneyReportedCaptor {
         ArgumentCaptor<Long> mSessionId = ArgumentCaptor.forClass(Long.class);
         ArgumentCaptor<Integer> mJourney = ArgumentCaptor.forClass(Integer.class);
@@ -507,6 +529,7 @@
         ArgumentCaptor<Integer> mUserType = ArgumentCaptor.forClass(Integer.class);
         ArgumentCaptor<Integer> mUserFlags = ArgumentCaptor.forClass(Integer.class);
         ArgumentCaptor<Integer> mErrorCode = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Long> mElapsedTime = ArgumentCaptor.forClass(Long.class);
 
         public void captureAndAssert(UserJourneyLogger mUserJourneyLogger,
                 long sessionId, int journey, int originalUserId,
@@ -518,7 +541,8 @@
                             mTargetUserId.capture(),
                             mUserType.capture(),
                             mUserFlags.capture(),
-                            mErrorCode.capture());
+                            mErrorCode.capture(),
+                            mElapsedTime.capture());
 
             assertThat(mSessionId.getValue()).isEqualTo(sessionId);
             assertThat(mJourney.getValue()).isEqualTo(journey);
@@ -577,4 +601,4 @@
                     state, errorCode, 1);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
index de82854..b2843d8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
@@ -422,8 +422,7 @@
                     null /* splitNames */, null /* isFeatureSplits */, null /* usesSplitNames */,
                     null /* configForSplit */, null /* splitApkPaths */,
                     null /* splitRevisionCodes */, baseApk.getTargetSdkVersion(),
-                    null /* requiredSplitTypes */, null /* splitTypes */,
-                    false /* allowUpdateOwnership */);
+                    null /* requiredSplitTypes */, null /* splitTypes */);
             Assert.assertEquals(dm.length(), DexMetadataHelper.getPackageDexMetadataSize(pkgLite));
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/power/NotifierTest.java b/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
index 849aae2..2f03965 100644
--- a/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
@@ -34,7 +34,10 @@
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.os.BatteryStats;
 import android.os.Handler;
+import android.os.IWakeLockCallback;
 import android.os.Looper;
+import android.os.PowerManager;
+import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.VibrationAttributes;
 import android.os.Vibrator;
@@ -219,6 +222,34 @@
         verify(mStatusBarManagerInternal, never()).showChargingAnimation(anyInt());
     }
 
+    @Test
+    public void testOnWakeLockListener_RemoteException_NoRethrow() {
+        createNotifier();
+
+        IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() {
+            @Override public void onStateChanged(boolean enabled) throws RemoteException {
+                throw new RemoteException("Just testing");
+            }
+        };
+
+        final int uid = 1234;
+        final int pid = 5678;
+        mNotifier.onWakeLockReleased(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
+                "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
+                exceptingCallback);
+        mNotifier.onWakeLockAcquired(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
+                "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
+                exceptingCallback);
+        mNotifier.onWakeLockChanging(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
+                "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
+                exceptingCallback,
+                PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag",
+                "my.package.name", uid, pid, /* newWorkSource= */ null, /* newHistoryTag= */ null,
+                exceptingCallback);
+        mTestLooper.dispatchAll();
+        // If we didn't throw, we're good!
+    }
+
     private final PowerManagerService.Injector mInjector = new PowerManagerService.Injector() {
         @Override
         Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 933f002..7aec045 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -26,6 +26,9 @@
 import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
 import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
 
+import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
+import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertFalse;
@@ -145,6 +148,7 @@
     @Mock private ActivityManagerInternal mActivityManagerInternalMock;
     @Mock private AttentionManagerInternal mAttentionManagerInternalMock;
     @Mock private DreamManagerInternal mDreamManagerInternalMock;
+    @Mock private WindowManagerPolicy mPolicyMock;
     @Mock private PowerManagerService.NativeWrapper mNativeWrapperMock;
     @Mock private Notifier mNotifierMock;
     @Mock private WirelessChargerDetector mWirelessChargerDetectorMock;
@@ -205,6 +209,7 @@
                 .thenReturn(true);
         when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), anyString())).thenReturn("");
         when(mAmbientDisplayConfigurationMock.ambientDisplayAvailable()).thenReturn(true);
+        when(mPolicyMock.getLidState()).thenReturn(LID_ABSENT);
 
         addLocalServiceMock(LightsManager.class, mLightsManagerMock);
         addLocalServiceMock(DisplayManagerInternal.class, mDisplayManagerInternalMock);
@@ -212,6 +217,7 @@
         addLocalServiceMock(ActivityManagerInternal.class, mActivityManagerInternalMock);
         addLocalServiceMock(AttentionManagerInternal.class, mAttentionManagerInternalMock);
         addLocalServiceMock(DreamManagerInternal.class, mDreamManagerInternalMock);
+        addLocalServiceMock(WindowManagerPolicy.class, mPolicyMock);
 
         mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
         mResourcesSpy = spy(mContextSpy.getResources());
@@ -678,6 +684,20 @@
         assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
     }
 
+    @Test
+    public void testWakefulnessAwake_ShouldNotWakeUpWhenLidClosed() {
+        when(mPolicyMock.getLidState()).thenReturn(LID_CLOSED);
+        createService();
+        startSystem();
+        forceSleep();
+
+        mService.getBinderServiceInstance().wakeUp(mClock.now(),
+                PowerManager.WAKE_REASON_POWER_BUTTON,
+                "testing IPowerManager.wakeUp()", "pkg.name");
+
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+    }
+
     /**
      * Tests a series of variants that control whether a device wakes-up when it is plugged in
      * or docked.
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java b/services/tests/servicestests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java
index 76b6a82..d181419 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/stats/wakeups/CpuWakeupStatsTest.java
@@ -23,8 +23,6 @@
 import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_UNKNOWN;
 import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_WIFI;
 
-import static com.android.server.power.stats.wakeups.CpuWakeupStats.WAKEUP_REASON_HALF_WINDOW_MS;
-
 import static com.google.common.truth.Truth.assertThat;
 
 import android.content.Context;
@@ -55,7 +53,7 @@
     private static final String KERNEL_REASON_SENSOR_IRQ = "15 test.sensor.device";
     private static final String KERNEL_REASON_CELLULAR_DATA_IRQ = "18 test.cellular_data.device";
     private static final String KERNEL_REASON_UNKNOWN_IRQ = "140 test.unknown.device";
-    private static final String KERNEL_REASON_UNKNOWN = "free-form-reason test.alarm.device";
+    private static final String KERNEL_REASON_UNKNOWN_FORMAT = "free-form-reason test.alarm.device";
     private static final String KERNEL_REASON_ALARM_ABNORMAL = "-1 test.alarm.device";
     private static final String KERNEL_REASON_ABORT = "Abort: due to test.alarm.device";
 
@@ -85,30 +83,29 @@
 
     @Test
     public void removesOldWakeups() {
-        // The xml resource doesn't matter for this test.
-        final CpuWakeupStats obj = new CpuWakeupStats(sContext, R.xml.irq_device_map_1, mHandler);
+        final CpuWakeupStats obj = new CpuWakeupStats(sContext, R.xml.irq_device_map_3, mHandler);
         final long retention = obj.mConfig.WAKEUP_STATS_RETENTION_MS;
 
         final Set<Long> timestamps = new HashSet<>();
         final long firstWakeup = 453192;
 
-        obj.noteWakeupTimeAndReason(firstWakeup, 32, KERNEL_REASON_UNKNOWN_IRQ);
+        // Reasons do not matter for this test, as long as they map to known subsystems
+        obj.noteWakeupTimeAndReason(firstWakeup, 32, KERNEL_REASON_ALARM_IRQ);
         timestamps.add(firstWakeup);
         for (int i = 1; i < 1000; i++) {
             final long delta = mRandom.nextLong(retention);
             if (timestamps.add(firstWakeup + delta)) {
-                obj.noteWakeupTimeAndReason(firstWakeup + delta, i, KERNEL_REASON_UNKNOWN_IRQ);
+                obj.noteWakeupTimeAndReason(firstWakeup + delta, i, KERNEL_REASON_SENSOR_IRQ);
             }
         }
         assertThat(obj.mWakeupEvents.size()).isEqualTo(timestamps.size());
 
-        obj.noteWakeupTimeAndReason(firstWakeup + retention + 1242, 231,
-                KERNEL_REASON_UNKNOWN_IRQ);
+        obj.noteWakeupTimeAndReason(firstWakeup + retention, 231, KERNEL_REASON_WIFI_IRQ);
         assertThat(obj.mWakeupEvents.size()).isEqualTo(timestamps.size());
 
         for (int i = 0; i < 100; i++) {
             final long now = mRandom.nextLong(retention + 1, 100 * retention);
-            obj.noteWakeupTimeAndReason(now, i, KERNEL_REASON_UNKNOWN_IRQ);
+            obj.noteWakeupTimeAndReason(now, i, KERNEL_REASON_SOUND_TRIGGER_IRQ);
             assertThat(obj.mWakeupEvents.closestIndexOnOrBefore(now - retention)).isLessThan(0);
         }
     }
@@ -201,9 +198,9 @@
 
         // Outside the window, so should be ignored.
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_ALARM,
-                wakeupTime - WAKEUP_REASON_HALF_WINDOW_MS - 1, TEST_UID_1);
+                wakeupTime - obj.mConfig.WAKEUP_MATCHING_WINDOW_MS - 1, TEST_UID_1);
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_ALARM,
-                wakeupTime + WAKEUP_REASON_HALF_WINDOW_MS + 1, TEST_UID_2);
+                wakeupTime + obj.mConfig.WAKEUP_MATCHING_WINDOW_MS + 1, TEST_UID_2);
         // Should be attributed
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_ALARM, wakeupTime + 5, TEST_UID_3, TEST_UID_5);
 
@@ -234,9 +231,9 @@
 
         // Outside the window, so should be ignored.
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_SOUND_TRIGGER,
-                wakeupTime - WAKEUP_REASON_HALF_WINDOW_MS - 1, TEST_UID_1);
+                wakeupTime - obj.mConfig.WAKEUP_MATCHING_WINDOW_MS - 1, TEST_UID_1);
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_SOUND_TRIGGER,
-                wakeupTime + WAKEUP_REASON_HALF_WINDOW_MS + 1, TEST_UID_2);
+                wakeupTime + obj.mConfig.WAKEUP_MATCHING_WINDOW_MS + 1, TEST_UID_2);
         // Should be attributed
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_SOUND_TRIGGER, wakeupTime + 5, TEST_UID_3,
                 TEST_UID_5);
@@ -268,9 +265,9 @@
 
         // Outside the window, so should be ignored.
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_WIFI,
-                wakeupTime - WAKEUP_REASON_HALF_WINDOW_MS - 1, TEST_UID_1);
+                wakeupTime - obj.mConfig.WAKEUP_MATCHING_WINDOW_MS - 1, TEST_UID_1);
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_WIFI,
-                wakeupTime + WAKEUP_REASON_HALF_WINDOW_MS + 1, TEST_UID_2);
+                wakeupTime + obj.mConfig.WAKEUP_MATCHING_WINDOW_MS + 1, TEST_UID_2);
         // Should be attributed
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_WIFI, wakeupTime + 3, TEST_UID_4, TEST_UID_5);
 
@@ -300,9 +297,9 @@
         // Alarm activity
         // Outside the window, so should be ignored.
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_ALARM,
-                wakeupTime - WAKEUP_REASON_HALF_WINDOW_MS - 1, TEST_UID_1);
+                wakeupTime - obj.mConfig.WAKEUP_MATCHING_WINDOW_MS - 1, TEST_UID_1);
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_ALARM,
-                wakeupTime + WAKEUP_REASON_HALF_WINDOW_MS + 1, TEST_UID_2);
+                wakeupTime + obj.mConfig.WAKEUP_MATCHING_WINDOW_MS + 1, TEST_UID_2);
         // Should be attributed
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_ALARM, wakeupTime + 5, TEST_UID_3);
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_ALARM, wakeupTime - 3, TEST_UID_4,
@@ -311,9 +308,9 @@
         // Wifi activity
         // Outside the window, so should be ignored.
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_WIFI,
-                wakeupTime - WAKEUP_REASON_HALF_WINDOW_MS - 1, TEST_UID_4);
+                wakeupTime - obj.mConfig.WAKEUP_MATCHING_WINDOW_MS - 1, TEST_UID_4);
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_WIFI,
-                wakeupTime + WAKEUP_REASON_HALF_WINDOW_MS + 1, TEST_UID_3);
+                wakeupTime + obj.mConfig.WAKEUP_MATCHING_WINDOW_MS + 1, TEST_UID_3);
         // Should be attributed
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_WIFI, wakeupTime + 2, TEST_UID_1);
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_WIFI, wakeupTime - 1, TEST_UID_2,
@@ -347,33 +344,67 @@
     }
 
     @Test
-    public void unknownIrqAttribution() {
+    public void unknownIrqSoloIgnored() {
         final CpuWakeupStats obj = new CpuWakeupStats(sContext, R.xml.irq_device_map_3, mHandler);
         final long wakeupTime = 92123410;
 
         obj.noteWakeupTimeAndReason(wakeupTime, 24, KERNEL_REASON_UNKNOWN_IRQ);
 
-        assertThat(obj.mWakeupEvents.size()).isEqualTo(1);
+        assertThat(obj.mWakeupEvents.size()).isEqualTo(0);
 
-        // Unrelated subsystems, should not be attributed
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_ALARM, wakeupTime + 5, TEST_UID_3);
         obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_WIFI, wakeupTime - 3, TEST_UID_4,
                 TEST_UID_5);
 
-        final SparseArray<SparseIntArray> attribution = obj.mWakeupAttribution.get(wakeupTime);
-        assertThat(attribution).isNotNull();
-        assertThat(attribution.size()).isEqualTo(1);
-        assertThat(attribution.contains(CPU_WAKEUP_SUBSYSTEM_UNKNOWN)).isTrue();
-        final SparseIntArray uidProcStates = attribution.get(CPU_WAKEUP_SUBSYSTEM_UNKNOWN);
-        assertThat(uidProcStates == null || uidProcStates.size() == 0).isTrue();
+        // Any nearby activity should not end up in the attribution map.
+        assertThat(obj.mWakeupAttribution.size()).isEqualTo(0);
     }
 
     @Test
-    public void unknownWakeupIgnored() {
+    public void unknownAndWifiAttribution() {
+        final CpuWakeupStats obj = new CpuWakeupStats(sContext, R.xml.irq_device_map_3, mHandler);
+        final long wakeupTime = 92123410;
+
+        populateDefaultProcStates(obj);
+
+        obj.noteWakeupTimeAndReason(wakeupTime, 24,
+                KERNEL_REASON_UNKNOWN_IRQ + ":" + KERNEL_REASON_WIFI_IRQ);
+
+        // Wifi activity
+        // Outside the window, so should be ignored.
+        obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_WIFI,
+                wakeupTime - obj.mConfig.WAKEUP_MATCHING_WINDOW_MS - 1, TEST_UID_4);
+        // Should be attributed
+        obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_WIFI, wakeupTime + 2, TEST_UID_1);
+        obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_WIFI, wakeupTime - 1, TEST_UID_3,
+                TEST_UID_5);
+
+        // Unrelated, should be ignored.
+        obj.noteWakingActivity(CPU_WAKEUP_SUBSYSTEM_ALARM, wakeupTime + 5, TEST_UID_3);
+
+        final SparseArray<SparseIntArray> attribution = obj.mWakeupAttribution.get(wakeupTime);
+        assertThat(attribution).isNotNull();
+        assertThat(attribution.size()).isEqualTo(2);
+        assertThat(attribution.contains(CPU_WAKEUP_SUBSYSTEM_WIFI)).isTrue();
+        assertThat(attribution.get(CPU_WAKEUP_SUBSYSTEM_WIFI).get(TEST_UID_1)).isEqualTo(
+                TEST_PROC_STATE_1);
+        assertThat(attribution.get(CPU_WAKEUP_SUBSYSTEM_WIFI).indexOfKey(TEST_UID_2)).isLessThan(0);
+        assertThat(attribution.get(CPU_WAKEUP_SUBSYSTEM_WIFI).get(TEST_UID_3)).isEqualTo(
+                TEST_PROC_STATE_3);
+        assertThat(attribution.get(CPU_WAKEUP_SUBSYSTEM_WIFI).indexOfKey(TEST_UID_4)).isLessThan(0);
+        assertThat(attribution.get(CPU_WAKEUP_SUBSYSTEM_WIFI).get(TEST_UID_5)).isEqualTo(
+                TEST_PROC_STATE_5);
+        assertThat(attribution.contains(CPU_WAKEUP_SUBSYSTEM_UNKNOWN)).isTrue();
+        assertThat(attribution.get(CPU_WAKEUP_SUBSYSTEM_UNKNOWN)).isNull();
+        assertThat(attribution.contains(CPU_WAKEUP_SUBSYSTEM_ALARM)).isFalse();
+    }
+
+    @Test
+    public void unknownFormatWakeupIgnored() {
         final CpuWakeupStats obj = new CpuWakeupStats(sContext, R.xml.irq_device_map_3, mHandler);
         final long wakeupTime = 72123210;
 
-        obj.noteWakeupTimeAndReason(wakeupTime, 34, KERNEL_REASON_UNKNOWN);
+        obj.noteWakeupTimeAndReason(wakeupTime, 34, KERNEL_REASON_UNKNOWN_FORMAT);
 
         // Should be ignored as this type of wakeup is not known.
         assertThat(obj.mWakeupEvents.size()).isEqualTo(0);
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/wakeups/WakingActivityHistoryTest.java b/services/tests/servicestests/src/com/android/server/power/stats/wakeups/WakingActivityHistoryTest.java
index cba7dbe..b02618e 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/wakeups/WakingActivityHistoryTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/stats/wakeups/WakingActivityHistoryTest.java
@@ -28,8 +28,11 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.concurrent.ThreadLocalRandom;
+
 @RunWith(AndroidJUnit4.class)
 public class WakingActivityHistoryTest {
+    private volatile long mTestRetention = 54;
 
     private static boolean areSame(SparseIntArray a, SparseIntArray b) {
         if (a == b) {
@@ -55,7 +58,7 @@
 
     @Test
     public void recordActivityAppendsUids() {
-        final WakingActivityHistory history = new WakingActivityHistory();
+        final WakingActivityHistory history = new WakingActivityHistory(() -> Long.MAX_VALUE);
         final int subsystem = 42;
         final long timestamp = 54;
 
@@ -100,7 +103,7 @@
 
     @Test
     public void recordActivityDoesNotDeleteExistingUids() {
-        final WakingActivityHistory history = new WakingActivityHistory();
+        final WakingActivityHistory history = new WakingActivityHistory(() -> Long.MAX_VALUE);
         final int subsystem = 42;
         long timestamp = 101;
 
@@ -151,4 +154,120 @@
         assertThat(recordedUids.get(62, -1)).isEqualTo(31);
         assertThat(recordedUids.get(85, -1)).isEqualTo(39);
     }
+
+    @Test
+    public void removeBetween() {
+        final WakingActivityHistory history = new WakingActivityHistory(() -> Long.MAX_VALUE);
+
+        final int subsystem = 43;
+
+        final SparseIntArray uids = new SparseIntArray();
+        uids.put(1, 17);
+        uids.put(15, 2);
+        uids.put(62, 31);
+        history.recordActivity(subsystem, 123, uids);
+
+        uids.put(54, 91);
+        history.recordActivity(subsystem, 150, uids);
+
+        uids.put(101, 32);
+        uids.delete(1);
+        history.recordActivity(subsystem, 191, uids);
+
+        SparseIntArray removedUids = history.removeBetween(subsystem, 100, 122);
+        assertThat(removedUids).isNull();
+        assertThat(history.mWakingActivity.get(subsystem).size()).isEqualTo(3);
+
+        removedUids = history.removeBetween(subsystem, 124, 149);
+        assertThat(removedUids).isNull();
+        assertThat(history.mWakingActivity.get(subsystem).size()).isEqualTo(3);
+
+        removedUids = history.removeBetween(subsystem, 151, 190);
+        assertThat(removedUids).isNull();
+        assertThat(history.mWakingActivity.get(subsystem).size()).isEqualTo(3);
+
+        removedUids = history.removeBetween(subsystem, 192, 240);
+        assertThat(removedUids).isNull();
+        assertThat(history.mWakingActivity.get(subsystem).size()).isEqualTo(3);
+
+
+        // Removing from a different subsystem should do nothing.
+        removedUids = history.removeBetween(subsystem + 1, 0, 300);
+        assertThat(removedUids).isNull();
+        assertThat(history.mWakingActivity.get(subsystem).size()).isEqualTo(3);
+
+        removedUids = history.removeBetween(subsystem, 0, 300);
+        assertThat(removedUids.size()).isEqualTo(5);
+        assertThat(removedUids.get(1, -1)).isEqualTo(17);
+        assertThat(removedUids.get(15, -1)).isEqualTo(2);
+        assertThat(removedUids.get(62, -1)).isEqualTo(31);
+        assertThat(removedUids.get(54, -1)).isEqualTo(91);
+        assertThat(removedUids.get(101, -1)).isEqualTo(32);
+
+        assertThat(history.mWakingActivity.get(subsystem).size()).isEqualTo(0);
+
+        history.recordActivity(subsystem, 23, uids);
+        uids.put(31, 123);
+        history.recordActivity(subsystem, 49, uids);
+        uids.put(177, 432);
+        history.recordActivity(subsystem, 89, uids);
+
+        removedUids = history.removeBetween(subsystem, 23, 23);
+        assertThat(removedUids.size()).isEqualTo(4);
+        assertThat(removedUids.get(15, -1)).isEqualTo(2);
+        assertThat(removedUids.get(62, -1)).isEqualTo(31);
+        assertThat(removedUids.get(54, -1)).isEqualTo(91);
+        assertThat(removedUids.get(101, -1)).isEqualTo(32);
+
+        assertThat(history.mWakingActivity.get(subsystem).size()).isEqualTo(2);
+
+        removedUids = history.removeBetween(subsystem, 49, 54);
+        assertThat(removedUids.size()).isEqualTo(5);
+        assertThat(removedUids.get(15, -1)).isEqualTo(2);
+        assertThat(removedUids.get(62, -1)).isEqualTo(31);
+        assertThat(removedUids.get(54, -1)).isEqualTo(91);
+        assertThat(removedUids.get(101, -1)).isEqualTo(32);
+        assertThat(removedUids.get(31, -1)).isEqualTo(123);
+
+        assertThat(history.mWakingActivity.get(subsystem).size()).isEqualTo(1);
+
+        removedUids = history.removeBetween(subsystem, 23, 89);
+        assertThat(removedUids.size()).isEqualTo(6);
+        assertThat(removedUids.get(15, -1)).isEqualTo(2);
+        assertThat(removedUids.get(62, -1)).isEqualTo(31);
+        assertThat(removedUids.get(54, -1)).isEqualTo(91);
+        assertThat(removedUids.get(101, -1)).isEqualTo(32);
+        assertThat(removedUids.get(31, -1)).isEqualTo(123);
+        assertThat(removedUids.get(177, -1)).isEqualTo(432);
+
+        assertThat(history.mWakingActivity.get(subsystem).size()).isEqualTo(0);
+    }
+
+    @Test
+    public void deletesActivityPastRetention() {
+        final WakingActivityHistory history = new WakingActivityHistory(() -> mTestRetention);
+        final int subsystem = 49;
+
+        mTestRetention = 454;
+
+        final long firstTime = 342;
+        for (int i = 0; i < mTestRetention; i++) {
+            history.recordActivity(subsystem, firstTime + i, new SparseIntArray());
+        }
+        assertThat(history.mWakingActivity.get(subsystem)).isNotNull();
+        assertThat(history.mWakingActivity.get(subsystem).size()).isEqualTo(mTestRetention);
+
+        history.recordActivity(subsystem, firstTime + mTestRetention + 7, new SparseIntArray());
+        assertThat(history.mWakingActivity.get(subsystem).size()).isEqualTo(mTestRetention - 7);
+
+        final ThreadLocalRandom random = ThreadLocalRandom.current();
+
+        for (int i = 0; i < 100; i++) {
+            final long time = random.nextLong(firstTime + mTestRetention + 100,
+                    456 * mTestRetention);
+            history.recordActivity(subsystem, time, new SparseIntArray());
+            assertThat(history.mWakingActivity.get(subsystem).closestIndexOnOrBefore(
+                    time - mTestRetention)).isLessThan(0);
+        }
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 025315e..9166b3d 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -2194,6 +2194,7 @@
                 any(), anyString(), anyInt(), anyString(), anyInt()))
                 .thenReturn(SHOW_IMMEDIATELY);
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
         final NotificationRecord child = generateNotificationRecord(
@@ -2220,6 +2221,7 @@
                 any(), anyString(), anyInt(), anyString(), anyInt()))
                 .thenReturn(SHOW_IMMEDIATELY);
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
         parent.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
@@ -2243,6 +2245,7 @@
     public void testCancelNotificationWithTag_fromApp_canCancelOngoingNoClearChild()
             throws Exception {
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
         final NotificationRecord child = generateNotificationRecord(
@@ -2266,6 +2269,7 @@
     public void testCancelNotificationWithTag_fromApp_canCancelOngoingNoClearParent()
             throws Exception {
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
         parent.getNotification().flags |= FLAG_ONGOING_EVENT | FLAG_NO_CLEAR;
@@ -2292,6 +2296,7 @@
                 any(), anyString(), anyInt(), anyString(), anyInt()))
                 .thenReturn(SHOW_IMMEDIATELY);
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
         final NotificationRecord child = generateNotificationRecord(
@@ -2320,6 +2325,7 @@
                 any(), anyString(), anyInt(), anyString(), anyInt()))
                 .thenReturn(SHOW_IMMEDIATELY);
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
         parent.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
@@ -2345,6 +2351,7 @@
     public void testCancelAllNotifications_fromApp_canCancelOngoingNoClearChild()
             throws Exception {
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
         final NotificationRecord child = generateNotificationRecord(
@@ -2370,6 +2377,7 @@
     public void testCancelAllNotifications_fromApp_canCancelOngoingNoClearParent()
             throws Exception {
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
         parent.getNotification().flags |= FLAG_ONGOING_EVENT | FLAG_NO_CLEAR;
@@ -3209,7 +3217,7 @@
                 eq(channel2.getId()), anyBoolean()))
                 .thenReturn(channel2);
         when(mPreferencesHelper.createNotificationChannel(eq(PKG), anyInt(),
-                eq(channel2), anyBoolean(), anyBoolean()))
+                eq(channel2), anyBoolean(), anyBoolean(), anyInt(), anyBoolean()))
                 .thenReturn(true);
 
         reset(mListeners);
@@ -3268,7 +3276,7 @@
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
                 .thenReturn(mTestNotificationChannel);
         when(mPreferencesHelper.deleteNotificationChannel(eq(PKG), anyInt(),
-                eq(mTestNotificationChannel.getId()))).thenReturn(true);
+                eq(mTestNotificationChannel.getId()),  anyInt(), anyBoolean())).thenReturn(true);
         reset(mListeners);
         mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
         verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
@@ -3367,7 +3375,7 @@
                 null, PKG, Process.myUserHandle(), mTestNotificationChannel);
 
         verify(mPreferencesHelper, times(1)).updateNotificationChannel(
-                anyString(), anyInt(), any(), anyBoolean());
+                anyString(), anyInt(), any(), anyBoolean(),  anyInt(), anyBoolean());
 
         verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
@@ -3389,7 +3397,7 @@
         }
 
         verify(mPreferencesHelper, never()).updateNotificationChannel(
-                anyString(), anyInt(), any(), anyBoolean());
+                anyString(), anyInt(), any(), anyBoolean(),  anyInt(), anyBoolean());
 
         verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
@@ -3415,7 +3423,7 @@
         }
 
         verify(mPreferencesHelper, never()).updateNotificationChannel(
-                anyString(), anyInt(), any(), anyBoolean());
+                anyString(), anyInt(), any(), anyBoolean(),  anyInt(), anyBoolean());
 
         verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
@@ -4895,7 +4903,8 @@
         mService.mLocaleChangeReceiver.onReceive(mContext,
                 new Intent(Intent.ACTION_LOCALE_CHANGED));
 
-        verify(mZenModeHelper, times(1)).updateDefaultZenRules();
+        verify(mZenModeHelper, times(1)).updateDefaultZenRules(
+                anyInt(), anyBoolean());
     }
 
     @Test
@@ -5609,6 +5618,26 @@
     }
 
     @Test
+    public void testVisitUris_publicVersion() throws Exception {
+        final Icon smallIconPublic = Icon.createWithContentUri("content://media/small/icon");
+        final Icon largeIconPrivate = Icon.createWithContentUri("content://media/large/icon");
+
+        Notification publicVersion = new Notification.Builder(mContext, "a")
+                .setContentTitle("notification with uris")
+                .setSmallIcon(smallIconPublic)
+                .build();
+        Notification n = new Notification.Builder(mContext, "a")
+                .setLargeIcon(largeIconPrivate)
+                .setPublicVersion(publicVersion)
+                .build();
+
+        Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
+        n.visitUris(visitor);
+        verify(visitor, times(1)).accept(eq(smallIconPublic.getUri()));
+        verify(visitor, times(1)).accept(eq(largeIconPrivate.getUri()));
+    }
+
+    @Test
     public void testVisitUris_audioContentsString() throws Exception {
         final Uri audioContents = Uri.parse("content://com.example/audio");
 
@@ -6759,6 +6788,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(true);
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
@@ -6781,6 +6811,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(true);
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
@@ -6800,6 +6831,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(true);
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
@@ -6829,6 +6861,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(false); // rate limit reached
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
@@ -6852,6 +6885,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(true);
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
@@ -6886,6 +6920,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(true);
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
@@ -6905,6 +6940,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(true);
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
@@ -6924,6 +6960,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(true);
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
@@ -6954,6 +6991,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(false); // rate limit reached
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
         setAppInForegroundForToasts(mUid, false);
@@ -6976,6 +7014,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(false); // rate limit reached
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
         setAppInForegroundForToasts(mUid, true);
@@ -6997,6 +7036,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(false); // rate limit reached
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, true);
         setAppInForegroundForToasts(mUid, false);
@@ -7018,6 +7058,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(false); // rate limit reached
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
         setAppInForegroundForToasts(mUid, false);
@@ -7076,6 +7117,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(true);
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
@@ -7097,6 +7139,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(true);
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
@@ -7200,6 +7243,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(true);
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
         mockIsUserVisible(DEFAULT_DISPLAY, false);
@@ -7220,6 +7264,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(true);
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
@@ -7242,6 +7287,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(true);
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
@@ -7286,6 +7332,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(true);
         setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
 
@@ -8177,7 +8224,8 @@
         mBinderService.addAutomaticZenRule(rule, "com.android.settings");
 
         // verify that zen mode helper gets passed in a package name of "android"
-        verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), anyString());
+        verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), anyString(),
+                anyInt(), eq(true)); // system call counts as "is system or system ui"
     }
 
     @Test
@@ -8198,7 +8246,8 @@
         mBinderService.addAutomaticZenRule(rule, "com.android.settings");
 
         // verify that zen mode helper gets passed in a package name of "android"
-        verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), anyString());
+        verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), anyString(),
+                anyInt(),  eq(true));  // system call counts as "system or system ui"
     }
 
     @Test
@@ -8218,7 +8267,8 @@
 
         // verify that zen mode helper gets passed in the package name from the arg, not the owner
         verify(mockZenModeHelper).addAutomaticZenRule(
-                eq("another.package"), eq(rule), anyString());
+                eq("another.package"), eq(rule), anyString(), anyInt(),
+                eq(false));  // doesn't count as a system/systemui call
     }
 
     @Test
@@ -10037,8 +10087,9 @@
 
     @Test
     public void testMatchesCallFilter_noPermissionShouldThrow() throws Exception {
-        // set the testable NMS to not system uid
+        // set the testable NMS to not system uid/appid
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
 
         // make sure a caller without listener access or read_contacts permission can't call
         // matchesCallFilter.
@@ -10077,6 +10128,7 @@
     @Test
     public void testMatchesCallFilter_hasListenerPermission() throws Exception {
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
 
         // make sure a caller with only listener access and not read_contacts permission can call
         // matchesCallFilter.
@@ -10095,6 +10147,7 @@
     @Test
     public void testMatchesCallFilter_hasContactsPermission() throws Exception {
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
 
         // make sure a caller with only read_contacts permission and not listener access can call
         // matchesCallFilter.
@@ -11225,6 +11278,7 @@
         when(mJsi.isNotificationAssociatedWithAnyUserInitiatedJobs(anyInt(), anyInt(), anyString()))
                 .thenReturn(true);
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
         final NotificationRecord child = generateNotificationRecord(
@@ -11249,6 +11303,7 @@
         when(mJsi.isNotificationAssociatedWithAnyUserInitiatedJobs(anyInt(), anyInt(), anyString()))
                 .thenReturn(true);
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
         parent.getNotification().flags |= FLAG_USER_INITIATED_JOB;
@@ -11273,6 +11328,7 @@
         when(mJsi.isNotificationAssociatedWithAnyUserInitiatedJobs(anyInt(), anyInt(), anyString()))
                 .thenReturn(true);
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
         final NotificationRecord child = generateNotificationRecord(
@@ -11299,6 +11355,7 @@
         when(mJsi.isNotificationAssociatedWithAnyUserInitiatedJobs(anyInt(), anyInt(), anyString()))
                 .thenReturn(true);
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
         parent.getNotification().flags |= FLAG_USER_INITIATED_JOB;
@@ -11722,6 +11779,7 @@
     private void allowTestPackageToToast() throws Exception {
         assertWithMessage("toast queue").that(mService.mToastQueue).isEmpty();
         mService.isSystemUid = false;
+        mService.isSystemAppId = false;
         setToastRateIsWithinQuota(true);
         setIfPackageHasPermissionToAvoidToastRateLimiting(TEST_PACKAGE, false);
         // package is not suspended
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java
index 27677e1..4c10ddc 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java
@@ -87,8 +87,6 @@
     // This list should be emptied! Items can be removed as bugs are fixed.
     private static final Multimap<Class<?>, String> KNOWN_BAD =
             ImmutableMultimap.<Class<?>, String>builder()
-                    .put(Notification.Builder.class, "setPublicVersion") // b/276294099
-                    .putAll(RemoteViews.class, "addView", "addStableView") // b/277740082
                     .put(RemoteViews.class, "setIcon") // b/281018094
                     .put(Notification.WearableExtender.class, "addAction") // TODO: b/281044385
                     .put(Person.Builder.class, "setUri") // TODO: b/281044385
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index c78b03e..48ad86d 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -60,6 +60,7 @@
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
@@ -421,13 +422,15 @@
         int uid0 = 1001;
         setUpPackageWithUid(package0, uid0);
         NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
-        assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
+        assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false,
+                uid0, false));
 
         String package10 = "test.package.user10";
         int uid10 = 1001001;
         setUpPackageWithUid(package10, uid10);
         NotificationChannel channel10 = new NotificationChannel("id10", "name10", IMPORTANCE_HIGH);
-        assertTrue(mHelper.createNotificationChannel(package10, uid10, channel10, true, false));
+        assertTrue(mHelper.createNotificationChannel(package10, uid10, channel10, true, false,
+                uid10, false));
 
         ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
         appPermissions.put(new Pair<>(uid0, package0), new Pair<>(false, false));
@@ -459,7 +462,8 @@
         int uid0 = 1001;
         setUpPackageWithUid(package0, uid0);
         NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
-        assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
+        assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false,
+                uid0, false));
 
         ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
         appPermissions.put(new Pair<>(uid0, package0), new Pair<>(true, false));
@@ -506,10 +510,14 @@
         channel2.setConversationId("id1", "conversation");
         channel2.setDemoted(true);
 
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
-        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false));
-        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false));
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+                UID_N_MR1, false);
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+                UID_N_MR1, false));
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
+                UID_N_MR1, false));
 
         mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
 
@@ -569,12 +577,18 @@
         NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
         channel3.enableVibration(true);
 
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
-        mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
+                SYSTEM_UID, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false,
+                SYSTEM_UID, true);
+        mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false,
+                UID_N_MR1, false);
 
         mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
         mHelper.setInvalidMessageSent(PKG_P, UID_P);
@@ -1040,12 +1054,18 @@
         NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
         channel3.enableVibration(true);
 
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
-        mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
+                SYSTEM_UID, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false,
+                SYSTEM_UID, true);
+        mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false,
+                UID_N_MR1, false);
 
         mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
         mHelper.setInvalidMessageSent(PKG_P, UID_P);
@@ -1120,12 +1140,18 @@
         NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
         channel3.enableVibration(true);
 
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
-        mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
+                SYSTEM_UID, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false,
+                SYSTEM_UID, true);
+        mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false,
+                UID_N_MR1, false);
 
         mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
         mHelper.setInvalidMessageSent(PKG_P, UID_P);
@@ -1202,12 +1228,18 @@
         NotificationChannel channel3 = new NotificationChannel("id3", "NAM3", IMPORTANCE_HIGH);
         channel3.enableVibration(true);
 
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
-        mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
+                SYSTEM_UID, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false,
+                SYSTEM_UID, true);
+        mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false,
+                UID_N_MR1, false);
 
         mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
         mHelper.setInvalidMessageSent(PKG_P, UID_P);
@@ -1285,7 +1317,8 @@
         NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_LOW);
         channel.setSound(SOUND_URI, mAudioAttributes);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
 
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
                 USER_SYSTEM, channel.getId());
@@ -1312,7 +1345,8 @@
         NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_LOW);
         channel.setSound(SOUND_URI, mAudioAttributes);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
                 USER_SYSTEM, channel.getId());
 
@@ -1334,7 +1368,8 @@
         NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_LOW);
         channel.setSound(SOUND_URI, mAudioAttributes);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
                 USER_SYSTEM, channel.getId());
 
@@ -1359,7 +1394,8 @@
         NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_LOW);
         channel.setSound(SOUND_URI, mAudioAttributes);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
                 USER_SYSTEM, channel.getId());
 
@@ -1437,7 +1473,8 @@
         NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_LOW);
         channel.setSound(null, mAudioAttributes);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
                 USER_SYSTEM, channel.getId());
 
@@ -1466,7 +1503,8 @@
         NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_LOW);
         channel.setSound(ANDROID_RES_SOUND_URI, mAudioAttributes);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
                 USER_SYSTEM, channel.getId());
 
@@ -1501,7 +1539,8 @@
         NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_LOW);
         channel.setSound(FILE_SOUND_URI, mAudioAttributes);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, true,
                 USER_SYSTEM, channel.getId());
 
@@ -1527,14 +1566,21 @@
                 new NotificationChannel("id3", "name3", IMPORTANCE_LOW);
         channel3.setGroup(ncg.getId());
 
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
+                SYSTEM_UID, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false,
+                UID_N_MR1, false);
 
-        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId());
-        mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg.getId());
+        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(),
+                UID_N_MR1, false);
+        mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg.getId(),
+                UID_N_MR1, false);
         assertEquals(channel2,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
 
@@ -1578,7 +1624,8 @@
                 UID_N_MR1,
                 NotificationChannel.DEFAULT_CHANNEL_ID, false);
         defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true,
+                UID_N_MR1, false);
 
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
                 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID);
@@ -1641,7 +1688,8 @@
     @Test
     public void testDeletesDefaultChannelAfterChannelIsCreated() throws Exception {
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
-                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
+                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false,
+                UID_N_MR1, false);
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
                 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
 
@@ -1661,7 +1709,8 @@
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
                 UserHandle.USER_ALL, NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
-                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
+                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false,
+                UID_N_MR1, false);
 
         loadStreamXml(baos, false, UserHandle.USER_ALL);
 
@@ -1674,7 +1723,7 @@
         try {
             mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
                     new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE - 1),
-                    true, false);
+                    true, false, UID_N_MR1, false);
             fail("Was allowed to create a channel with invalid importance");
         } catch (IllegalArgumentException e) {
             // yay
@@ -1682,7 +1731,7 @@
         try {
             mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
                     new NotificationChannel("bananas", "bananas", IMPORTANCE_UNSPECIFIED),
-                    true, false);
+                    true, false, UID_N_MR1, false);
             fail("Was allowed to create a channel with invalid importance");
         } catch (IllegalArgumentException e) {
             // yay
@@ -1690,57 +1739,61 @@
         try {
             mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
                     new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1),
-                    true, false);
+                    true, false, UID_N_MR1, false);
             fail("Was allowed to create a channel with invalid importance");
         } catch (IllegalArgumentException e) {
             // yay
         }
         assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
-                new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false));
+                new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false,
+                UID_N_MR1, false));
         assertFalse(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
-                new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false));
+                new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false,
+                UID_N_MR1, false));
     }
 
     @Test
     public void testUpdateChannel_downgradeImportance() {
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
                 new NotificationChannel("bananas", "bananas", IMPORTANCE_DEFAULT),
-                true, false);
+                true, false, UID_N_MR1, false);
 
         assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
-                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false));
+                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false,
+                UID_N_MR1, false));
     }
 
     @Test
     public void testUpdateChannel_upgradeImportance_ignored() {
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
                 new NotificationChannel("bananas", "bananas", IMPORTANCE_DEFAULT),
-                true, false);
+                true, false, UID_N_MR1, false);
 
         assertFalse(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
-                new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false));
+                new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false,
+                UID_N_MR1, false));
     }
 
     @Test
     public void testUpdateChannel_badImportance() {
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
                 new NotificationChannel("bananas", "bananas", IMPORTANCE_DEFAULT),
-                true, false);
+                true, false, UID_N_MR1, false);
 
         assertThrows(IllegalArgumentException.class,
                 () -> mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
                         new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE - 1), true,
-                        false));
+                        false, UID_N_MR1, false));
 
         assertThrows(IllegalArgumentException.class,
                 () -> mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
                         new NotificationChannel("bananas", "bananas", IMPORTANCE_UNSPECIFIED), true,
-                        false));
+                        false, UID_N_MR1, false));
 
         assertThrows(IllegalArgumentException.class,
                 () -> mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
                         new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1), true,
-                        false));
+                        false, UID_N_MR1, false));
     }
 
     @Test
@@ -1753,7 +1806,8 @@
         channel.setBypassDnd(true);
         channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
 
-        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false));
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false,
+                SYSTEM_UID, true));
 
         // same id, try to update all fields
         final NotificationChannel channel2 =
@@ -1763,7 +1817,8 @@
         channel2.setBypassDnd(false);
         channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
 
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true,
+                SYSTEM_UID, true);
 
         // all fields should be changed
         assertEquals(channel2,
@@ -1788,7 +1843,8 @@
         defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
 
         mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true,
+                SYSTEM_UID, true);
 
         // ensure app level fields are changed
         assertFalse(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
@@ -1801,7 +1857,8 @@
     public void testUpdate_postUpgrade_noUpdateAppFields() throws Exception {
         final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
 
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false,
+                SYSTEM_UID, true);
         assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
         assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_O, UID_O));
         assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
@@ -1812,7 +1869,8 @@
         channel.setBypassDnd(true);
         channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
 
-        mHelper.updateNotificationChannel(PKG_O, UID_O, channel, true);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, channel, true,
+                SYSTEM_UID, true);
 
         // ensure app level fields are not changed
         assertTrue(mHelper.canShowBadge(PKG_O, UID_O));
@@ -1825,7 +1883,8 @@
     public void testUpdate_preUpgrade_noUpdateAppFieldsWithMultipleChannels() throws Exception {
         final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
 
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false,
+                SYSTEM_UID, true);
         assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
         assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
         assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
@@ -1836,7 +1895,8 @@
         channel.setBypassDnd(true);
         channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
 
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true,
+                SYSTEM_UID, true);
 
         NotificationChannel defaultChannel = mHelper.getNotificationChannel(
                 PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
@@ -1846,7 +1906,8 @@
         defaultChannel.setBypassDnd(true);
         defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
 
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, defaultChannel, true,
+                SYSTEM_UID, true);
 
         // ensure app level fields are not changed
         assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
@@ -1877,7 +1938,8 @@
         }
         channel.lockFields(lockMask);
 
-        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false));
 
         NotificationChannel savedChannel =
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
@@ -1909,7 +1971,8 @@
         }
         channel.lockFields(lockMask);
 
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
 
         NotificationChannel savedChannel =
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
@@ -1936,13 +1999,14 @@
 
     @Test
     public void testLockFields_soundAndVibration() {
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false,
+                UID_N_MR1, false);
 
         final NotificationChannel update1 = getChannel();
         update1.setSound(new Uri.Builder().scheme("test").build(),
                 new AudioAttributes.Builder().build());
         update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true, SYSTEM_UID, true);
         assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
                 | NotificationChannel.USER_LOCKED_SOUND,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
@@ -1950,7 +2014,7 @@
 
         NotificationChannel update2 = getChannel();
         update2.enableVibration(true);
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true, SYSTEM_UID, true);
         assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
                         | NotificationChannel.USER_LOCKED_SOUND
                         | NotificationChannel.USER_LOCKED_VIBRATION,
@@ -1960,18 +2024,19 @@
 
     @Test
     public void testLockFields_vibrationAndLights() {
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false,
+                SYSTEM_UID, true);
 
         final NotificationChannel update1 = getChannel();
         update1.setVibrationPattern(new long[]{7945, 46 ,246});
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true, SYSTEM_UID, true);
         assertEquals(NotificationChannel.USER_LOCKED_VIBRATION,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
                         .getUserLockedFields());
 
         final NotificationChannel update2 = getChannel();
         update2.enableLights(true);
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true, SYSTEM_UID, true);
         assertEquals(NotificationChannel.USER_LOCKED_VIBRATION
                         | NotificationChannel.USER_LOCKED_LIGHTS,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
@@ -1980,18 +2045,20 @@
 
     @Test
     public void testLockFields_lightsAndImportance() {
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false,
+                UID_N_MR1, false);
 
         final NotificationChannel update1 = getChannel();
         update1.setLightColor(Color.GREEN);
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true, SYSTEM_UID, true);
         assertEquals(NotificationChannel.USER_LOCKED_LIGHTS,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
                         .getUserLockedFields());
 
         final NotificationChannel update2 = getChannel();
         update2.setImportance(IMPORTANCE_DEFAULT);
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true,
+                SYSTEM_UID, true);
         assertEquals(NotificationChannel.USER_LOCKED_LIGHTS
                         | NotificationChannel.USER_LOCKED_IMPORTANCE,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
@@ -2000,21 +2067,22 @@
 
     @Test
     public void testLockFields_visibilityAndDndAndBadge() {
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false,
+                UID_N_MR1, false);
         assertEquals(0,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel().getId(), false)
                         .getUserLockedFields());
 
         final NotificationChannel update1 = getChannel();
         update1.setBypassDnd(true);
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update1, true, SYSTEM_UID, true);
         assertEquals(NotificationChannel.USER_LOCKED_PRIORITY,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update1.getId(), false)
                         .getUserLockedFields());
 
         final NotificationChannel update2 = getChannel();
         update2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update2, true, SYSTEM_UID, true);
         assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
                         | NotificationChannel.USER_LOCKED_VISIBILITY,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update2.getId(), false)
@@ -2022,7 +2090,7 @@
 
         final NotificationChannel update3 = getChannel();
         update3.setShowBadge(false);
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update3, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update3, true, SYSTEM_UID, true);
         assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
                         | NotificationChannel.USER_LOCKED_VISIBILITY
                         | NotificationChannel.USER_LOCKED_SHOW_BADGE,
@@ -2032,14 +2100,16 @@
 
     @Test
     public void testLockFields_allowBubble() {
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false,
+                UID_N_MR1, false);
         assertEquals(0,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel().getId(), false)
                         .getUserLockedFields());
 
         final NotificationChannel update = getChannel();
         update.setAllowBubbles(true);
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true,
+                SYSTEM_UID, true);
         assertEquals(NotificationChannel.USER_LOCKED_ALLOW_BUBBLE,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update.getId(), false)
                         .getUserLockedFields());
@@ -2047,15 +2117,19 @@
 
     @Test
     public void testDeleteNonExistentChannel() throws Exception {
-        mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, "does not exist");
+        mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, "does not exist",
+                UID_N_MR1, false);
     }
 
     @Test
     public void testDoubleDeleteChannel() throws Exception {
         NotificationChannel channel = getChannel();
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
-        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
-        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
+        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(),
+                UID_N_MR1, false);
+        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(),
+                UID_N_MR1, false);
         assertEquals(2, mLogger.getCalls().size());
         assertEquals(
                 NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_CREATED,
@@ -2076,8 +2150,10 @@
         channel.enableVibration(true);
         channel.setVibrationPattern(new long[]{100, 67, 145, 156});
 
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
-        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
+        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(),
+                UID_N_MR1, false);
 
         // Does not return deleted channel
         NotificationChannel response =
@@ -2105,10 +2181,13 @@
         NotificationChannel channel2 =
                 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
         channelMap.put(channel2.getId(), channel2);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false,
+                UID_N_MR1, false);
 
-        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
+        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(),
+                UID_N_MR1, false);
 
         // Returns only non-deleted channels
         List<NotificationChannel> channels =
@@ -2138,12 +2217,17 @@
                 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
         NotificationChannel channel3 =
                 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false,
+                UID_N_MR1, false);
 
-        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
-        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId());
+        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(),
+                UID_N_MR1, false);
+        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(),
+                UID_N_MR1, false);
 
         assertEquals(2, mHelper.getDeletedChannelCount(PKG_N_MR1, UID_N_MR1));
         assertEquals(0, mHelper.getDeletedChannelCount("pkg2", UID_O));
@@ -2157,11 +2241,15 @@
                 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_NONE);
         NotificationChannel channel3 =
                 new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_NONE);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false,
+                UID_N_MR1, false);
 
-        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId());
+        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(),
+                UID_N_MR1, false);
 
         assertEquals(1, mHelper.getBlockedChannelCount(PKG_N_MR1, UID_N_MR1));
         assertEquals(0, mHelper.getBlockedChannelCount("pkg2", UID_O));
@@ -2180,7 +2268,8 @@
         NotificationChannel channel = new NotificationChannel("id", "name",
                 NotificationManager.IMPORTANCE_MAX);
         channel.setBypassDnd(true);
-        mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, 111, channel, true, true,
+                111, false);
 
         assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
                 uid).getList().size());
@@ -2194,15 +2283,18 @@
                 NotificationManager.IMPORTANCE_MAX);
         channel1.setBypassDnd(true);
         channel1.setGroup(ncg.getId());
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, ncg,  /* fromTargetApp */ true);
-        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel1, true, /*has DND access*/ true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, ncg,  /* fromTargetApp */ true,
+                uid, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel1, true, /*has DND access*/ true,
+                uid, false);
 
         assertEquals(1, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
                 uid).getList().size());
 
         // disable group
         ncg.setBlocked(true);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, ncg,  /* fromTargetApp */ false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, ncg,  /* fromTargetApp */ false,
+                SYSTEM_UID, true);
         assertEquals(0, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
                 uid).getList().size());
     }
@@ -2220,9 +2312,12 @@
         channel2.setBypassDnd(true);
         channel3.setBypassDnd(true);
         // has DND access, so can set bypassDnd attribute
-        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel1, true, /*has DND access*/ true);
-        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
-        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel3, true, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel1, true, /*has DND access*/ true,
+                uid, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
+                uid, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel3, true, true,
+                uid, false);
         assertEquals(3, mHelper.getNotificationChannelsBypassingDnd(PKG_N_MR1,
                 uid).getList().size());
 
@@ -2247,29 +2342,31 @@
         // expected result: areChannelsBypassingDnd = false
         // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
         NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false,
+                uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
 
         // create notification channel that can bypass dnd
         // expected result: areChannelsBypassingDnd = true
         NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel2.setBypassDnd(true);
-        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
+                uid, false);
         assertTrue(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
 
         // delete channels
-        mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel.getId());
+        mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel.getId(), uid, false);
         assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND
-        verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
 
-        mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel2.getId());
+        mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel2.getId(), uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
     }
 
@@ -2282,18 +2379,20 @@
         // expected result: areChannelsBypassingDnd = false
         // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
         NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false,
+                uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
 
         // Recreate a channel & now the app has dnd access granted and can set the bypass dnd field
         NotificationChannel update = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
         update.setBypassDnd(true);
-        mHelper.createNotificationChannel(PKG_N_MR1, uid, update, true, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, update, true, true,
+                uid, false);
 
         assertTrue(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
     }
 
@@ -2306,29 +2405,31 @@
         // expected result: areChannelsBypassingDnd = false
         // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
         NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false,
+                uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
 
         // create notification channel that can bypass dnd, using local app level settings
         // expected result: areChannelsBypassingDnd = true
         NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel2.setBypassDnd(true);
-        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
+                uid, false);
         assertTrue(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
 
         // delete channels
-        mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel.getId());
+        mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel.getId(), uid, false);
         assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND
-        verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
 
-        mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel2.getId());
+        mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel2.getId(), uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
     }
 
@@ -2350,13 +2451,16 @@
         // expected result: areChannelsBypassingDnd = false
         NotificationChannelGroup group = new NotificationChannelGroup("group", "group");
         group.setBlocked(true);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, group, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, group, false,
+                SYSTEM_UID, true);
         NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel2.setGroup("group");
         channel2.setBypassDnd(true);
-        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
+                uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(),
+                anyInt(), anyBoolean());
         resetZenModeHelper();
     }
 
@@ -2377,9 +2481,10 @@
         // expected result: areChannelsBypassingDnd = false
         NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel2.setBypassDnd(true);
-        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
+                uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
     }
 
@@ -2400,9 +2505,10 @@
         // expected result: areChannelsBypassingDnd = false
         NotificationChannel channel2 = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel2.setBypassDnd(true);
-        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
+                uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
     }
 
@@ -2415,25 +2521,26 @@
         // expected result: areChannelsBypassingDnd = false
         // setNotificationPolicy isn't called since areChannelsBypassingDnd was already false
         NotificationChannel channel = new NotificationChannel("id1", "name1", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false,
+                uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
 
         // update channel so it CAN bypass dnd:
         // expected result: areChannelsBypassingDnd = true
         channel.setBypassDnd(true);
-        mHelper.updateNotificationChannel(PKG_N_MR1, uid, channel, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, uid, channel, true, SYSTEM_UID, true);
         assertTrue(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
 
         // update channel so it can't bypass dnd:
         // expected result: areChannelsBypassingDnd = false
         channel.setBypassDnd(false);
-        mHelper.updateNotificationChannel(PKG_N_MR1, uid, channel, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, uid, channel, true, SYSTEM_UID, true);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
     }
 
@@ -2448,7 +2555,7 @@
                 mPermissionHelper, mLogger,
                 mAppOpsManager, mStatsEventBuilderFactory, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
     }
 
@@ -2461,7 +2568,7 @@
                 mPermissionHelper, mLogger,
                 mAppOpsManager, mStatsEventBuilderFactory, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
+        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
         resetZenModeHelper();
     }
 
@@ -2472,14 +2579,17 @@
                 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setVibrationPattern(vibration);
 
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
-        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId());
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
+        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(),
+                UID_N_MR1, false);
 
         NotificationChannel newChannel = new NotificationChannel(
                 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
         newChannel.setVibrationPattern(new long[]{100});
 
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel, true, false,
+                UID_N_MR1, false);
 
         // No long deleted, using old settings
         compareChannels(channel,
@@ -2491,7 +2601,8 @@
         assertTrue(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
         assertFalse(mHelper.onlyHasDefaultChannel(PKG_O, UID_O));
 
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, getChannel(), true, false,
+                UID_N_MR1, false);
         assertFalse(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
     }
 
@@ -2499,7 +2610,8 @@
     public void testCreateChannel_defaultChannelId() throws Exception {
         try {
             mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, new NotificationChannel(
-                    NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true, false);
+                    NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true, false,
+                    UID_N_MR1, false);
             fail("Allowed to create default channel");
         } catch (IllegalArgumentException e) {
             // pass
@@ -2513,7 +2625,8 @@
                 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setVibrationPattern(vibration);
 
-        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false));
 
         NotificationChannel newChannel = new NotificationChannel(
                 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
@@ -2524,7 +2637,8 @@
         newChannel.setShowBadge(!channel.canShowBadge());
 
         assertFalse(mHelper.createNotificationChannel(
-                PKG_N_MR1, UID_N_MR1, newChannel, true, false));
+                PKG_N_MR1, UID_N_MR1, newChannel, true, false,
+                UID_N_MR1, false));
 
         // Old settings not overridden
         compareChannels(channel,
@@ -2542,7 +2656,8 @@
         final NotificationChannel channel = new NotificationChannel("id2", "name2",
                  NotificationManager.IMPORTANCE_DEFAULT);
         channel.setSound(sound, mAudioAttributes);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false,
+                UID_N_MR1, false);
         assertEquals(sound, mHelper.getNotificationChannel(
                 PKG_N_MR1, UID_N_MR1, channel.getId(), false).getSound());
     }
@@ -2554,8 +2669,10 @@
         NotificationChannel channel2 =
                 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
 
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
+                UID_N_MR1, false);
 
         mHelper.permanentlyDeleteNotificationChannels(PKG_N_MR1, UID_N_MR1);
 
@@ -2576,14 +2693,20 @@
                 new NotificationChannel("deleted", "belongs to deleted", IMPORTANCE_DEFAULT);
         groupedAndDeleted.setGroup("totally");
 
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted, true,
+                UID_N_MR1, false);
         mHelper.createNotificationChannel(
-                PKG_N_MR1, UID_N_MR1, nonGroupedNonDeletedChannel, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedAndDeleted, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedButNotDeleted, true, false);
+                PKG_N_MR1, UID_N_MR1, nonGroupedNonDeletedChannel, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedAndDeleted, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, groupedButNotDeleted, true, false,
+                UID_N_MR1, false);
 
-        mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted.getId());
+        mHelper.deleteNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, deleted.getId(),
+                UID_N_MR1, false);
 
         assertNull(mHelper.getNotificationChannelGroup(deleted.getId(), PKG_N_MR1, UID_N_MR1));
         assertNotNull(
@@ -2626,10 +2749,14 @@
         convo.setGroup("not");
         convo.setConversationId("not deleted", "banana");
 
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, base, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, convo, true, false);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, base, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, convo, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, notDeleted, true,
+                UID_N_MR1, false);
 
         NotificationChannelGroup g
                 = mHelper.getNotificationChannelGroup(notDeleted.getId(), PKG_N_MR1, UID_N_MR1);
@@ -2679,7 +2806,8 @@
         // Deleted
         NotificationChannel channel1 =
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+                UID_N_MR1, false);
 
         assertTrue(mHelper.onPackagesChanged(true, USER_SYSTEM, new String[]{PKG_N_MR1},
                 new int[]{UID_N_MR1}));
@@ -2688,7 +2816,8 @@
                 PKG_N_MR1, UID_N_MR1, true).getList().size());
 
         // Not deleted
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+                UID_N_MR1, false);
 
         assertFalse(mHelper.onPackagesChanged(false, USER_SYSTEM,
                 new String[]{PKG_N_MR1}, new int[]{UID_N_MR1}));
@@ -2698,9 +2827,11 @@
     @Test
     public void testOnPackageChanged_packageRemoval_groups() throws Exception {
         NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+                UID_N_MR1, false);
         NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+                UID_N_MR1, false);
 
         mHelper.onPackagesChanged(true, USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
                 UID_N_MR1});
@@ -2712,7 +2843,8 @@
     @Test
     public void testOnPackageChange_downgradeTargetSdk() throws Exception {
         // create channel as api 26
-        mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false,
+                UID_N_MR1, false);
 
         // install new app version targeting 25
         final ApplicationInfo legacy = new ApplicationInfo();
@@ -2731,9 +2863,11 @@
     public void testClearData() {
         ArraySet<Pair<String, Integer>> pkgPair = new ArraySet<>();
         pkgPair.add(new Pair<>(PKG_O, UID_O));
-        mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false,
+                UID_O, false);
         mHelper.createNotificationChannelGroup(
-                PKG_O, UID_O, new NotificationChannelGroup("1", "bye"), true);
+                PKG_O, UID_O, new NotificationChannelGroup("1", "bye"), true,
+                UID_O, false);
         mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, pkgPair);
         mHelper.setNotificationDelegate(PKG_O, UID_O, "", 1);
         mHelper.setBubblesAllowed(PKG_O, UID_O, DEFAULT_BUBBLE_PREFERENCE);
@@ -2750,7 +2884,8 @@
         assertEquals(0, mHelper.getNotificationChannelGroups(PKG_O, UID_O).size());
 
         NotificationChannel channel = getChannel();
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false,
+                UID_O, false);
 
         assertTrue(channel.isImportanceLockedByCriticalDeviceFunction());
     }
@@ -2764,7 +2899,8 @@
     @Test
     public void testCreateGroup() {
         NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+                UID_N_MR1, false);
         assertEquals(ncg,
                 mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1).iterator().next());
         verify(mHandler, never()).requestSort();
@@ -2781,7 +2917,8 @@
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         channel1.setGroup("garbage");
         try {
-            mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+            mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+                    UID_N_MR1, false);
             fail("Created a channel with a bad group");
         } catch (IllegalArgumentException e) {
         }
@@ -2791,11 +2928,13 @@
     @Test
     public void testCannotCreateChannel_goodGroup() {
         NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+                UID_N_MR1, false);
         NotificationChannel channel1 =
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         channel1.setGroup(ncg.getId());
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+                UID_N_MR1, false);
 
         assertEquals(ncg.getId(), mHelper.getNotificationChannel(
                 PKG_N_MR1, UID_N_MR1, channel1.getId(), false).getGroup());
@@ -2804,29 +2943,36 @@
     @Test
     public void testGetChannelGroups() {
         NotificationChannelGroup unused = new NotificationChannelGroup("unused", "s");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, unused, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, unused, true,
+                UID_N_MR1, false);
         NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+                UID_N_MR1, false);
         NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true,
+                UID_N_MR1, false);
 
         NotificationChannel channel1 =
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         channel1.setGroup(ncg.getId());
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+                UID_N_MR1, false);
         NotificationChannel channel1a =
                 new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH);
         channel1a.setGroup(ncg.getId());
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1a, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1a, true, false,
+                UID_N_MR1, false);
 
         NotificationChannel channel2 =
                 new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH);
         channel2.setGroup(ncg2.getId());
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true, false,
+                UID_N_MR1, false);
 
         NotificationChannel channel3 =
                 new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false,
+                UID_N_MR1, false);
 
         List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
                 PKG_N_MR1, UID_N_MR1, true, true, false).getList();
@@ -2855,16 +3001,19 @@
     @Test
     public void testGetChannelGroups_noSideEffects() {
         NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+                UID_N_MR1, false);
 
         NotificationChannel channel1 =
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         channel1.setGroup(ncg.getId());
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+                UID_N_MR1, false);
         mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, true, true, false).getList();
 
         channel1.setImportance(IMPORTANCE_LOW);
-        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true);
+        mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true,
+                UID_N_MR1, false);
 
         List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
                 PKG_N_MR1, UID_N_MR1, true, true, false).getList();
@@ -2880,14 +3029,17 @@
     @Test
     public void testGetChannelGroups_includeEmptyGroups() {
         NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true,
+                UID_N_MR1, false);
         NotificationChannelGroup ncgEmpty = new NotificationChannelGroup("group2", "name2");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncgEmpty, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncgEmpty, true,
+                UID_N_MR1, false);
 
         NotificationChannel channel1 =
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         channel1.setGroup(ncg.getId());
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
+                UID_N_MR1, false);
 
         List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
                 PKG_N_MR1, UID_N_MR1, false, false, true).getList();
@@ -2906,13 +3058,15 @@
     @Test
     public void testCreateChannel_updateName() {
         NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
-        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false,
+                UID_N_MR1, false));
         NotificationChannel actual =
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
         assertEquals("hello", actual.getName());
 
         nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
-        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false,
+                UID_N_MR1, false));
 
         actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
         assertEquals("goodbye", actual.getName());
@@ -2924,16 +3078,19 @@
     @Test
     public void testCreateChannel_addToGroup() {
         NotificationChannelGroup group = new NotificationChannelGroup("group", "group");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true,
+                UID_N_MR1, false);
         NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
-        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false,
+                UID_N_MR1, false));
         NotificationChannel actual =
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
         assertNull(actual.getGroup());
 
         nc = new NotificationChannel("id", "hello", IMPORTANCE_HIGH);
         nc.setGroup(group.getId());
-        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false,
+                UID_N_MR1, false));
 
         actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
         assertNotNull(actual.getGroup());
@@ -2969,14 +3126,16 @@
             int numChannels = ThreadLocalRandom.current().nextInt(1, 10);
             for (int j = 0; j < numChannels; j++) {
                 mHelper.createNotificationChannel(pkgName, UID_N_MR1,
-                        new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true, false);
+                        new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true, false,
+                        UID_N_MR1, false);
             }
             expectedChannels.put(pkgName, numChannels);
         }
 
         // delete the first channel of the first package
         String pkg = expectedChannels.keyAt(0);
-        mHelper.deleteNotificationChannel("pkg" + 0, UID_N_MR1, "0");
+        mHelper.deleteNotificationChannel("pkg" + 0, UID_N_MR1, "0",
+                UID_N_MR1, false);
         // dump should not include deleted channels
         int count = expectedChannels.get(pkg);
         expectedChannels.put(pkg, count - 1);
@@ -3012,10 +3171,14 @@
                 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         NotificationChannel channel3 = new NotificationChannel("id3", "name3", IMPORTANCE_HIGH);
 
-        mHelper.createNotificationChannel(PKG_P, UID_P, channel1, true, false);
-        mHelper.createNotificationChannel(PKG_P, UID_P, channel2, false, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false);
-        mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
+        mHelper.createNotificationChannel(PKG_P, UID_P, channel1, true, false,
+                UID_P, false);
+        mHelper.createNotificationChannel(PKG_P, UID_P, channel2, false, false,
+                UID_P, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, false, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false,
+                UID_N_MR1, false);
 
         // in the json array, all of the individual package preferences are simply elements in the
         // values array. this set is to collect expected outputs for each of our packages.
@@ -3328,7 +3491,8 @@
     @Test
     public void testIsGroupBlocked_notBlocked() throws Exception {
         NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true,
+                UID_N_MR1, false);
 
         assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
     }
@@ -3336,9 +3500,11 @@
     @Test
     public void testIsGroupBlocked_blocked() throws Exception {
         NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true,
+                UID_N_MR1, false);
         group.setBlocked(true);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, false,
+                UID_N_MR1, false);
 
         assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
     }
@@ -3347,27 +3513,32 @@
     public void testIsGroupBlocked_appCannotCreateAsBlocked() throws Exception {
         NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
         group.setBlocked(true);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true,
+                UID_N_MR1, false);
         assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
 
         NotificationChannelGroup group3 = group.clone();
         group3.setBlocked(false);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true,
+                UID_N_MR1, false);
         assertFalse(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
     }
 
     @Test
     public void testIsGroup_appCannotResetBlock() throws Exception {
         NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true,
+                UID_N_MR1, false);
         NotificationChannelGroup group2 = group.clone();
         group2.setBlocked(true);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group2, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group2, false,
+                UID_N_MR1, false);
         assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
 
         NotificationChannelGroup group3 = group.clone();
         group3.setBlocked(false);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group3, true,
+                UID_N_MR1, false);
         assertTrue(mHelper.isGroupBlocked(PKG_N_MR1, UID_N_MR1, group.getId()));
     }
 
@@ -3375,8 +3546,10 @@
     public void testGetNotificationChannelGroupWithChannels() throws Exception {
         NotificationChannelGroup group = new NotificationChannelGroup("group", "group");
         NotificationChannelGroup other = new NotificationChannelGroup("something else", "name");
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
-        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, other, true);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, other, true,
+                UID_N_MR1, false);
 
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
         a.setGroup(group.getId());
@@ -3386,11 +3559,16 @@
         c.setGroup(group.getId());
         NotificationChannel d = new NotificationChannel("d", "d", IMPORTANCE_DEFAULT);
 
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, a, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, c, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, d, true, false);
-        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, c.getId());
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, a, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, c, true, false,
+                UID_N_MR1, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, d, true, false,
+                UID_N_MR1, false);
+        mHelper.deleteNotificationChannel(PKG_N_MR1, UID_N_MR1, c.getId(),
+                UID_N_MR1, false);
 
         NotificationChannelGroup retrieved = mHelper.getNotificationChannelGroupWithChannels(
                 PKG_N_MR1, UID_N_MR1, group.getId(), true);
@@ -3409,7 +3587,8 @@
         NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
         test.setBypassDnd(true);
 
-        mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
+        mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false,
+                SYSTEM_UID, true);
 
         assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
                 .canBypassDnd());
@@ -3420,7 +3599,8 @@
         NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
         test.setBypassDnd(true);
 
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true,
+                UID_N_MR1, false);
 
         assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
     }
@@ -3430,7 +3610,8 @@
         NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
         test.setBypassDnd(true);
 
-        mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false,
+                UID_N_MR1, false);
 
         assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
     }
@@ -3438,11 +3619,13 @@
     @Test
     public void testAndroidPkgCannotBypassDnd_update() throws Exception {
         NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
+        mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false,
+                SYSTEM_UID, true);
 
         NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
         update.setBypassDnd(true);
-        assertFalse(mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false));
+        assertFalse(mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false,
+                SYSTEM_UID, true));
 
         assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
                 .canBypassDnd());
@@ -3451,11 +3634,13 @@
     @Test
     public void testDndPkgCanBypassDnd_update() throws Exception {
         NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, test, true, true,
+                UID_N_MR1, false);
 
         NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
         update.setBypassDnd(true);
-        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true, true));
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true, true,
+                UID_N_MR1, false));
 
         assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
     }
@@ -3463,10 +3648,12 @@
     @Test
     public void testNormalPkgCannotBypassDnd_update() {
         NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, 1000, test, true, false,
+                UID_N_MR1, false);
         NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
         update.setBypassDnd(true);
-        mHelper.createNotificationChannel(PKG_N_MR1, 1000, update, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, 1000, update, true, false,
+                UID_N_MR1, false);
         assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 1000, "A", false).canBypassDnd());
     }
 
@@ -3726,12 +3913,14 @@
         assertTrue(mHelper.isImportanceLocked(PKG_O, UID_O));
 
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false,
+                UID_O, false);
 
         NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
         update.setAllowBubbles(false);
 
-        mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, update, true,
+                UID_O, false);
 
         assertEquals(IMPORTANCE_HIGH,
                 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
@@ -3745,12 +3934,12 @@
         toAdd.add(new Pair<>(PKG_O, UID_O));
         mHelper.updateDefaultApps(0, null, toAdd);
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
 
         NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
         update.setAllowBubbles(false);
 
-        mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, update, true, UID_O, false);
 
         assertEquals(IMPORTANCE_HIGH,
                 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
@@ -3763,12 +3952,12 @@
         when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(true);
 
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_NONE);
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, false, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, false, false, UID_O, false);
 
         NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
         update.setAllowBubbles(false);
 
-        mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, update, true, UID_O, false);
 
         assertEquals(IMPORTANCE_HIGH,
                 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
@@ -3782,12 +3971,12 @@
 
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
         a.setBlockable(true);
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
 
         NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
         update.setAllowBubbles(false);
 
-        mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, update, true, UID_O, false);
 
         assertEquals(IMPORTANCE_NONE,
                 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
@@ -3800,12 +3989,12 @@
         when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(false);
 
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
 
         NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
         update.setAllowBubbles(false);
 
-        mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, update, true, UID_O, false);
 
         assertEquals(IMPORTANCE_NONE,
                 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
@@ -3819,9 +4008,11 @@
         NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
         NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
         // different uids, same package
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
-        mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
-        mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false,
+                SYSTEM_UID, true);
+        mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true,
+                UserHandle.PER_USER_RANGE + 1, false);
 
         UserInfo user = new UserInfo();
         user.id = 0;
@@ -3859,7 +4050,7 @@
         mHelper.updateFixedImportance(users);
 
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
 
         assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
                 .isImportanceLockedByCriticalDeviceFunction());
@@ -3871,9 +4062,10 @@
         NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
         NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
         // different uids, same package
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
-        mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
-        mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false, UID_O, false);
+        mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true,
+                UID_O, false);
 
         ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
         toAdd.add(new Pair<>(PKG_O, UID_O));
@@ -3892,8 +4084,8 @@
     public void testUpdateDefaultApps_add_onlyGivenPkg() {
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
         NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false, UID_O, false);
 
         ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
         toAdd.add(new Pair<>(PKG_O, UID_O));
@@ -3910,8 +4102,8 @@
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
         NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
         // different uids, same package
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
-        mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false, SYSTEM_UID, true);
 
         ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
         toAdd.add(new Pair<>(PKG_O, UID_O));
@@ -3936,8 +4128,10 @@
     public void testUpdateDefaultApps_addAndRemove() {
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
         NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false,
+                UID_O, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false,
+                UID_N_MR1, false);
 
         ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
         toAdd.add(new Pair<>(PKG_O, UID_O));
@@ -3975,7 +4169,7 @@
     public void testUpdateDefaultApps_channelDoesNotExistYet() {
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
         NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
 
         ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
         toAdd.add(new Pair<>(PKG_O, UID_O));
@@ -3984,7 +4178,7 @@
         assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
                 .isImportanceLockedByCriticalDeviceFunction());
 
-        mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false, UID_O, false);
         assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
                 .isImportanceLockedByCriticalDeviceFunction());
     }
@@ -3992,7 +4186,7 @@
     @Test
     public void testUpdateNotificationChannel_defaultAppLockedImportance() {
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
         ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
         toAdd.add(new Pair<>(PKG_O, UID_O));
         mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
@@ -4000,19 +4194,20 @@
         NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
         update.setAllowBubbles(false);
 
-        mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, update, true, SYSTEM_UID, true);
         assertEquals(IMPORTANCE_HIGH,
                 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
         assertEquals(false,
                 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
 
-        mHelper.updateNotificationChannel(PKG_O, UID_O, update, false);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, update, false, UID_O, false);
         assertEquals(IMPORTANCE_HIGH,
                 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
 
         NotificationChannel updateImportanceLow = new NotificationChannel("a", "a",
                 IMPORTANCE_LOW);
-        mHelper.updateNotificationChannel(PKG_O, UID_O, updateImportanceLow, true);
+        mHelper.updateNotificationChannel(PKG_O, UID_O, updateImportanceLow, true,
+                SYSTEM_UID, true);
         assertEquals(IMPORTANCE_LOW,
                 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
     }
@@ -4024,7 +4219,7 @@
         mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
 
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
 
         assertTrue(a.isImportanceLockedByCriticalDeviceFunction());
     }
@@ -4050,7 +4245,7 @@
         assertTrue(mHelper.isImportanceLocked(PKG_O, UID_O));
 
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
 
         // Still locked by permission if not role
         assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
@@ -4078,7 +4273,7 @@
         assertTrue(mHelper.isImportanceLocked(PKG_O, UID_O));
 
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false, UID_O, false);
 
         // Still locked by role if not permission
         assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
@@ -4090,7 +4285,7 @@
         NotificationChannel channel1 =
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
 
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel1, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel1, true, false, UID_O, false);
 
         // clear data
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, true,
@@ -4144,14 +4339,14 @@
         for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
             NotificationChannel channel = new NotificationChannel(String.valueOf(i),
                     String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
-            mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
+            mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true, UID_O, false);
         }
         try {
             NotificationChannel channel = new NotificationChannel(
                     String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
                     String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT),
                     NotificationManager.IMPORTANCE_HIGH);
-            mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
+            mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true, UID_O, false);
             fail("Allowed to create too many notification channels");
         } catch (IllegalStateException e) {
             // great
@@ -4167,7 +4362,7 @@
         for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
             NotificationChannel channel = new NotificationChannel(String.valueOf(i),
                     String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
-            mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true);
+            mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true, UID_O, false);
         }
 
         final String xml = "<ranking version=\"1\">\n"
@@ -4200,13 +4395,15 @@
         for (int i = 0; i < NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT; i++) {
             NotificationChannelGroup group = new NotificationChannelGroup(String.valueOf(i),
                     String.valueOf(i));
-            mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, fromTargetApp);
+            mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, fromTargetApp,
+                    UID_O, false);
         }
         try {
             NotificationChannelGroup group = new NotificationChannelGroup(
                     String.valueOf(NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT),
                     String.valueOf(NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT));
-            mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, fromTargetApp);
+            mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, fromTargetApp,
+                    UID_O, false);
             fail("Allowed to create too many notification channel groups");
         } catch (IllegalStateException e) {
             // great
@@ -4222,7 +4419,8 @@
         for (int i = 0; i < NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT; i++) {
             NotificationChannelGroup group = new NotificationChannelGroup(String.valueOf(i),
                     String.valueOf(i));
-            mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true);
+            mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true,
+                    UID_O, false);
         }
 
         final String xml = "<ranking version=\"1\">\n"
@@ -4300,13 +4498,15 @@
 
         NotificationChannel parent =
                 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false,
+                UID_O, false);
 
         NotificationChannel friend = new NotificationChannel(String.format(
                 CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId),
                 "messages", IMPORTANCE_DEFAULT);
         friend.setConversationId(parent.getId(), conversationId);
-        mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false,
+                UID_O, false);
 
         compareChannelsParentChild(parent, mHelper.getConversationNotificationChannel(
                 PKG_O, UID_O, parent.getId(), conversationId, false, false), conversationId);
@@ -4318,7 +4518,8 @@
 
         NotificationChannel parent =
                 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false,
+                UID_O, false);
 
         compareChannels(parent, mHelper.getConversationNotificationChannel(
                 PKG_O, UID_O, parent.getId(), conversationId, true, false));
@@ -4335,7 +4536,8 @@
         friend.setConversationId(parentId, conversationId);
 
         try {
-            mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
+            mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false,
+                    UID_O, false);
             fail("allowed creation of conversation channel without a parent");
         } catch (IllegalArgumentException e) {
             // good
@@ -4429,9 +4631,12 @@
                 mAppOpsManager, mStatsEventBuilderFactory, false);
 
         mHelper.createNotificationChannel(
-                PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false);
-        assertTrue(mHelper.deleteNotificationChannel(PKG_P, UID_P, "id"));
-        assertFalse(mHelper.deleteNotificationChannel(PKG_P, UID_P, "id"));
+                PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false,
+                UID_P, false);
+        assertTrue(mHelper.deleteNotificationChannel(PKG_P, UID_P, "id",
+                UID_P, false));
+        assertFalse(mHelper.deleteNotificationChannel(PKG_P, UID_P, "id",
+                UID_P, false));
     }
 
     @Test
@@ -4441,8 +4646,9 @@
                 mAppOpsManager, mStatsEventBuilderFactory, false);
 
         mHelper.createNotificationChannel(
-                PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false);
-        mHelper.deleteNotificationChannel(PKG_P, UID_P, "id");
+                PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false,
+                UID_P, false);
+        mHelper.deleteNotificationChannel(PKG_P, UID_P, "id", UID_P, false);
         NotificationChannel nc1 = mHelper.getNotificationChannel(PKG_P, UID_P, "id", true);
         assertTrue(DateUtils.isToday(nc1.getDeletedTimeMs()));
         assertTrue(nc1.isDeleted());
@@ -4471,14 +4677,16 @@
                 mAppOpsManager, mStatsEventBuilderFactory, false);
 
         mHelper.createNotificationChannel(
-                PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false);
-        mHelper.deleteNotificationChannel(PKG_P, UID_P, "id");
+                PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false,
+                UID_P, false);
+        mHelper.deleteNotificationChannel(PKG_P, UID_P, "id", UID_P, false);
         NotificationChannel nc1 = mHelper.getNotificationChannel(PKG_P, UID_P, "id", true);
         assertTrue(DateUtils.isToday(nc1.getDeletedTimeMs()));
         assertTrue(nc1.isDeleted());
 
         mHelper.createNotificationChannel(
-                PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false);
+                PKG_P, UID_P, new NotificationChannel("id", "id", 2), true, false,
+                UID_P, false);
         nc1 = mHelper.getNotificationChannel(PKG_P, UID_P, "id", true);
         assertEquals(-1, nc1.getDeletedTimeMs());
         assertFalse(nc1.isDeleted());
@@ -4513,29 +4721,35 @@
         String convoId = "convo";
         NotificationChannel messages =
                 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false,
+                UID_O, false);
         NotificationChannel calls =
                 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false,
+                UID_O, false);
         NotificationChannel p =
                 new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
+        mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false,
+                UID_P, false);
 
         NotificationChannel channel =
                 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
         channel.setConversationId(messages.getId(), convoId);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false,
+                UID_O, false);
 
         NotificationChannel diffConvo =
                 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
         diffConvo.setConversationId(p.getId(), "different convo");
-        mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
+        mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false,
+                UID_O, false);
 
         NotificationChannel channel2 =
                 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
         channel2.setConversationId(calls.getId(), convoId);
         channel2.setImportantConversation(true);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, false, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, false, false,
+                SYSTEM_UID, true);
 
         List<ConversationChannelWrapper> convos =
                 mHelper.getConversations(IntArray.wrap(new int[] {0}), false);
@@ -4551,23 +4765,26 @@
         String convoId = "convo";
         NotificationChannel messages =
                 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false,
+                UID_O, false);
 
         NotificationChannel messagesUser10 =
                 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
         mHelper.createNotificationChannel(
-                PKG_O, UID_O + UserHandle.PER_USER_RANGE, messagesUser10, true, false);
+                PKG_O, UID_O + UserHandle.PER_USER_RANGE, messagesUser10, true, false,
+                UID_O + UserHandle.PER_USER_RANGE, false);
 
         NotificationChannel messagesFromB =
                 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
         messagesFromB.setConversationId(messages.getId(), "different convo");
-        mHelper.createNotificationChannel(PKG_O, UID_O, messagesFromB, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, messagesFromB, true, false, UID_O, false);
 
         NotificationChannel messagesFromBUser10 =
                 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
         messagesFromBUser10.setConversationId(messagesUser10.getId(), "different convo");
         mHelper.createNotificationChannel(
-                PKG_O, UID_O + UserHandle.PER_USER_RANGE, messagesFromBUser10, true, false);
+                PKG_O, UID_O + UserHandle.PER_USER_RANGE, messagesFromBUser10, true, false,
+                UID_O + UserHandle.PER_USER_RANGE, false);
 
 
         List<ConversationChannelWrapper> convos =
@@ -4589,30 +4806,31 @@
         String convoId = "convo";
         NotificationChannel messages =
                 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false, UID_O, false);
         NotificationChannel calls =
                 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false, UID_O, false);
         NotificationChannel p =
                 new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
+        mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false, UID_O, false);
 
         NotificationChannel channel =
                 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
         channel.setConversationId(messages.getId(), convoId);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
 
         NotificationChannel diffConvo =
                 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
         diffConvo.setConversationId(p.getId(), "different convo");
         diffConvo.setDemoted(true);
-        mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
+        mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false, UID_P, false);
 
         NotificationChannel channel2 =
                 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
         channel2.setConversationId(calls.getId(), convoId);
         channel2.setImportantConversation(true);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, false, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, false, false,
+                SYSTEM_UID, true);
 
         List<ConversationChannelWrapper> convos =
                 mHelper.getConversations(IntArray.wrap(new int[] {0}), false);
@@ -4628,30 +4846,31 @@
         String convoId = "convo";
         NotificationChannel messages =
                 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false, UID_O, false);
         NotificationChannel calls =
                 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false, UID_O, false);
         NotificationChannel p =
                 new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
+        mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false, UID_P, false);
 
         NotificationChannel channel =
                 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
         channel.setConversationId(messages.getId(), convoId);
         channel.setImportantConversation(true);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false, UID_O, false);
 
         NotificationChannel diffConvo =
                 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
         diffConvo.setConversationId(p.getId(), "different convo");
         diffConvo.setImportantConversation(true);
-        mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, false, false);
+        mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, false, false,
+                SYSTEM_UID, true);
 
         NotificationChannel channel2 =
                 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
         channel2.setConversationId(calls.getId(), convoId);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false, UID_O, false);
 
         List<ConversationChannelWrapper> convos =
                 mHelper.getConversations(IntArray.wrap(new int[] {0}), true);
@@ -4667,13 +4886,14 @@
         String convoId = "convo";
         NotificationChannel messages =
                 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false, UID_O, false);
 
         NotificationChannel channel =
                 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
         channel.setConversationId(messages.getId(), convoId);
         channel.setImportantConversation(true);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, false, false,
+                SYSTEM_UID, true);
 
         mHelper.permanentlyDeleteNotificationChannel(PKG_O, UID_O, "messages");
 
@@ -4704,7 +4924,7 @@
     public void testGetConversations_noConversations() {
         NotificationChannel channel =
                 new NotificationChannel("not_convo", "not_convo", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
 
         assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
     }
@@ -4713,15 +4933,15 @@
     public void testGetConversations_noDisabledGroups() {
         NotificationChannelGroup group = new NotificationChannelGroup("a", "a");
         group.setBlocked(true);
-        mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, false);
+        mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, false, SYSTEM_UID, true);
         NotificationChannel parent = new NotificationChannel("parent", "p", 1);
-        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);
 
         NotificationChannel channel =
                 new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
         channel.setConversationId("parent", "convo");
         channel.setGroup(group.getId());
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
 
         assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
     }
@@ -4729,12 +4949,12 @@
     @Test
     public void testGetConversations_noDeleted() {
         NotificationChannel parent = new NotificationChannel("parent", "p", 1);
-        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);
         NotificationChannel channel =
                 new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
         channel.setConversationId("parent", "convo");
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
-        mHelper.deleteNotificationChannel(PKG_O, UID_O, channel.getId());
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
+        mHelper.deleteNotificationChannel(PKG_O, UID_O, channel.getId(), UID_O, false);
 
         assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
     }
@@ -4742,12 +4962,12 @@
     @Test
     public void testGetConversations_noDemoted() {
         NotificationChannel parent = new NotificationChannel("parent", "p", 1);
-        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);
         NotificationChannel channel =
                 new NotificationChannel("convo", "convo", IMPORTANCE_DEFAULT);
         channel.setConversationId("parent", "convo");
         channel.setDemoted(true);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
 
         assertThat(mHelper.getConversations(PKG_O, UID_O)).isEmpty();
     }
@@ -4755,26 +4975,26 @@
     @Test
     public void testGetConversations() {
         NotificationChannelGroup group = new NotificationChannelGroup("acct", "account_name");
-        mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true);
+        mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true, UID_O, false);
 
         NotificationChannel messages =
                 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
         messages.setGroup(group.getId());
-        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false, UID_O, false);
         NotificationChannel calls =
                 new NotificationChannel("calls", "Calls", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false, UID_O, false);
 
         NotificationChannel channel =
                 new NotificationChannel("A person", "A lovely person", IMPORTANCE_DEFAULT);
         channel.setGroup(group.getId());
         channel.setConversationId(messages.getId(), channel.getName().toString());
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
 
         NotificationChannel channel2 =
                 new NotificationChannel("B person", "B fabulous person", IMPORTANCE_DEFAULT);
         channel2.setConversationId(calls.getId(), channel2.getName().toString());
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false, UID_O, false);
 
         Map<String, NotificationChannel> expected = new HashMap<>();
         expected.put(channel.getId(), channel);
@@ -4807,35 +5027,36 @@
         String convoIdC = "convoC";
         NotificationChannel messages =
                 new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false, UID_O, false);
         NotificationChannel calls =
                 new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false, UID_O, false);
 
         NotificationChannel channel =
                 new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
         channel.setConversationId(messages.getId(), convoId);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
 
         NotificationChannel noMatch =
                 new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
         noMatch.setConversationId(messages.getId(), "different convo");
-        mHelper.createNotificationChannel(PKG_O, UID_O, noMatch, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, noMatch, true, false, UID_O, false);
 
         NotificationChannel channel2 =
                 new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
         channel2.setConversationId(calls.getId(), convoId);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false, UID_O, false);
 
         NotificationChannel channel3 =
                 new NotificationChannel("C person msgs", "msgs from C", IMPORTANCE_DEFAULT);
         channel3.setConversationId(messages.getId(), convoIdC);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel3, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel3, true, false, UID_O, false);
 
         assertEquals(channel, mHelper.getNotificationChannel(PKG_O, UID_O, channel.getId(), false));
         assertEquals(channel2,
                 mHelper.getNotificationChannel(PKG_O, UID_O, channel2.getId(), false));
-        List<String> deleted = mHelper.deleteConversations(PKG_O, UID_O, Set.of(convoId, convoIdC));
+        List<String> deleted = mHelper.deleteConversations(PKG_O, UID_O, Set.of(convoId, convoIdC),
+                UID_O, false);
         assertEquals(3, deleted.size());
 
         assertEquals(messages,
@@ -4950,12 +5171,12 @@
         String channelId = "parent";
         String name = "messages";
         NotificationChannel fodderA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG_O, UID_O, fodderA, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, fodderA, true, false, UID_O, false);
         NotificationChannel channel =
                 new NotificationChannel(channelId, name, IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
         NotificationChannel fodderB = new NotificationChannel("b", "b", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_O, UID_O, fodderB, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, fodderB, true, false, UID_O, false);
 
         ArrayList<StatsEvent> events = new ArrayList<>();
         mHelper.pullPackageChannelPreferencesStats(events);
@@ -4980,11 +5201,11 @@
     @Test
     public void testPullPackageChannelPreferencesStats_one_to_one() {
         NotificationChannel channelA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channelA, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channelA, true, false, UID_O, false);
         NotificationChannel channelB = new NotificationChannel("b", "b", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channelB, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channelB, true, false, UID_O, false);
         NotificationChannel channelC = new NotificationChannel("c", "c", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channelC, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channelC, true, false, UID_O, false);
 
         List<String> channels = new LinkedList<>(Arrays.asList("a", "b", "c"));
 
@@ -5008,7 +5229,7 @@
 
         NotificationChannel parent =
                 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);
 
         String channelId = String.format(
                 CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId);
@@ -5016,7 +5237,7 @@
         NotificationChannel friend = new NotificationChannel(channelId,
                 name, IMPORTANCE_DEFAULT);
         friend.setConversationId(parent.getId(), conversationId);
-        mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false, UID_O, false);
 
         ArrayList<StatsEvent> events = new ArrayList<>();
         mHelper.pullPackageChannelPreferencesStats(events);
@@ -5038,14 +5259,14 @@
     public void testPullPackageChannelPreferencesStats_conversation_demoted() {
         NotificationChannel parent =
                 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);
         String channelId = String.format(
                 CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), "friend");
         NotificationChannel friend = new NotificationChannel(channelId,
                 "conversation", IMPORTANCE_DEFAULT);
         friend.setConversationId(parent.getId(), "friend");
         friend.setDemoted(true);
-        mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false, UID_O, false);
 
         ArrayList<StatsEvent> events = new ArrayList<>();
         mHelper.pullPackageChannelPreferencesStats(events);
@@ -5067,14 +5288,14 @@
     public void testPullPackageChannelPreferencesStats_conversation_priority() {
         NotificationChannel parent =
                 new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false, UID_O, false);
         String channelId = String.format(
                 CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), "friend");
         NotificationChannel friend = new NotificationChannel(channelId,
                 "conversation", IMPORTANCE_DEFAULT);
         friend.setConversationId(parent.getId(), "friend");
         friend.setImportantConversation(true);
-        mHelper.createNotificationChannel(PKG_O, UID_O, friend, false, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, friend, false, false, SYSTEM_UID, true);
 
         ArrayList<StatsEvent> events = new ArrayList<>();
         mHelper.pullPackageChannelPreferencesStats(events);
@@ -5096,11 +5317,12 @@
     public void testPullPackagePreferencesStats_postPermissionMigration() {
         // make sure there's at least one channel for each package we want to test
         NotificationChannel channelA = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channelA, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channelA, true, false,
+                UID_N_MR1, false);
         NotificationChannel channelB = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channelB, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channelB, true, false, UID_O, false);
         NotificationChannel channelC = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_P, UID_P, channelC, true, false);
+        mHelper.createNotificationChannel(PKG_P, UID_P, channelC, true, false, UID_P, false);
 
         // build a collection of app permissions that should be passed in and used
         ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> appPermissions = new ArrayMap<>();
@@ -5143,7 +5365,7 @@
     @Test
     public void testUnlockNotificationChannelImportance() {
         NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false, UID_O, false);
         channel.lockFields(USER_LOCKED_IMPORTANCE);
         assertTrue((channel.getUserLockedFields() & USER_LOCKED_IMPORTANCE) != 0);
 
@@ -5155,11 +5377,11 @@
     @Test
     public void testUnlockAllNotificationChannels() {
         NotificationChannel channelA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG_O, UID_O, channelA, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channelA, true, false, UID_O, false);
         NotificationChannel channelB = new NotificationChannel("b", "b", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_P, UID_P, channelB, true, false);
+        mHelper.createNotificationChannel(PKG_P, UID_P, channelB, true, false, UID_P, false);
         NotificationChannel channelC = new NotificationChannel("c", "c", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_P, UID_O, channelC, false, false);
+        mHelper.createNotificationChannel(PKG_P, UID_O, channelC, false, false, UID_O, false);
 
         channelA.lockFields(USER_LOCKED_IMPORTANCE);
         channelB.lockFields(USER_LOCKED_IMPORTANCE);
@@ -5178,11 +5400,11 @@
     @Test
     public void createNotificationChannel_updateDifferent_requestsSort() {
         NotificationChannel original = new NotificationChannel("id", "Bah", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_P, 0, original, true, false);
+        mHelper.createNotificationChannel(PKG_P, 0, original, true, false, 0, false);
         clearInvocations(mHandler);
 
         NotificationChannel updated = new NotificationChannel("id", "Wow", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_P, 0, updated, true, false);
+        mHelper.createNotificationChannel(PKG_P, 0, updated, true, false, 0, false);
 
         verify(mHandler).requestSort();
     }
@@ -5190,11 +5412,11 @@
     @Test
     public void createNotificationChannel_updateSame_doesNotRequestSort() {
         NotificationChannel original = new NotificationChannel("id", "Bah", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_P, 0, original, true, false);
+        mHelper.createNotificationChannel(PKG_P, 0, original, true, false, 0, false);
         clearInvocations(mHandler);
 
         NotificationChannel same = new NotificationChannel("id", "Bah", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_P, 0, same, true, false);
+        mHelper.createNotificationChannel(PKG_P, 0, same, true, false, 0, false);
 
         verifyZeroInteractions(mHandler);
     }
@@ -5202,11 +5424,11 @@
     @Test
     public void updateNotificationChannel_different_requestsSort() {
         NotificationChannel original = new NotificationChannel("id", "Bah", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_P, 0, original, true, false);
+        mHelper.createNotificationChannel(PKG_P, 0, original, true, false, 0, false);
         clearInvocations(mHandler);
 
         NotificationChannel updated = new NotificationChannel("id", "Wow", IMPORTANCE_DEFAULT);
-        mHelper.updateNotificationChannel(PKG_P, 0, updated, false);
+        mHelper.updateNotificationChannel(PKG_P, 0, updated, false, 0, false);
 
         verify(mHandler).requestSort();
     }
@@ -5214,7 +5436,7 @@
     @Test
     public void updateNotificationChannel_same_doesNotRequestSort() {
         NotificationChannel original = new NotificationChannel("id", "Bah", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_P, 0, original, true, false);
+        mHelper.createNotificationChannel(PKG_P, 0, original, true, false, 0, false);
         clearInvocations(mHandler);
         // Note: Creating a NotificationChannel identical to the original is not equals(), because
         // of mOriginalImportance. So we create a "true copy" instead.
@@ -5224,7 +5446,7 @@
         NotificationChannel same = NotificationChannel.CREATOR.createFromParcel(parcel);
         parcel.recycle();
 
-        mHelper.updateNotificationChannel(PKG_P, 0, same, false);
+        mHelper.updateNotificationChannel(PKG_P, 0, same, false, 0, false);
 
         verifyZeroInteractions(mHandler);
     }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java b/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
index 61a6985..9f4eee7 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/TestableNotificationManagerService.java
@@ -67,7 +67,13 @@
     @Override
     protected boolean isCallerSystemOrPhone() {
         countSystemChecks++;
-        return isSystemUid;
+        return isSystemUid || isSystemAppId;
+    }
+
+    @Override
+    protected boolean isCallerIsSystemOrSystemUi() {
+        countSystemChecks++;
+        return isSystemUid || isSystemAppId;
     }
 
     @Override
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java
new file mode 100644
index 0000000..4a1435f
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.notification;
+
+import android.content.pm.PackageManager;
+
+import com.android.os.dnd.DNDPolicyProto;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * ZenModeEventLoggerFake extends ZenModeEventLogger for ease of verifying logging output. This
+ * class behaves exactly the same as its parent class except that instead of actually logging, it
+ * stores the full information at time of log whenever something would be logged.
+ */
+public class ZenModeEventLoggerFake extends ZenModeEventLogger {
+    // A record of the contents of each event we'd log, stored by recording the ChangeState object
+    // at the time of the log.
+    private List<ZenStateChanges> mChanges = new ArrayList<>();
+
+    public ZenModeEventLoggerFake(PackageManager pm) {
+        super(pm);
+    }
+
+    @Override
+    void logChanges() {
+        // current change state being logged
+        mChanges.add(mChangeState.copy());
+    }
+
+    // Reset the state of the logger (remove all changes).
+    public void reset() {
+        mChanges = new ArrayList<>();
+    }
+
+    // Returns the number of changes logged.
+    public int numLoggedChanges() {
+        return mChanges.size();
+    }
+
+    // is index i out of range for the set of changes we have
+    private boolean outOfRange(int i) {
+        return i < 0 || i >= mChanges.size();
+    }
+
+    // Throw an exception if provided index is out of range
+    private void checkInRange(int i) throws IllegalArgumentException {
+        if (outOfRange(i)) {
+            throw new IllegalArgumentException("invalid index for logged event: " + i);
+        }
+    }
+
+    // Get the UiEvent ID of the i'th logged event.
+    public int getEventId(int i) throws IllegalArgumentException {
+        checkInRange(i);
+        return mChanges.get(i).getEventId().getId();
+    }
+
+    // Get the previous zen mode associated with the change at event i.
+    public int getPrevZenMode(int i) throws IllegalArgumentException {
+        checkInRange(i);
+        return mChanges.get(i).mPrevZenMode;
+    }
+
+    // Get the new zen mode associated with the change at event i.
+    public int getNewZenMode(int i) throws IllegalArgumentException {
+        checkInRange(i);
+        return mChanges.get(i).mNewZenMode;
+    }
+
+    // Get the changed rule type associated with event i.
+    public int getChangedRuleType(int i) throws IllegalArgumentException {
+        checkInRange(i);
+        return mChanges.get(i).getChangedRuleType();
+    }
+
+    public int getNumRulesActive(int i) throws IllegalArgumentException {
+        checkInRange(i);
+        return mChanges.get(i).getNumRulesActive();
+    }
+
+    public boolean getFromSystemOrSystemUi(int i) throws IllegalArgumentException {
+        // While this isn't a logged output value, it's still helpful to check in tests.
+        checkInRange(i);
+        return mChanges.get(i).mFromSystemOrSystemUi;
+    }
+
+    public boolean getIsUserAction(int i) throws IllegalArgumentException {
+        checkInRange(i);
+        return mChanges.get(i).getIsUserAction();
+    }
+
+    public int getPackageUid(int i) throws IllegalArgumentException {
+        checkInRange(i);
+        return mChanges.get(i).getPackageUid();
+    }
+
+    // Get the DNDPolicyProto (unmarshaled from bytes) associated with event i.
+    // Note that in creation of the log, we use a notification.proto mirror of DNDPolicyProto,
+    // but here we use the actual logging-side proto to make sure they continue to match.
+    public DNDPolicyProto getPolicyProto(int i) throws IllegalArgumentException {
+        checkInRange(i);
+        byte[] policyBytes = mChanges.get(i).getDNDPolicyProto();
+        try {
+            return DNDPolicyProto.parseFrom(policyBytes);
+        } catch (InvalidProtocolBufferException e) {
+            return null; // couldn't turn it into proto
+        }
+    }
+
+    public boolean getAreChannelsBypassing(int i) throws IllegalArgumentException {
+        checkInRange(i);
+        return mChanges.get(i).getAreChannelsBypassing();
+    }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 2c95bde..dedb8f1 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -34,16 +34,21 @@
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
 import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.service.notification.Condition.STATE_FALSE;
 import static android.service.notification.Condition.STATE_TRUE;
 import static android.util.StatsLog.ANNOTATION_ID_IS_UID;
 
+import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.LOG_DND_STATE_EVENTS;
 import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE;
 import static com.android.os.dnd.DNDModeProto.CHANNELS_BYPASSING_FIELD_NUMBER;
 import static com.android.os.dnd.DNDModeProto.ENABLED_FIELD_NUMBER;
 import static com.android.os.dnd.DNDModeProto.ID_FIELD_NUMBER;
 import static com.android.os.dnd.DNDModeProto.UID_FIELD_NUMBER;
 import static com.android.os.dnd.DNDModeProto.ZEN_MODE_FIELD_NUMBER;
+import static com.android.os.dnd.DNDProtoEnums.PEOPLE_STARRED;
 import static com.android.os.dnd.DNDProtoEnums.ROOT_CONFIG;
+import static com.android.os.dnd.DNDProtoEnums.STATE_ALLOW;
+import static com.android.os.dnd.DNDProtoEnums.STATE_DISALLOW;
 import static com.android.server.notification.ZenModeHelper.RULE_LIMIT_PER_PACKAGE;
 
 import static junit.framework.Assert.assertEquals;
@@ -104,9 +109,12 @@
 import android.util.Xml;
 
 import com.android.internal.R;
+import com.android.internal.config.sysui.TestableFlagResolver;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
+import com.android.os.dnd.DNDPolicyProto;
+import com.android.os.dnd.DNDProtoEnums;
 import com.android.server.UiServiceTestCase;
 import com.android.server.notification.ManagedServices.UserProfiles;
 
@@ -152,6 +160,8 @@
     private ContentResolver mContentResolver;
     @Mock AppOpsManager mAppOps;
     private WrappedSysUiStatsEvent.WrappedBuilderFactory mStatsEventBuilderFactory;
+    TestableFlagResolver mTestFlagResolver = new TestableFlagResolver();
+    ZenModeEventLoggerFake mZenModeEventLogger;
 
     @Before
     public void setUp() throws PackageManager.NameNotFoundException {
@@ -176,8 +186,10 @@
                 AppGlobals.getPackageManager());
         mConditionProviders.addSystemProvider(new CountdownConditionProvider());
         mConditionProviders.addSystemProvider(new ScheduleConditionProvider());
+        mZenModeEventLogger = new ZenModeEventLoggerFake(mPackageManager);
         mZenModeHelper = new ZenModeHelper(mContext, mTestableLooper.getLooper(),
-                mConditionProviders, mStatsEventBuilderFactory);
+                mConditionProviders, mStatsEventBuilderFactory, mTestFlagResolver,
+                mZenModeEventLogger);
 
         ResolveInfo ri = new ResolveInfo();
         ri.activityInfo = new ActivityInfo();
@@ -188,6 +200,8 @@
         when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(
                 new String[] {pkg});
         mZenModeHelper.mPm = mPackageManager;
+
+        mZenModeEventLogger.reset();
     }
 
     private XmlResourceParser getDefaultConfigParser() throws IOException, XmlPullParserException {
@@ -224,7 +238,8 @@
         mZenModeHelper.writeXml(serializer, false, version, UserHandle.USER_ALL);
         serializer.endDocument();
         serializer.flush();
-        mZenModeHelper.setConfig(new ZenModeConfig(), null, "writing xml");
+        mZenModeHelper.setConfig(new ZenModeConfig(), null, "writing xml", Process.SYSTEM_UID,
+                true);
         return baos;
     }
 
@@ -239,7 +254,7 @@
         serializer.flush();
         ZenModeConfig newConfig = new ZenModeConfig();
         newConfig.user = userId;
-        mZenModeHelper.setConfig(newConfig, null, "writing xml");
+        mZenModeHelper.setConfig(newConfig, null, "writing xml", Process.SYSTEM_UID, true);
         return baos;
     }
 
@@ -822,14 +837,11 @@
         mZenModeHelper.mAudioManager = mAudioManager;
         setupZenConfig();
 
-        // Change the config a little bit, but enough that it would turn zen mode on
-        ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
-        newConfig.manualRule = new ZenModeConfig.ZenRule();
-        newConfig.manualRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        newConfig.manualRule.enabled = true;
-        mZenModeHelper.setConfig(newConfig, null, "test");
+        // Turn manual zen mode on
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null,
+                "test", CUSTOM_PKG_UID, false);
 
-        // audio manager shouldn't do anything until the handler processes its messagse
+        // audio manager shouldn't do anything until the handler processes its messages
         verify(mAudioManager, never()).updateRingerModeAffectedStreamsInternal();
 
         // now process the looper's messages
@@ -993,7 +1005,7 @@
         List<StatsEvent> events = new LinkedList<>();
 
         mZenModeHelper.pullRules(events);
-        mZenModeHelper.removeAutomaticZenRule(CUSTOM_RULE_ID, "test");
+        mZenModeHelper.removeAutomaticZenRule(CUSTOM_RULE_ID, "test", CUSTOM_PKG_UID, false);
         assertTrue(-1
                 == mZenModeHelper.mRulesUidCache.getOrDefault(CUSTOM_PKG_NAME + "|" + 0, -1));
     }
@@ -1044,12 +1056,12 @@
         config10.user = 10;
         config10.allowAlarms = true;
         config10.allowMedia = true;
-        mZenModeHelper.setConfig(config10, null, "writeXml");
+        mZenModeHelper.setConfig(config10, null, "writeXml", Process.SYSTEM_UID, true);
         ZenModeConfig config11 = mZenModeHelper.mConfig.copy();
         config11.user = 11;
         config11.allowAlarms = false;
         config11.allowMedia = false;
-        mZenModeHelper.setConfig(config11, null, "writeXml");
+        mZenModeHelper.setConfig(config11, null, "writeXml", Process.SYSTEM_UID, true);
 
         // Backup user 10 and reset values.
         ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, 10);
@@ -1552,7 +1564,8 @@
         ZenModeConfig config = new ZenModeConfig();
         config.automaticRules = new ArrayMap<>();
         mZenModeHelper.mConfig = config;
-        mZenModeHelper.updateDefaultZenRules(); // shouldn't throw null pointer
+        mZenModeHelper.updateDefaultZenRules(
+                Process.SYSTEM_UID, true); // shouldn't throw null pointer
         mZenModeHelper.pullRules(events); // shouldn't throw null pointer
     }
 
@@ -1577,7 +1590,7 @@
         autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule);
         mZenModeHelper.mConfig.automaticRules = autoRules;
 
-        mZenModeHelper.updateDefaultZenRules();
+        mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID, true);
         assertEquals(updatedDefaultRule,
                 mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
     }
@@ -1603,7 +1616,7 @@
         autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule);
         mZenModeHelper.mConfig.automaticRules = autoRules;
 
-        mZenModeHelper.updateDefaultZenRules();
+        mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID, true);
         assertEquals(updatedDefaultRule,
                 mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
     }
@@ -1630,7 +1643,7 @@
         autoRules.put(SCHEDULE_DEFAULT_RULE_ID, customDefaultRule);
         mZenModeHelper.mConfig.automaticRules = autoRules;
 
-        mZenModeHelper.updateDefaultZenRules();
+        mZenModeHelper.updateDefaultZenRules(Process.SYSTEM_UID, true);
         ZenModeConfig.ZenRule ruleAfterUpdating =
                 mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID);
         assertEquals(customDefaultRule.enabled, ruleAfterUpdating.enabled);
@@ -1653,7 +1666,8 @@
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
             // We need the package name to be something that's not "android" so there aren't any
             // existing rules under that package.
-            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
+                    CUSTOM_PKG_UID, false);
             assertNotNull(id);
         }
         try {
@@ -1663,7 +1677,8 @@
                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
+                    CUSTOM_PKG_UID, false);
             fail("allowed too many rules to be created");
         } catch (IllegalArgumentException e) {
             // yay
@@ -1683,7 +1698,8 @@
                     ZenModeConfig.toScheduleConditionId(si),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
+                    CUSTOM_PKG_UID, false);
             assertNotNull(id);
         }
         try {
@@ -1693,7 +1709,8 @@
                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
+                    CUSTOM_PKG_UID, false);
             fail("allowed too many rules to be created");
         } catch (IllegalArgumentException e) {
             // yay
@@ -1713,7 +1730,8 @@
                     ZenModeConfig.toScheduleConditionId(si),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
+                    CUSTOM_PKG_UID, false);
             assertNotNull(id);
         }
         try {
@@ -1723,7 +1741,8 @@
                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
+                    CUSTOM_PKG_UID, false);
             fail("allowed too many rules to be created");
         } catch (IllegalArgumentException e) {
             // yay
@@ -1738,7 +1757,8 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test");
+        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test",
+                Process.SYSTEM_UID, true);
 
         assertTrue(id != null);
         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
@@ -1758,7 +1778,8 @@
                 new ComponentName("android", "ScheduleConditionProvider"),
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test");
+        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test",
+                Process.SYSTEM_UID, true);
 
         assertTrue(id != null);
         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
@@ -1781,9 +1802,11 @@
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
 
-        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
+        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
+                CUSTOM_PKG_UID, false);
         mZenModeHelper.setAutomaticZenRuleState(zenRule.getConditionId(),
-                new Condition(zenRule.getConditionId(), "", STATE_TRUE));
+                new Condition(zenRule.getConditionId(), "", STATE_TRUE),
+                CUSTOM_PKG_UID, false);
 
         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
         assertEquals(STATE_TRUE, ruleInConfig.condition.state);
@@ -1798,7 +1821,8 @@
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
 
-        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
+        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
+                CUSTOM_PKG_UID, false);
 
         AutomaticZenRule zenRule2 = new AutomaticZenRule("NEW",
                 null,
@@ -1807,7 +1831,7 @@
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
 
-        mZenModeHelper.updateAutomaticZenRule(id, zenRule2, "");
+        mZenModeHelper.updateAutomaticZenRule(id, zenRule2, "", CUSTOM_PKG_UID, false);
 
         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
         assertEquals("NEW", ruleInConfig.name);
@@ -1822,14 +1846,15 @@
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
 
-        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
+        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
+                CUSTOM_PKG_UID, false);
 
         assertTrue(id != null);
         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
         assertTrue(ruleInConfig != null);
         assertEquals(zenRule.getName(), ruleInConfig.name);
 
-        mZenModeHelper.removeAutomaticZenRule(id, "test");
+        mZenModeHelper.removeAutomaticZenRule(id, "test", CUSTOM_PKG_UID, false);
         assertNull(mZenModeHelper.mConfig.automaticRules.get(id));
     }
 
@@ -1841,14 +1866,16 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
+        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
+                CUSTOM_PKG_UID, false);
 
         assertTrue(id != null);
         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
         assertTrue(ruleInConfig != null);
         assertEquals(zenRule.getName(), ruleInConfig.name);
 
-        mZenModeHelper.removeAutomaticZenRules(mContext.getPackageName(), "test");
+        mZenModeHelper.removeAutomaticZenRules(mContext.getPackageName(), "test",
+                CUSTOM_PKG_UID, false);
         assertNull(mZenModeHelper.mConfig.automaticRules.get(id));
     }
 
@@ -1863,15 +1890,17 @@
                 new ComponentName("android", "ScheduleConditionProvider"),
                 sharedUri,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test");
+        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test",
+                Process.SYSTEM_UID, true);
         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
                 new ComponentName("android", "ScheduleConditionProvider"),
                 sharedUri,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id2 = mZenModeHelper.addAutomaticZenRule("android", zenRule2, "test");
+        String id2 = mZenModeHelper.addAutomaticZenRule("android", zenRule2, "test",
+                Process.SYSTEM_UID, true);
 
         Condition condition = new Condition(sharedUri, "", STATE_TRUE);
-        mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition);
+        mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition, Process.SYSTEM_UID, true);
 
         for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
             if (rule.id.equals(id)) {
@@ -1884,17 +1913,17 @@
             }
         }
 
-        condition = new Condition(sharedUri, "", Condition.STATE_FALSE);
-        mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition);
+        condition = new Condition(sharedUri, "", STATE_FALSE);
+        mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition, Process.SYSTEM_UID, true);
 
         for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
             if (rule.id.equals(id)) {
                 assertNotNull(rule.condition);
-                assertTrue(rule.condition.state == Condition.STATE_FALSE);
+                assertTrue(rule.condition.state == STATE_FALSE);
             }
             if (rule.id.equals(id2)) {
                 assertNotNull(rule.condition);
-                assertTrue(rule.condition.state == Condition.STATE_FALSE);
+                assertTrue(rule.condition.state == STATE_FALSE);
             }
         }
     }
@@ -1904,16 +1933,512 @@
         setupZenConfig();
 
         // note that caller=null because that's how it comes in from NMS.setZenMode
-        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "");
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
+                Process.SYSTEM_UID, true);
 
         // confirm that setting zen mode via setManualZenMode changed the zen mode correctly
         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeHelper.mZenMode);
 
         // and also that it works to turn it back off again
-        mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "");
+        mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "",
+                Process.SYSTEM_UID, true);
+
         assertEquals(Global.ZEN_MODE_OFF, mZenModeHelper.mZenMode);
     }
 
+    @Test
+    public void testZenModeEventLog_setManualZenMode() throws IllegalArgumentException {
+        mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+        setupZenConfig();
+
+        // Turn zen mode on (to important_interruptions)
+        // Need to additionally call the looper in order to finish the post-apply-config process
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
+                Process.SYSTEM_UID, true);
+
+        // Now turn zen mode off, but via a different package UID -- this should get registered as
+        // "not an action by the user" because some other app is changing zen mode
+        mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "", CUSTOM_PKG_UID,
+                false);
+
+        // In total, this should be 2 loggable changes
+        assertEquals(2, mZenModeEventLogger.numLoggedChanges());
+
+        // we expect the following changes from turning zen mode on:
+        //   - manual rule added
+        //   - zen mode -> ZEN_MODE_IMPORTANT_INTERRUPTIONS
+        // This should combine to 1 log event (zen mode turns on) with the following properties:
+        //   - event ID: DND_TURNED_ON
+        //   - new zen mode = important interruptions; prev zen mode = off
+        //   - changed rule type = manual
+        //   - rules active = 1
+        //   - user action = true (system-based turning zen mode on)
+        //   - package uid = system (as set above)
+        //   - resulting DNDPolicyProto the same as the values in setupZenConfig()
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+                mZenModeEventLogger.getEventId(0));
+        assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getPrevZenMode(0));
+        assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0));
+        assertEquals(DNDProtoEnums.MANUAL_RULE, mZenModeEventLogger.getChangedRuleType(0));
+        assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
+        assertTrue(mZenModeEventLogger.getFromSystemOrSystemUi(0));
+        assertTrue(mZenModeEventLogger.getIsUserAction(0));
+        assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(0));
+        checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
+
+        // and from turning zen mode off:
+        //   - event ID: DND_TURNED_OFF
+        //   - new zen mode = off; previous = important interruptions
+        //   - changed rule type = manual
+        //   - rules active = 0
+        //   - user action = false
+        //   - package uid = custom one passed in above
+        //   - DNDPolicyProto still the same
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
+                mZenModeEventLogger.getEventId(1));
+        assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getPrevZenMode(1));
+        assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getNewZenMode(1));
+        assertEquals(DNDProtoEnums.MANUAL_RULE, mZenModeEventLogger.getChangedRuleType(1));
+        assertEquals(0, mZenModeEventLogger.getNumRulesActive(1));
+        assertFalse(mZenModeEventLogger.getIsUserAction(1));
+        assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(1));
+        checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1));
+    }
+
+    @Test
+    public void testZenModeEventLog_automaticRules() throws IllegalArgumentException {
+        mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+        setupZenConfig();
+
+        // Add a new automatic zen rule that's enabled
+        AutomaticZenRule zenRule = new AutomaticZenRule("name",
+                null,
+                new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
+                ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+                null,
+                NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule,
+                "test", Process.SYSTEM_UID, true);
+
+        // Event 1: Mimic the rule coming on automatically by setting the Condition to STATE_TRUE
+        mZenModeHelper.setAutomaticZenRuleState(id,
+                new Condition(zenRule.getConditionId(), "", STATE_TRUE),
+                Process.SYSTEM_UID, true);
+
+        // Event 2: "User" turns off the automatic rule (sets it to not enabled)
+        zenRule.setEnabled(false);
+        mZenModeHelper.updateAutomaticZenRule(id, zenRule, "", Process.SYSTEM_UID, true);
+
+        // Add a new system rule
+        AutomaticZenRule systemRule = new AutomaticZenRule("systemRule",
+                null,
+                new ComponentName("android", "ScheduleConditionProvider"),
+                ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+                null,
+                NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+        String systemId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), systemRule,
+                "test", Process.SYSTEM_UID, true);
+
+        // Event 3: turn on the system rule
+        mZenModeHelper.setAutomaticZenRuleState(systemId,
+                new Condition(zenRule.getConditionId(), "", STATE_TRUE),
+                Process.SYSTEM_UID, true);
+
+        // Event 4: "User" deletes the rule
+        mZenModeHelper.removeAutomaticZenRule(systemId, "", Process.SYSTEM_UID, true);
+
+        // In total, this represents 4 events
+        assertEquals(4, mZenModeEventLogger.numLoggedChanges());
+
+        // We should see an event from the automatic rule turning on; it should have the following
+        // properties:
+        //   - event ID: DND_TURNED_ON
+        //   - zen mode: OFF -> IMPORTANT_INTERRUPTIONS
+        //   - automatic rule change
+        //   - 1 rule (newly) active
+        //   - automatic (is not a user action)
+        //   - package UID is written to be the rule *owner* even though it "comes from system"
+        //   - zen policy is the same as the set-up zen config
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+                mZenModeEventLogger.getEventId(0));
+        assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getPrevZenMode(0));
+        assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0));
+        assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(0));
+        assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
+        assertFalse(mZenModeEventLogger.getIsUserAction(0));
+        assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
+        checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
+
+        // When the automatic rule is disabled, this should turn off zen mode and also count as a
+        // user action.
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
+                mZenModeEventLogger.getEventId(1));
+        assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getPrevZenMode(1));
+        assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getNewZenMode(1));
+        assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(1));
+        assertEquals(0, mZenModeEventLogger.getNumRulesActive(1));
+        assertTrue(mZenModeEventLogger.getIsUserAction(1));
+        assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
+        checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1));
+
+        // When the system rule is enabled, this counts as an automatic action that comes from the
+        // system and turns on DND
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+                mZenModeEventLogger.getEventId(2));
+        assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(2));
+        assertEquals(1, mZenModeEventLogger.getNumRulesActive(2));
+        assertFalse(mZenModeEventLogger.getIsUserAction(2));
+        assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(2));
+
+        // When the system rule is deleted, we consider this a user action that turns DND off
+        // (again)
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
+                mZenModeEventLogger.getEventId(3));
+        assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(3));
+        assertEquals(0, mZenModeEventLogger.getNumRulesActive(3));
+        assertTrue(mZenModeEventLogger.getIsUserAction(3));
+        assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(3));
+    }
+
+    @Test
+    public void testZenModeEventLog_policyChanges() throws IllegalArgumentException {
+        mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+        setupZenConfig();
+
+        // First just turn zen mode on
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
+                Process.SYSTEM_UID, true);
+
+        // Now change the policy slightly; want to confirm that this'll be reflected in the logs
+        ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
+        newConfig.allowAlarms = true;
+        newConfig.allowRepeatCallers = false;
+        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
+                true);
+
+        // Turn zen mode off; we want to make sure policy changes do not get logged when zen mode
+        // is off.
+        mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "",
+                Process.SYSTEM_UID, true);
+
+        // Change the policy again
+        newConfig.allowMessages = false;
+        newConfig.allowRepeatCallers = true;
+        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
+                true);
+
+        // Total events: we only expect ones for turning on, changing policy, and turning off
+        assertEquals(3, mZenModeEventLogger.numLoggedChanges());
+
+        // The first event is just turning DND on; make sure the policy is what we expect there
+        // before it changes in the next stage
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+                mZenModeEventLogger.getEventId(0));
+        checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
+
+        // Second message where we change the policy:
+        //   - DND_POLICY_CHANGED (indicates only the policy changed and nothing else)
+        //   - rule type: unknown (it's a policy change, not a rule change)
+        //   - user action (because it comes from a "system" uid)
+        //   - check the specific things changed above
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
+                mZenModeEventLogger.getEventId(1));
+        assertEquals(DNDProtoEnums.UNKNOWN_RULE, mZenModeEventLogger.getChangedRuleType(1));
+        assertTrue(mZenModeEventLogger.getIsUserAction(1));
+        assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
+        DNDPolicyProto dndProto = mZenModeEventLogger.getPolicyProto(1);
+        assertEquals(STATE_ALLOW, dndProto.getAlarms().getNumber());
+        assertEquals(STATE_DISALLOW, dndProto.getRepeatCallers().getNumber());
+
+        // The third and final event should turn DND off
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
+                mZenModeEventLogger.getEventId(2));
+
+        // There should be no fourth event for changing the policy the second time.
+    }
+
+    @Test
+    public void testZenModeEventLog_ruleCounts() throws IllegalArgumentException {
+        mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+        setupZenConfig();
+
+        AutomaticZenRule zenRule = new AutomaticZenRule("name",
+                null,
+                new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
+                ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+                null,
+                NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
+                Process.SYSTEM_UID, true);
+
+        // Rule 2, same as rule 1
+        AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
+                null,
+                new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
+                ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+                null,
+                NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+        String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, "test",
+                Process.SYSTEM_UID, true);
+
+        // Rule 3, has stricter settings than the default settings
+        ZenModeConfig ruleConfig = mZenModeHelper.mConfig.copy();
+        ruleConfig.allowReminders = false;
+        ruleConfig.allowCalls = false;
+        ruleConfig.allowMessages = false;
+        AutomaticZenRule zenRule3 = new AutomaticZenRule("name3",
+                null,
+                new ComponentName("android", "ScheduleConditionProvider"),
+                ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+                ruleConfig.toZenPolicy(),
+                NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+        String id3 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule3, "test",
+                Process.SYSTEM_UID, true);
+
+        // First: turn on rule 1
+        mZenModeHelper.setAutomaticZenRuleState(id,
+                new Condition(zenRule.getConditionId(), "", STATE_TRUE),
+                Process.SYSTEM_UID, true);
+
+        // Second: turn on rule 2
+        mZenModeHelper.setAutomaticZenRuleState(id2,
+                new Condition(zenRule2.getConditionId(), "", STATE_TRUE),
+                Process.SYSTEM_UID, true);
+
+        // Third: turn on rule 3
+        mZenModeHelper.setAutomaticZenRuleState(id3,
+                new Condition(zenRule3.getConditionId(), "", STATE_TRUE),
+                Process.SYSTEM_UID, true);
+
+        // Fourth: Turn *off* rule 2
+        mZenModeHelper.setAutomaticZenRuleState(id2,
+                new Condition(zenRule2.getConditionId(), "", STATE_FALSE),
+                Process.SYSTEM_UID, true);
+
+        // This should result in a total of four events
+        assertEquals(4, mZenModeEventLogger.numLoggedChanges());
+
+        // Event 1: rule 1 turns on. We expect this to turn on DND (zen mode) overall, so that's
+        // what the event should reflect. At this time, the policy is the same as initial setup.
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+                mZenModeEventLogger.getEventId(0));
+        assertEquals(Global.ZEN_MODE_OFF, mZenModeEventLogger.getPrevZenMode(0));
+        assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0));
+        assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
+        assertFalse(mZenModeEventLogger.getIsUserAction(0));
+        assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
+        checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
+
+        // Event 2: rule 2 turns on. This should not change anything about the policy, so the only
+        // change is that there are more rules active now.
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
+                mZenModeEventLogger.getEventId(1));
+        assertEquals(2, mZenModeEventLogger.getNumRulesActive(1));
+        assertFalse(mZenModeEventLogger.getIsUserAction(1));
+        assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(1));
+        checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1));
+
+        // Event 3: rule 3 turns on. This should trigger a policy change, and be classified as such,
+        // but meanwhile also change the number of active rules.
+        // Rule 3 is also set up to be a "system"-owned rule, so the caller UID should remain system
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
+                mZenModeEventLogger.getEventId(2));
+        assertEquals(3, mZenModeEventLogger.getNumRulesActive(2));
+        assertFalse(mZenModeEventLogger.getIsUserAction(2));
+        assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(2));
+        DNDPolicyProto dndProto = mZenModeEventLogger.getPolicyProto(2);
+        assertEquals(STATE_DISALLOW, dndProto.getReminders().getNumber());
+        assertEquals(STATE_DISALLOW, dndProto.getCalls().getNumber());
+        assertEquals(STATE_DISALLOW, dndProto.getMessages().getNumber());
+
+        // Event 4: rule 2 turns off. Because rule 3 is still on and stricter than rule 1 (also
+        // still on), there should be no policy change as a result of rule 2 going away. Therefore
+        // this event should again only be an active rule change.
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
+                mZenModeEventLogger.getEventId(3));
+        assertEquals(2, mZenModeEventLogger.getNumRulesActive(3));
+        assertFalse(mZenModeEventLogger.getIsUserAction(3));
+    }
+
+    @Test
+    public void testZenModeEventLog_noLogWithNoConfigChange() throws IllegalArgumentException {
+        // If evaluateZenMode is called independently of a config change, don't log.
+        mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+        setupZenConfig();
+
+        // Artificially turn zen mode "on". Re-evaluating zen mode should cause it to turn back off
+        // given that we don't have any zen rules active.
+        mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelper.evaluateZenMode("test", true);
+
+        // Check that the change actually took: zen mode should be off now
+        assertEquals(Global.ZEN_MODE_OFF, mZenModeHelper.mZenMode);
+
+        // but still, nothing should've been logged
+        assertEquals(0, mZenModeEventLogger.numLoggedChanges());
+    }
+
+    @Test
+    public void testZenModeEventLog_reassignUid() throws IllegalArgumentException {
+        // Test that, only in specific cases, we reassign the calling UID to one associated with
+        // the automatic rule owner.
+        mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+        setupZenConfig();
+
+        // Rule 1, owned by a package
+        AutomaticZenRule zenRule = new AutomaticZenRule("name",
+                null,
+                new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
+                ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+                null,
+                NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
+                Process.SYSTEM_UID, true);
+
+        // Rule 2, same as rule 1 but owned by the system
+        AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
+                null,
+                new ComponentName("android", "ScheduleConditionProvider"),
+                ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+                null,
+                NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+        String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, "test",
+                Process.SYSTEM_UID, true);
+
+        // Turn on rule 1; call looks like it's from the system. Because setting a condition is
+        // typically an automatic (non-user-initiated) action, expect the calling UID to be
+        // re-evaluated to the one associat.d with CUSTOM_PKG_NAME.
+        mZenModeHelper.setAutomaticZenRuleState(id,
+                new Condition(zenRule.getConditionId(), "", STATE_TRUE),
+                Process.SYSTEM_UID, true);
+
+        // Second: turn on rule 2. This is a system-owned rule and the UID should not be modified
+        // (nor even looked up; the mock PackageManager won't handle "android" as input).
+        mZenModeHelper.setAutomaticZenRuleState(id2,
+                new Condition(zenRule2.getConditionId(), "", STATE_TRUE),
+                Process.SYSTEM_UID, true);
+
+        // Disable rule 1. Because this looks like a user action, the UID should not be modified
+        // from the system-provided one.
+        zenRule.setEnabled(false);
+        mZenModeHelper.updateAutomaticZenRule(id, zenRule, "", Process.SYSTEM_UID, true);
+
+        // Add a manual rule. Any manual rule changes should not get calling uids reassigned.
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
+                CUSTOM_PKG_UID, false);
+
+        // Change rule 2's condition, but from some other UID. Since it doesn't look like it's from
+        // the system, we keep the UID info.
+        mZenModeHelper.setAutomaticZenRuleState(id2,
+                new Condition(zenRule2.getConditionId(), "", STATE_FALSE),
+                12345, false);
+
+        // That was 5 events total
+        assertEquals(5, mZenModeEventLogger.numLoggedChanges());
+
+        // The first event (activating rule 1) should be of type "zen mode turns on", automatic,
+        // have a package UID of CUSTOM_PKG_UID
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+                mZenModeEventLogger.getEventId(0));
+        assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(0));
+        assertFalse(mZenModeEventLogger.getIsUserAction(0));
+        assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
+
+        // The second event (activating rule 2) should have similar other properties but the UID
+        // should be system.
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
+                mZenModeEventLogger.getEventId(1));
+        assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(1));
+        assertFalse(mZenModeEventLogger.getIsUserAction(1));
+        assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1));
+
+        // Third event: disable rule 1. This looks like a user action so UID should be left alone.
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
+                mZenModeEventLogger.getEventId(2));
+        assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(2));
+        assertTrue(mZenModeEventLogger.getIsUserAction(2));
+        assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(2));
+
+        // Fourth event: turns on manual mode. Doesn't change effective policy so this is just a
+        // change in active rules. Confirm that the package UID is left unchanged.
+        // Because it's a manual mode change not from the system, isn't considered a user action.
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
+                mZenModeEventLogger.getEventId(3));
+        assertEquals(DNDProtoEnums.MANUAL_RULE, mZenModeEventLogger.getChangedRuleType(3));
+        assertFalse(mZenModeEventLogger.getIsUserAction(3));
+        assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(3));
+
+        // Fourth event: changed condition on rule 2 (turning it off via condition).
+        // This comes from a random different UID so we expect that to remain untouched.
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_ACTIVE_RULES_CHANGED.getId(),
+                mZenModeEventLogger.getEventId(4));
+        assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(4));
+        assertFalse(mZenModeEventLogger.getIsUserAction(4));
+        assertEquals(12345, mZenModeEventLogger.getPackageUid(4));
+    }
+
+    @Test
+    public void testZenModeEventLog_channelsBypassingChanges() {
+        // Verify that the right thing happens when the canBypassDnd value changes.
+        mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+        setupZenConfig();
+
+        // Turn on zen mode with a manual rule with an enabler set. This should *not* count
+        // as a user action, and *should* get its UID reassigned.
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
+                CUSTOM_PKG_NAME, "", Process.SYSTEM_UID, true);
+
+        // Now change apps bypassing to true
+        ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
+        newConfig.areChannelsBypassingDnd = true;
+        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
+                true);
+
+        // and then back to false, all without changing anything else
+        newConfig.areChannelsBypassingDnd = false;
+        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
+                true);
+
+        // Turn off manual mode, call from a package: don't reset UID even though enabler is set
+        mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null,
+                CUSTOM_PKG_NAME, "", 12345, false);
+
+        // And likewise when turning it back on again
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
+                CUSTOM_PKG_NAME, "", 12345, false);
+
+        // These are 5 events in total.
+        assertEquals(5, mZenModeEventLogger.numLoggedChanges());
+
+        // First event: turns on, UID reassigned for manual mode
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+                mZenModeEventLogger.getEventId(0));
+        assertFalse(mZenModeEventLogger.getIsUserAction(0));
+        assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
+
+        // Second event should be a policy-only change with are channels bypassing = true
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
+                mZenModeEventLogger.getEventId(1));
+        assertTrue(mZenModeEventLogger.getAreChannelsBypassing(1));
+
+        // Third event also a policy-only change but with channels bypassing now false
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId(),
+                mZenModeEventLogger.getEventId(2));
+        assertFalse(mZenModeEventLogger.getAreChannelsBypassing(2));
+
+        // Fourth event: should turn DND off, not have UID reassigned
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
+                mZenModeEventLogger.getEventId(3));
+        assertFalse(mZenModeEventLogger.getIsUserAction(3));
+        assertEquals(12345, mZenModeEventLogger.getPackageUid(3));
+
+        // Fifth event: turn DND back on, not have UID reassigned
+        assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+                mZenModeEventLogger.getEventId(4));
+        assertFalse(mZenModeEventLogger.getIsUserAction(4));
+        assertEquals(12345, mZenModeEventLogger.getPackageUid(4));
+    }
+
     private void setupZenConfig() {
         mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
         mZenModeHelper.mConfig.allowAlarms = false;
@@ -1921,7 +2446,9 @@
         mZenModeHelper.mConfig.allowSystem = false;
         mZenModeHelper.mConfig.allowReminders = true;
         mZenModeHelper.mConfig.allowCalls = true;
+        mZenModeHelper.mConfig.allowCallsFrom = PRIORITY_SENDERS_STARRED;
         mZenModeHelper.mConfig.allowMessages = true;
+        mZenModeHelper.mConfig.allowConversations = true;
         mZenModeHelper.mConfig.allowEvents = true;
         mZenModeHelper.mConfig.allowRepeatCallers = true;
         mZenModeHelper.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
@@ -1935,12 +2462,33 @@
         assertFalse(mZenModeHelper.mConfig.allowSystem);
         assertTrue(mZenModeHelper.mConfig.allowReminders);
         assertTrue(mZenModeHelper.mConfig.allowCalls);
+        assertEquals(PRIORITY_SENDERS_STARRED, mZenModeHelper.mConfig.allowCallsFrom);
         assertTrue(mZenModeHelper.mConfig.allowMessages);
+        assertTrue(mZenModeHelper.mConfig.allowConversations);
         assertTrue(mZenModeHelper.mConfig.allowEvents);
         assertTrue(mZenModeHelper.mConfig.allowRepeatCallers);
         assertEquals(SUPPRESSED_EFFECT_BADGE, mZenModeHelper.mConfig.suppressedVisualEffects);
     }
 
+    private void checkDndProtoMatchesSetupZenConfig(DNDPolicyProto dndProto) {
+        assertEquals(STATE_DISALLOW, dndProto.getAlarms().getNumber());
+        assertEquals(STATE_DISALLOW, dndProto.getMedia().getNumber());
+        assertEquals(STATE_DISALLOW, dndProto.getSystem().getNumber());
+        assertEquals(STATE_ALLOW, dndProto.getReminders().getNumber());
+        assertEquals(STATE_ALLOW, dndProto.getCalls().getNumber());
+        assertEquals(PEOPLE_STARRED, dndProto.getAllowCallsFrom().getNumber());
+        assertEquals(STATE_ALLOW, dndProto.getMessages().getNumber());
+        assertEquals(STATE_ALLOW, dndProto.getEvents().getNumber());
+        assertEquals(STATE_ALLOW, dndProto.getRepeatCallers().getNumber());
+        assertEquals(STATE_ALLOW, dndProto.getFullscreen().getNumber());
+        assertEquals(STATE_ALLOW, dndProto.getLights().getNumber());
+        assertEquals(STATE_ALLOW, dndProto.getPeek().getNumber());
+        assertEquals(STATE_ALLOW, dndProto.getStatusBar().getNumber());
+        assertEquals(STATE_DISALLOW, dndProto.getBadge().getNumber());
+        assertEquals(STATE_ALLOW, dndProto.getAmbient().getNumber());
+        assertEquals(STATE_ALLOW, dndProto.getNotificationList().getNumber());
+    }
+
     /**
      * Wrapper to use TypedXmlPullParser as XmlResourceParser for Resources.getXml()
      */
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 37c4b37..5c3102d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -23,12 +23,15 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyNoMoreInteractions;
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
@@ -389,6 +392,19 @@
     }
 
     @Test
+    public void testInTaskActivityStart() {
+        mTrampolineActivity.setVisible(true);
+        doReturn(true).when(mTrampolineActivity).isReportedDrawn();
+        spyOn(mActivityMetricsLogger);
+
+        onActivityLaunched(mTopActivity);
+        transitToDrawnAndVerifyOnLaunchFinished(mTopActivity);
+
+        verify(mActivityMetricsLogger, timeout(TIMEOUT_MS)).logInTaskActivityStart(
+                any(), anyBoolean(), anyInt());
+    }
+
+    @Test
     public void testOnActivityLaunchFinishedTrampoline() {
         onActivityLaunchedTrampoline();
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 2671e77..2b589bf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -944,7 +944,7 @@
                 anyInt(), anyInt()));
         doReturn(BackgroundStartPrivileges.allowBackgroundActivityStarts(null)).when(
                 () -> PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller(
-                anyObject(), anyInt()));
+                anyObject(), anyInt(), anyObject()));
         runAndVerifyBackgroundActivityStartsSubtest(
                 "allowed_notAborted", false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
index ad9f710..bbec091 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
@@ -79,6 +79,8 @@
     private Task mTask;
     private final ContentRecordingSession mDisplaySession =
             ContentRecordingSession.createDisplaySession(DEFAULT_DISPLAY);
+    private final ContentRecordingSession mWaitingDisplaySession =
+            ContentRecordingSession.createDisplaySession(DEFAULT_DISPLAY);
     private ContentRecordingSession mTaskSession;
     private static Point sSurfaceSize;
     private ContentRecorder mContentRecorder;
@@ -120,6 +122,10 @@
         mTaskSession = ContentRecordingSession.createTaskSession(sTaskWindowContainerToken);
         mTaskSession.setVirtualDisplayId(displayId);
 
+        // GIVEN a session is waiting for the user to review consent.
+        mWaitingDisplaySession.setVirtualDisplayId(displayId);
+        mWaitingDisplaySession.setWaitingForConsent(true);
+
         mConfigListener = new ConfigListener();
         DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
                 mContext.getMainExecutor(), mConfigListener);
@@ -221,6 +227,18 @@
     }
 
     @Test
+    public void testUpdateRecording_waitingForConsent() {
+        mContentRecorder.setContentRecordingSession(mWaitingDisplaySession);
+        mContentRecorder.updateRecording();
+        assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
+
+
+        mContentRecorder.setContentRecordingSession(mDisplaySession);
+        mContentRecorder.updateRecording();
+        assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
+    }
+
+    @Test
     public void testOnConfigurationChanged_neverRecording() {
         mContentRecorder.onConfigurationChanged(ORIENTATION_PORTRAIT);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java
index 6cda038..52226c2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java
@@ -24,10 +24,8 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 
-import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
 import android.view.ContentRecordingSession;
 
@@ -36,6 +34,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 /**
  * Tests for the {@link ContentRecordingController} class.
@@ -49,12 +49,20 @@
 public class ContentRecordingControllerTests extends WindowTestsBase {
     private final ContentRecordingSession mDefaultSession =
             ContentRecordingSession.createDisplaySession(DEFAULT_DISPLAY);
+    private final ContentRecordingSession mWaitingDisplaySession =
+            ContentRecordingSession.createDisplaySession(DEFAULT_DISPLAY);
 
     private int mVirtualDisplayId;
     private DisplayContent mVirtualDisplayContent;
+    private WindowContainer.RemoteToken mRootTaskToken;
+
+    @Mock
+    private WindowContainer mTaskWindowContainer;
 
     @Before
     public void setup() {
+        MockitoAnnotations.initMocks(this);
+
         // GIVEN the VirtualDisplay associated with the session (so the display has state ON).
         mVirtualDisplayContent = new TestDisplayContent.Builder(mAtm, 500, 600).build();
         mVirtualDisplayId = mVirtualDisplayContent.getDisplayId();
@@ -62,6 +70,11 @@
         spyOn(mVirtualDisplayContent);
 
         mDefaultSession.setVirtualDisplayId(mVirtualDisplayId);
+        mWaitingDisplaySession.setVirtualDisplayId(mVirtualDisplayId);
+        mWaitingDisplaySession.setWaitingForConsent(true);
+
+        mRootTaskToken = new WindowContainer.RemoteToken(mTaskWindowContainer);
+        mTaskWindowContainer.mRemoteToken = mRootTaskToken;
     }
 
     @Test
@@ -92,7 +105,7 @@
     }
 
     @Test
-    public void testSetContentRecordingSessionLocked_newDisplaySession_accepted() {
+    public void testSetContentRecordingSessionLocked_newSession_accepted() {
         ContentRecordingController controller = new ContentRecordingController();
         // GIVEN a valid display session.
         // WHEN updating the session.
@@ -104,15 +117,37 @@
     }
 
     @Test
-    public void testSetContentRecordingSessionLocked_updateCurrentDisplaySession_notAccepted() {
+    public void testSetContentRecordingSessionLocked_updateSession_noLongerWaiting_accepted() {
+        ContentRecordingController controller = new ContentRecordingController();
+        // GIVEN a valid display session already in place.
+        controller.setContentRecordingSessionLocked(mWaitingDisplaySession, mWm);
+        verify(mVirtualDisplayContent, atLeastOnce()).setContentRecordingSession(
+                mWaitingDisplaySession);
+
+        // WHEN updating the session on the same display, so no longer waiting to record.
+        ContentRecordingSession sessionUpdate = ContentRecordingSession.createTaskSession(
+                mRootTaskToken.toWindowContainerToken().asBinder());
+        sessionUpdate.setVirtualDisplayId(mVirtualDisplayId);
+        sessionUpdate.setWaitingForConsent(false);
+        controller.setContentRecordingSessionLocked(sessionUpdate, mWm);
+
+        ContentRecordingSession resultingSession = controller.getContentRecordingSessionLocked();
+        // THEN the session was accepted.
+        assertThat(resultingSession).isEqualTo(sessionUpdate);
+        verify(mVirtualDisplayContent, atLeastOnce()).setContentRecordingSession(sessionUpdate);
+        verify(mVirtualDisplayContent).updateRecording();
+    }
+
+    @Test
+    public void testSetContentRecordingSessionLocked_invalidUpdateSession_notWaiting_notAccepted() {
         ContentRecordingController controller = new ContentRecordingController();
         // GIVEN a valid display session already in place.
         controller.setContentRecordingSessionLocked(mDefaultSession, mWm);
         verify(mVirtualDisplayContent, atLeastOnce()).setContentRecordingSession(mDefaultSession);
 
         // WHEN updating the session on the same display.
-        ContentRecordingSession sessionUpdate =
-                ContentRecordingSession.createTaskSession(mock(IBinder.class));
+        ContentRecordingSession sessionUpdate = ContentRecordingSession.createTaskSession(
+                mRootTaskToken.toWindowContainerToken().asBinder());
         sessionUpdate.setVirtualDisplayId(mVirtualDisplayId);
         controller.setContentRecordingSessionLocked(sessionUpdate, mWm);
 
@@ -123,7 +158,7 @@
     }
 
     @Test
-    public void testSetContentRecordingSessionLocked_disableCurrentDisplaySession_accepted() {
+    public void testSetContentRecordingSessionLocked_disableCurrentSession_accepted() {
         ContentRecordingController controller = new ContentRecordingController();
         // GIVEN a valid display session already in place.
         controller.setContentRecordingSessionLocked(mDefaultSession, mWm);
@@ -141,7 +176,7 @@
     }
 
     @Test
-    public void testSetContentRecordingSessionLocked_takeOverCurrentDisplaySession_accepted() {
+    public void testSetContentRecordingSessionLocked_takeOverCurrentSession_accepted() {
         ContentRecordingController controller = new ContentRecordingController();
         // GIVEN a valid display session already in place.
         controller.setContentRecordingSessionLocked(mDefaultSession, mWm);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
index 9d1fde4..b515a9d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
@@ -34,6 +34,8 @@
 
 import com.android.internal.R;
 
+import com.google.common.util.concurrent.MoreExecutors;
+
 import org.junit.Before;
 import org.junit.Test;
 
@@ -117,7 +119,7 @@
     public void testUnregisterDeviceStateCallback() {
         initialize(true /* supportFold */, true /* supportHalfFolded */);
         assertEquals(1, mTarget.mDeviceStateCallbacks.size());
-        assertEquals(mDelegate, mTarget.mDeviceStateCallbacks.get(0));
+        assertTrue(mTarget.mDeviceStateCallbacks.containsKey(mDelegate));
 
         mTarget.onStateChanged(mOpenDeviceStates[0]);
         assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
@@ -194,8 +196,9 @@
             when(mMockContext.getResources()).thenReturn((mockRes));
             mockFold(mSupportFold, mSupportHalfFold);
             Handler mockHandler = mock(Handler.class);
-            mTarget = new DeviceStateController(mMockContext, mockHandler);
-            mTarget.registerDeviceStateCallback(mDelegate);
+            mTarget = new DeviceStateController(mMockContext, mockHandler,
+                    new WindowManagerGlobalLock());
+            mTarget.registerDeviceStateCallback(mDelegate, MoreExecutors.directExecutor());
         }
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 8ac6b0f..5ec3604 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -301,6 +301,33 @@
     }
 
     @Test
+    public void testSwitchDecorInsets() {
+        createNavBarWithProvidedInsets(mDisplayContent);
+        final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
+        final DisplayInfo info = mDisplayContent.getDisplayInfo();
+        final int w = info.logicalWidth;
+        final int h = info.logicalHeight;
+        displayPolicy.updateDecorInsetsInfo();
+        final Rect prevConfigFrame = new Rect(displayPolicy.getDecorInsetsInfo(info.rotation,
+                info.logicalWidth, info.logicalHeight).mConfigFrame);
+
+        displayPolicy.updateCachedDecorInsets();
+        mDisplayContent.updateBaseDisplayMetrics(w / 2, h / 2,
+                info.logicalDensityDpi, info.physicalXDpi, info.physicalYDpi);
+        // There is no previous cache. But the current state will be cached.
+        assertFalse(displayPolicy.shouldKeepCurrentDecorInsets());
+
+        // Switch to original state.
+        displayPolicy.updateCachedDecorInsets();
+        mDisplayContent.updateBaseDisplayMetrics(w, h,
+                info.logicalDensityDpi, info.physicalXDpi, info.physicalYDpi);
+        assertTrue(displayPolicy.shouldKeepCurrentDecorInsets());
+        // The current insets are restored from cache directly.
+        assertEquals(prevConfigFrame, displayPolicy.getDecorInsetsInfo(info.rotation,
+                info.logicalWidth, info.logicalHeight).mConfigFrame);
+    }
+
+    @Test
     public void testUpdateDisplayConfigurationByDecor() {
         doReturn(NO_CUTOUT).when(mDisplayContent).calculateDisplayCutoutForRotation(anyInt());
         final WindowState navbar = createNavBarWithProvidedInsets(mDisplayContent);
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index d1d83f6..d7e736d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -25,6 +25,7 @@
 import static android.view.WindowInsets.Type.statusBars;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 
@@ -38,6 +39,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.spy;
@@ -420,10 +422,10 @@
 
     @Test
     public void testUpdateAboveInsetsState_zOrderChanged() {
-        final WindowState ime = createTestWindow("ime");
-        final WindowState app = createTestWindow("app");
-        final WindowState statusBar = createTestWindow("statusBar");
-        final WindowState navBar = createTestWindow("navBar");
+        final WindowState ime = createNonAppWindow("ime");
+        final WindowState app = createNonAppWindow("app");
+        final WindowState statusBar = createNonAppWindow("statusBar");
+        final WindowState navBar = createNonAppWindow("navBar");
 
         final InsetsSourceProvider imeSourceProvider =
                 getController().getOrCreateSourceProvider(ID_IME, ime());
@@ -431,7 +433,9 @@
 
         waitUntilHandlersIdle();
         clearInvocations(mDisplayContent);
+        imeSourceProvider.updateControlForTarget(app, false /* force */);
         imeSourceProvider.setClientVisible(true);
+        verify(mDisplayContent).assignWindowLayers(anyBoolean());
         waitUntilHandlersIdle();
         // The visibility change should trigger a traversal to notify the change.
         verify(mDisplayContent).notifyInsetsChanged(any());
@@ -547,6 +551,7 @@
                 control2.getInsetsHint().bottom);
     }
 
+    /** Creates a window which is associated with ActivityRecord. */
     private WindowState createTestWindow(String name) {
         final WindowState win = createWindow(null, TYPE_APPLICATION, name);
         win.setHasSurface(true);
@@ -554,6 +559,14 @@
         return win;
     }
 
+    /** Creates a non-activity window. */
+    private WindowState createNonAppWindow(String name) {
+        final WindowState win = createWindow(null, LAST_APPLICATION_WINDOW + 1, name);
+        win.setHasSurface(true);
+        spyOn(win);
+        return win;
+    }
+
     private InsetsStateController getController() {
         return mDisplayContent.getInsetsStateController();
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
index 03c93e9..7d507e9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.wm;
 
+import static android.content.pm.ActivityInfo.FORCE_NON_RESIZE_APP;
+import static android.content.pm.ActivityInfo.FORCE_RESIZE_APP;
 import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION;
 import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
 import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
@@ -24,6 +26,7 @@
 import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
 import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
 import static android.content.pm.ActivityInfo.OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO;
 import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
 import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR;
 import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT;
@@ -40,7 +43,9 @@
 import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE;
 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
 import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;
 import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
 
@@ -453,6 +458,29 @@
     }
 
     @Test
+    public void testGetCropBoundsIfNeeded_handleCropForTransparentActivityBasedOnOpaqueBounds() {
+        final InsetsSource taskbar = new InsetsSource(/*id=*/ 0,
+                 WindowInsets.Type.navigationBars());
+        taskbar.setInsetsRoundedCornerFrame(true);
+        final WindowState mainWindow = mockForGetCropBoundsAndRoundedCorners(taskbar);
+        final Rect opaqueBounds = new Rect(0, 0, 500, 300);
+        doReturn(opaqueBounds).when(mActivity).getBounds();
+        // Activity is translucent
+        spyOn(mActivity.mLetterboxUiController);
+        doReturn(true).when(mActivity.mLetterboxUiController).hasInheritedLetterboxBehavior();
+
+        // Makes requested sizes different
+        mainWindow.mRequestedWidth = opaqueBounds.width() - 1;
+        mainWindow.mRequestedHeight = opaqueBounds.height() - 1;
+        assertNull(mActivity.mLetterboxUiController.getCropBoundsIfNeeded(mainWindow));
+
+        // Makes requested sizes equals
+        mainWindow.mRequestedWidth = opaqueBounds.width();
+        mainWindow.mRequestedHeight = opaqueBounds.height();
+        assertNotNull(mActivity.mLetterboxUiController.getCropBoundsIfNeeded(mainWindow));
+    }
+
+    @Test
     public void testGetCropBoundsIfNeeded_noCrop() {
         final InsetsSource taskbar = new InsetsSource(/*id=*/ 0,
                 WindowInsets.Type.navigationBars());
@@ -861,6 +889,174 @@
     }
 
     @Test
+    @EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO})
+    public void testshouldOverrideMinAspectRatio_overrideEnabled_returnsTrue() {
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertTrue(mController.shouldOverrideMinAspectRatio());
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO})
+    public void testshouldOverrideMinAspectRatio_propertyTrue_overrideEnabled_returnsTrue()
+            throws Exception {
+        mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertTrue(mController.shouldOverrideMinAspectRatio());
+    }
+
+    @Test
+    @DisableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO})
+    public void testshouldOverrideMinAspectRatio_propertyTrue_overrideDisabled_returnsFalse()
+            throws Exception {
+        mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldOverrideMinAspectRatio());
+    }
+
+    @Test
+    @DisableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO})
+    public void testshouldOverrideMinAspectRatio_overrideDisabled_returnsFalse() {
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldOverrideMinAspectRatio());
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO})
+    public void testshouldOverrideMinAspectRatio_propertyFalse_overrideEnabled_returnsFalse()
+            throws Exception {
+        mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ false);
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldOverrideMinAspectRatio());
+    }
+
+    @Test
+    @DisableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO})
+    public void testshouldOverrideMinAspectRatio_propertyFalse_noOverride_returnsFalse()
+            throws Exception {
+        mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ false);
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldOverrideMinAspectRatio());
+    }
+
+    @Test
+    @EnableCompatChanges({FORCE_RESIZE_APP})
+    public void testshouldOverrideForceResizeApp_overrideEnabled_returnsTrue() {
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertTrue(mController.shouldOverrideForceResizeApp());
+    }
+
+    @Test
+    @EnableCompatChanges({FORCE_RESIZE_APP})
+    public void testshouldOverrideForceResizeApp_propertyTrue_overrideEnabled_returnsTrue()
+            throws Exception {
+        mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ true);
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertTrue(mController.shouldOverrideForceResizeApp());
+    }
+
+    @Test
+    @DisableCompatChanges({FORCE_RESIZE_APP})
+    public void testshouldOverrideForceResizeApp_propertyTrue_overrideDisabled_returnsFalse()
+            throws Exception {
+        mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ true);
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldOverrideForceResizeApp());
+    }
+
+    @Test
+    @DisableCompatChanges({FORCE_RESIZE_APP})
+    public void testshouldOverrideForceResizeApp_overrideDisabled_returnsFalse() {
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldOverrideForceResizeApp());
+    }
+
+    @Test
+    @EnableCompatChanges({FORCE_RESIZE_APP})
+    public void testshouldOverrideForceResizeApp_propertyFalse_overrideEnabled_returnsFalse()
+            throws Exception {
+        mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ false);
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldOverrideForceResizeApp());
+    }
+
+    @Test
+    @DisableCompatChanges({FORCE_RESIZE_APP})
+    public void testshouldOverrideForceResizeApp_propertyFalse_noOverride_returnsFalse()
+            throws Exception {
+        mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ false);
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldOverrideForceResizeApp());
+    }
+
+    @Test
+    @EnableCompatChanges({FORCE_NON_RESIZE_APP})
+    public void testshouldOverrideForceNonResizeApp_overrideEnabled_returnsTrue() {
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertTrue(mController.shouldOverrideForceNonResizeApp());
+    }
+
+    @Test
+    @EnableCompatChanges({FORCE_NON_RESIZE_APP})
+    public void testshouldOverrideForceNonResizeApp_propertyTrue_overrideEnabled_returnsTrue()
+            throws Exception {
+        mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ true);
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertTrue(mController.shouldOverrideForceNonResizeApp());
+    }
+
+    @Test
+    @DisableCompatChanges({FORCE_NON_RESIZE_APP})
+    public void testshouldOverrideForceNonResizeApp_propertyTrue_overrideDisabled_returnsFalse()
+            throws Exception {
+        mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ true);
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldOverrideForceNonResizeApp());
+    }
+
+    @Test
+    @DisableCompatChanges({FORCE_NON_RESIZE_APP})
+    public void testshouldOverrideForceNonResizeApp_overrideDisabled_returnsFalse() {
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldOverrideForceNonResizeApp());
+    }
+
+    @Test
+    @EnableCompatChanges({FORCE_NON_RESIZE_APP})
+    public void testshouldOverrideForceNonResizeApp_propertyFalse_overrideEnabled_returnsFalse()
+            throws Exception {
+        mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ false);
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldOverrideForceNonResizeApp());
+    }
+
+    @Test
+    @DisableCompatChanges({FORCE_NON_RESIZE_APP})
+    public void testshouldOverrideForceNonResizeApp_propertyFalse_noOverride_returnsFalse()
+            throws Exception {
+        mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ false);
+        mController = new LetterboxUiController(mWm, mActivity);
+
+        assertFalse(mController.shouldOverrideForceNonResizeApp());
+    }
+
+    @Test
     public void testgetFixedOrientationLetterboxAspectRatio_splitScreenAspectEnabled() {
         doReturn(true).when(mActivity.mWmService.mLetterboxConfiguration)
                 .isCameraCompatTreatmentEnabled(anyBoolean());
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 10f4158..0ccb0d0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -1286,7 +1286,7 @@
             doReturn(bufferSize.x).when(buffer).getWidth();
             doReturn(bufferSize.y).when(buffer).getHeight();
         }
-        return new TaskSnapshot(1, new ComponentName("", ""), buffer,
+        return new TaskSnapshot(1, 0 /* captureTime */, new ComponentName("", ""), buffer,
                 ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
                 Surface.ROTATION_0, taskSize, new Rect() /* contentInsets */,
                 new Rect() /* letterboxInsets*/, false /* isLowResolution */,
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 7092b0b..6e52af1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -298,8 +298,6 @@
         assertTrue(mController.isAnimatingTask(activity.getTask()));
 
         spyOn(mWm.mTaskSnapshotController);
-        doNothing().when(mWm.mTaskSnapshotController).notifyAppVisibilityChanged(any(),
-                anyBoolean());
         doReturn(mMockTaskSnapshot).when(mWm.mTaskSnapshotController).getSnapshot(anyInt(),
                 anyInt(), eq(false) /* restoreFromDisk */, eq(false) /* isLowResolution */);
         mController.setDeferredCancel(true /* deferred */, true /* screenshot */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 06bcbf3..2dd34eb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -3511,6 +3511,51 @@
     }
 
     @Test
+    public void testLetterboxAlignedToBottom_NotOverlappingNavbar() {
+        assertLandscapeActivityAlignedToBottomWithNavbar(false /* immersive */);
+    }
+
+    @Test
+    public void testImmersiveLetterboxAlignedToBottom_OverlappingNavbar() {
+        assertLandscapeActivityAlignedToBottomWithNavbar(true /* immersive */);
+    }
+
+    private void assertLandscapeActivityAlignedToBottomWithNavbar(boolean immersive) {
+        final int screenHeight = 2800;
+        final int screenWidth = 1400;
+        final int taskbarHeight = 200;
+        setUpDisplaySizeWithApp(screenWidth, screenHeight);
+
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true);
+        mActivity.mWmService.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(1.0f);
+
+        final InsetsSource navSource = new InsetsSource(
+                InsetsSource.createId(null, 0, navigationBars()), navigationBars());
+        navSource.setInsetsRoundedCornerFrame(true);
+        // Immersive activity has transient navbar
+        navSource.setVisible(!immersive);
+        navSource.setFrame(new Rect(0, screenHeight - taskbarHeight, screenWidth, screenHeight));
+        mActivity.mWmService.mLetterboxConfiguration.setLetterboxActivityCornersRadius(15);
+
+        final WindowState w1 = addWindowToActivity(mActivity);
+        w1.mAboveInsetsState.addSource(navSource);
+
+        // Prepare unresizable landscape activity
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
+        final DisplayPolicy displayPolicy = mActivity.mDisplayContent.getDisplayPolicy();
+        doReturn(immersive).when(displayPolicy).isImmersiveMode();
+
+        mActivity.mRootWindowContainer.performSurfacePlacement();
+
+        LetterboxDetails letterboxDetails = mActivity.mLetterboxUiController.getLetterboxDetails();
+
+        // Letterboxed activity at bottom
+        assertEquals(new Rect(0, 2100, 1400, 2800), mActivity.getBounds());
+        final int expectedHeight = immersive ? screenHeight : screenHeight - taskbarHeight;
+        assertEquals(expectedHeight, letterboxDetails.getLetterboxInnerBounds().bottom);
+    }
+
+    @Test
     public void testSplitScreenLetterboxDetailsForStatusBar_twoLetterboxedApps() {
         mAtm.mDevEnableNonResizableMultiWindow = true;
         setUpDisplaySizeWithApp(2800, 1000);
@@ -3938,7 +3983,7 @@
         mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         mWm.mLetterboxConfiguration.setIsAutomaticReachabilityInBookModeEnabled(true);
         mWm.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
-                1.0f /*letterboxVerticalPositionMultiplier*/);
+                1.0f /*letterboxHorizontalPositionMultiplier*/);
         prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
 
         Rect letterboxNoFold = new Rect(2100, 0, 2800, 1400);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
index 5eebe74..fc5e9ca 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
@@ -18,6 +18,7 @@
 
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
@@ -119,6 +120,22 @@
         assertTrue(mockWC.onSyncFinishedDrawing());
         bse.onSurfacePlacement();
         verify(listener, times(1)).onTransactionReady(eq(id), notNull());
+
+        // The sync is not finished for a relaunching activity.
+        id = startSyncSet(bse, listener);
+        final ActivityRecord r = new ActivityBuilder(mAtm).setCreateTask(true).build();
+        final WindowState w = mock(WindowState.class);
+        doReturn(true).when(w).isVisibleRequested();
+        doReturn(true).when(w).fillsParent();
+        doReturn(true).when(w).isSyncFinished(any());
+        r.mChildren.add(w);
+        bse.addToSyncSet(id, r);
+        r.onSyncFinishedDrawing();
+        assertTrue(r.isSyncFinished(r.getSyncGroup()));
+        r.startRelaunching();
+        assertFalse(r.isSyncFinished(r.getSyncGroup()));
+        r.finishRelaunching();
+        assertTrue(r.isSyncFinished(r.getSyncGroup()));
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
index 4c7b0aa0..91256ee 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
@@ -75,7 +75,7 @@
         final ArraySet<ActivityRecord> closingApps = new ArraySet<>();
         closingApps.add(closingWindow.mActivityRecord);
         final ArraySet<Task> closingTasks = new ArraySet<>();
-        mWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
+        getClosingTasks(closingApps, closingTasks);
         assertEquals(1, closingTasks.size());
         assertEquals(closingWindow.mActivityRecord.getTask(), closingTasks.valueAt(0));
     }
@@ -93,7 +93,7 @@
         final ArraySet<ActivityRecord> closingApps = new ArraySet<>();
         closingApps.add(closingWindow.mActivityRecord);
         final ArraySet<Task> closingTasks = new ArraySet<>();
-        mWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
+        getClosingTasks(closingApps, closingTasks);
         assertEquals(0, closingTasks.size());
     }
 
@@ -108,10 +108,23 @@
         final ArraySet<Task> closingTasks = new ArraySet<>();
         mWm.mTaskSnapshotController.addSkipClosingAppSnapshotTasks(
                 Sets.newArraySet(closingWindow.mActivityRecord.getTask()));
-        mWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
+        getClosingTasks(closingApps, closingTasks);
         assertEquals(0, closingTasks.size());
     }
 
+    /** Retrieves all closing tasks based on the list of closing apps during an app transition. */
+    private void getClosingTasks(ArraySet<ActivityRecord> closingApps,
+            ArraySet<Task> outClosingTasks) {
+        outClosingTasks.clear();
+        for (int i = closingApps.size() - 1; i >= 0; i--) {
+            final ActivityRecord activity = closingApps.valueAt(i);
+            final Task task = activity.getTask();
+            if (task == null) continue;
+
+            mWm.mTaskSnapshotController.getClosingTasksInner(task, outClosingTasks);
+        }
+    }
+
     @Test
     public void testGetSnapshotMode() {
         final WindowState disabledWindow = createWindow(null,
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
index b69874a..84c0696 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -218,7 +218,7 @@
             Canvas c = buffer.lockCanvas();
             c.drawColor(Color.RED);
             buffer.unlockCanvasAndPost(c);
-            return new TaskSnapshot(MOCK_SNAPSHOT_ID, mTopActivityComponent,
+            return new TaskSnapshot(MOCK_SNAPSHOT_ID, 0 /* captureTime */, mTopActivityComponent,
                     HardwareBuffer.createFromGraphicBuffer(buffer),
                     ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
                     mRotation, taskSize, TEST_CONTENT_INSETS, TEST_LETTERBOX_INSETS,
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index adf3f39..192632c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -18,6 +18,8 @@
 
 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 
+import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
+
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -354,4 +356,9 @@
     public boolean isGlobalKey(int keyCode) {
         return false;
     }
+
+    @Override
+    public int getLidState() {
+        return LID_ABSENT;
+    }
 }
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index a98429a..cf236dd 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -2539,10 +2539,19 @@
         }
 
         @Override
-        public void reportChooserSelection(String packageName, int userId, String contentType,
-                                           String[] annotations, String action) {
+        public void reportChooserSelection(@NonNull String packageName, int userId,
+                @NonNull String contentType, String[] annotations, @NonNull String action) {
             if (packageName == null) {
-                Slog.w(TAG, "Event report user selecting a null package");
+                throw new IllegalArgumentException("Package selection must not be null.");
+            }
+            // A valid contentType and action must be provided for chooser selection events.
+            if (contentType == null || contentType.isBlank()
+                    || action == null || action.isBlank()) {
+                return;
+            }
+            // Verify if this package exists before reporting an event for it.
+            if (mPackageManagerInternal.getPackageUid(packageName, 0, userId) < 0) {
+                Slog.w(TAG, "Event report user selecting an invalid package");
                 return;
             }
 
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 9fb5509..13945a1 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -366,10 +366,10 @@
             try {
                 int uid = mPackageManager.getPackageUid(mOriginatorIdentity.packageName,
                         PackageManager.PackageInfoFlags.of(0));
-                if (uid != mOriginatorIdentity.uid) {
-                    throw new SecurityException("Package name: " +
-                            mOriginatorIdentity.packageName + "with uid: " + uid
-                            + "attempted to spoof as: " + mOriginatorIdentity.uid);
+                if (!UserHandle.isSameApp(uid, mOriginatorIdentity.uid)) {
+                    throw new SecurityException("Uid " + mOriginatorIdentity.uid +
+                            " attempted to spoof package name " +
+                            mOriginatorIdentity.packageName + " with uid: " + uid);
                 }
             } catch (PackageManager.NameNotFoundException e) {
                 throw new SecurityException("Package name not found: "
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java b/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java
index f70268e..e793f31 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java
@@ -168,9 +168,18 @@
      * Attached to the HAL service via factory.
      */
     private void attachToHal() {
-        mHalService = new SoundTriggerHalEnforcer(
-                new SoundTriggerHalWatchdog(
-                    new SoundTriggerDuplicateModelHandler(mHalFactory.create())));
+        mHalService = null;
+        while (mHalService == null) {
+            try {
+                mHalService = new SoundTriggerHalEnforcer(
+                        new SoundTriggerHalWatchdog(
+                            new SoundTriggerDuplicateModelHandler(mHalFactory.create())));
+            } catch (RuntimeException e) {
+                if (!(e.getCause() instanceof RemoteException)) {
+                    throw e;
+                }
+            }
+        }
         mHalService.linkToDeath(this);
         mHalService.registerCallback(this);
         mProperties = mHalService.getProperties();
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java
index 3a65104..7598952 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java
@@ -84,6 +84,7 @@
 import com.android.internal.app.IHotwordRecognitionStatusCallback;
 import com.android.internal.infra.AndroidFuture;
 import com.android.server.LocalServices;
+import com.android.server.policy.AppOpsPolicy;
 import com.android.server.voiceinteraction.VoiceInteractionManagerServiceImpl.DetectorRemoteExceptionListener;
 
 import java.io.Closeable;
@@ -742,18 +743,24 @@
     void enforcePermissionsForDataDelivery() {
         Binder.withCleanCallingIdentity(() -> {
             synchronized (mLock) {
-                int result = PermissionChecker.checkPermissionForPreflight(
-                        mContext, RECORD_AUDIO, /* pid */ -1, mVoiceInteractorIdentity.uid,
-                        mVoiceInteractorIdentity.packageName);
-                if (result != PermissionChecker.PERMISSION_GRANTED) {
-                    throw new SecurityException(
-                        "Failed to obtain permission RECORD_AUDIO for identity "
-                        + mVoiceInteractorIdentity);
+                if (AppOpsPolicy.isHotwordDetectionServiceRequired(mContext.getPackageManager())) {
+                    int result = PermissionChecker.checkPermissionForPreflight(
+                            mContext, RECORD_AUDIO, /* pid */ -1, mVoiceInteractorIdentity.uid,
+                            mVoiceInteractorIdentity.packageName);
+                    if (result != PermissionChecker.PERMISSION_GRANTED) {
+                        throw new SecurityException(
+                                "Failed to obtain permission RECORD_AUDIO for identity "
+                                        + mVoiceInteractorIdentity);
+                    }
+                    int hotwordOp = AppOpsManager.strOpToOp(
+                            AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD);
+                    mAppOpsManager.noteOpNoThrow(hotwordOp,
+                            mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName,
+                            mVoiceInteractorIdentity.attributionTag, HOTWORD_DETECTION_OP_MESSAGE);
+                } else {
+                    enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity,
+                            RECORD_AUDIO, HOTWORD_DETECTION_OP_MESSAGE);
                 }
-                int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD);
-                mAppOpsManager.noteOpNoThrow(hotwordOp,
-                        mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName,
-                        mVoiceInteractorIdentity.attributionTag, HOTWORD_DETECTION_OP_MESSAGE);
                 enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity,
                         CAPTURE_AUDIO_HOTWORD, HOTWORD_DETECTION_OP_MESSAGE);
             }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index edaaf3f..248cc26 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -962,7 +962,7 @@
         final DetectorSession session = mDetectorSessions.get(
                 HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR);
         if (session == null || session.isDestroyed()) {
-            Slog.v(TAG, "Not found the look and talk perceiver");
+            Slog.v(TAG, "Not found the visual query detector");
             return null;
         }
         return (VisualQueryDetectorSession) session;
diff --git a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
index f9b76f4..9a8c965 100644
--- a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
+++ b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
@@ -32,7 +32,6 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.provider.DeviceConfig;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.TelephonyManager;
@@ -262,9 +261,6 @@
      */
     public static void showSwitchToManagedProfileDialogIfAppropriate(Context context,
             int subId, int callingUid, String callingPackage) {
-        if (!isSwitchToManagedProfileDialogFlagEnabled()) {
-            return;
-        }
         final long token = Binder.clearCallingIdentity();
         try {
             UserHandle callingUserHandle = UserHandle.getUserHandleForUid(callingUid);
@@ -302,11 +298,6 @@
         }
     }
 
-    public static boolean isSwitchToManagedProfileDialogFlagEnabled() {
-        return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
-                "enable_switch_to_managed_profile_dialog", false);
-    }
-
     private static boolean isUidForeground(Context context, int uid) {
         ActivityManager am = context.getSystemService(ActivityManager.class);
         boolean result = am != null && am.getUidImportance(uid)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/TEST_MAPPING b/tests/FlickerTests/src/com/android/server/wm/flicker/TEST_MAPPING
deleted file mode 100644
index 945de33..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/TEST_MAPPING
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "ironwood-postsubmit": [
-    {
-      "name": "FlickerTests",
-      "options": [
-        {
-          "include-annotation": "android.platform.test.annotations.IwTest"
-        },
-        {
-          "exclude-annotation": "org.junit.Ignore"
-        }
-      ]
-    }
-  ]
-}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt
index 7f496d8..122a6cb 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt
@@ -17,6 +17,7 @@
 package com.android.server.wm.flicker.ime
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
 import android.tools.common.traces.component.ComponentNameMatcher
@@ -102,6 +103,7 @@
 
     @Presubmit
     @Test
+    @PlatinumTest(focusArea = "ime")
     @IwTest(focusArea = "ime")
     override fun cujCompleted() {
         super.cujCompleted()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt
index c693ca7..5aa4382 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt
@@ -17,6 +17,7 @@
 package com.android.server.wm.flicker.ime
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -103,6 +104,7 @@
 
     @Presubmit
     @Test
+    @PlatinumTest(focusArea = "ime")
     @IwTest(focusArea = "ime")
     override fun cujCompleted() {
         super.cujCompleted()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
index d5208e0..6731089 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
@@ -18,6 +18,7 @@
 
 import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -71,6 +72,7 @@
 
     @Presubmit
     @Test
+    @PlatinumTest(focusArea = "ime")
     @IwTest(focusArea = "ime")
     override fun cujCompleted() {
         runAndIgnoreAssumptionViolation { entireScreenCovered() }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTest.kt
index d133529..c70e3cb 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTest.kt
@@ -17,6 +17,7 @@
 package com.android.server.wm.flicker.ime
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.Rotation
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -52,6 +53,7 @@
 
     @Presubmit
     @Test
+    @PlatinumTest(focusArea = "ime")
     @IwTest(focusArea = "ime")
     override fun cujCompleted() {
         super.cujCompleted()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index 855ea3e..7fbcfec 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -17,6 +17,7 @@
 package com.android.server.wm.flicker.rotation
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.traces.component.ComponentNameMatcher
 import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -129,6 +130,7 @@
     }
 
     @Test
+    @PlatinumTest(focusArea = "framework")
     @IwTest(focusArea = "framework")
     override fun cujCompleted() {
         super.cujCompleted()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index 0cbbb83..44ae14a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -17,6 +17,7 @@
 package com.android.server.wm.flicker.rotation
 
 import android.platform.test.annotations.IwTest
+import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.common.ScenarioBuilder
 import android.tools.common.traces.component.ComponentNameMatcher
@@ -213,6 +214,7 @@
     }
 
     @Test
+    @PlatinumTest(focusArea = "framework")
     @IwTest(focusArea = "framework")
     override fun cujCompleted() {
         appWindowFullScreen()
diff --git a/tests/Internal/src/android/app/WallpaperColorsTest.java b/tests/Internal/src/android/app/WallpaperColorsTest.java
index 9ffb236..70660a0 100644
--- a/tests/Internal/src/android/app/WallpaperColorsTest.java
+++ b/tests/Internal/src/android/app/WallpaperColorsTest.java
@@ -48,10 +48,10 @@
     }
 
     /**
-     * Check that white supports dark text and black doesn't
+     * Check that white surface supports dark text
      */
     @Test
-    public void colorHintsTest() {
+    public void whiteSurfaceColorHintsTest() {
         Bitmap image = Bitmap.createBitmap(30, 30, Bitmap.Config.ARGB_8888);
         Canvas canvas = new Canvas(image);
 
@@ -59,28 +59,68 @@
         int hints = WallpaperColors.fromBitmap(image).getColorHints();
         boolean supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
         boolean supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
-        boolean fromBitmap = (hints & WallpaperColors.HINT_FROM_BITMAP) != 0;
         Assert.assertTrue("White surface should support dark text.", supportsDarkText);
         Assert.assertFalse("White surface shouldn't support dark theme.", supportsDarkTheme);
-        Assert.assertTrue("From bitmap should be true if object was created "
-                + "using WallpaperColors#fromBitmap.", fromBitmap);
-
-        canvas.drawColor(Color.BLACK);
-        hints = WallpaperColors.fromBitmap(image).getColorHints();
-        supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
-        supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
-        Assert.assertFalse("Black surface shouldn't support dark text.", supportsDarkText);
-        Assert.assertTrue("Black surface should support dark theme.", supportsDarkTheme);
 
         Paint paint = new Paint();
         paint.setStyle(Paint.Style.FILL);
         paint.setColor(Color.BLACK);
-        canvas.drawColor(Color.WHITE);
         canvas.drawRect(0, 0, 8, 8, paint);
         supportsDarkText = (WallpaperColors.fromBitmap(image)
                 .getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
         Assert.assertFalse("Light surface shouldn't support dark text "
                 + "when it contains dark pixels.", supportsDarkText);
+    }
+
+    /**
+     * Check that x-small white region supports dark text when max number of dark pixels = 0
+     */
+    @Test
+    public void xSmallWhiteSurfaceColorHintsTest() {
+        Bitmap xsmall_image = Bitmap.createBitmap(1, 5, Bitmap.Config.ARGB_8888);
+        Canvas xsmall_canvas = new Canvas(xsmall_image);
+
+        xsmall_canvas.drawColor(Color.WHITE);
+        int hints = WallpaperColors.fromBitmap(xsmall_image).getColorHints();
+        boolean supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
+        boolean supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
+        Assert.assertTrue("X-small white surface should support dark text.",
+                supportsDarkText);
+        Assert.assertFalse("X-small white surface shouldn't support dark theme.",
+                supportsDarkTheme);
+    }
+
+    /**
+     * Check that black surface doesn't support dark text
+     */
+    @Test
+    public void blackSurfaceColorHintsTest() {
+        Bitmap image = Bitmap.createBitmap(30, 30, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(image);
+
+        canvas.drawColor(Color.BLACK);
+        int hints = WallpaperColors.fromBitmap(image).getColorHints();
+        boolean supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
+        boolean supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
+        Assert.assertFalse("Black surface shouldn't support dark text.", supportsDarkText);
+        Assert.assertTrue("Black surface should support dark theme.", supportsDarkTheme);
+    }
+
+    /**
+     * Check that bitmap hint properly indicates when object created via WallpaperColors#fromBitmap
+     * versus WallpaperColors() public constructor
+     */
+    @Test
+    public void bitmapHintsTest() {
+        Bitmap image = Bitmap.createBitmap(30, 30, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(image);
+
+        canvas.drawColor(Color.WHITE);
+        int hints = WallpaperColors.fromBitmap(image).getColorHints();
+
+        boolean fromBitmap = (hints & WallpaperColors.HINT_FROM_BITMAP) != 0;
+        Assert.assertTrue("From bitmap should be true if object was created "
+                + "using WallpaperColors#fromBitmap.", fromBitmap);
 
         WallpaperColors colors = new WallpaperColors(Color.valueOf(Color.GREEN), null, null);
         fromBitmap = (colors.getColorHints() & WallpaperColors.HINT_FROM_BITMAP) != 0;
diff --git a/tests/Internal/src/com/android/internal/app/AppLocaleCollectorTest.java b/tests/Internal/src/com/android/internal/app/AppLocaleCollectorTest.java
index 7d9a6a5..d16e90e 100644
--- a/tests/Internal/src/com/android/internal/app/AppLocaleCollectorTest.java
+++ b/tests/Internal/src/com/android/internal/app/AppLocaleCollectorTest.java
@@ -37,9 +37,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Locale;
 import java.util.Set;
 
@@ -54,7 +54,7 @@
     private LocaleStore.LocaleInfo mAppCurrentLocale;
     private Set<LocaleInfo> mAllAppActiveLocales;
     private Set<LocaleInfo> mImeLocales;
-    private List<LocaleInfo> mSystemCurrentLocales;
+    private Set<LocaleInfo> mSystemCurrentLocales;
     private Set<LocaleInfo> mSystemSupportedLocales;
     private AppLocaleStore.AppLocaleResult mResult;
     private static final String PKG1 = "pkg1";
@@ -73,14 +73,6 @@
     public void setUp() throws Exception {
         mAppLocaleCollector = spy(
                 new AppLocaleCollector(InstrumentationRegistry.getContext(), PKG1));
-
-        mAppCurrentLocale = createLocaleInfo("en-US", CURRENT);
-        mAllAppActiveLocales = initAllAppActivatedLocales();
-        mImeLocales = initImeLocales();
-        mSystemSupportedLocales = initSystemSupportedLocales();
-        mSystemCurrentLocales = initSystemCurrentLocales();
-        mResult = new AppLocaleStore.AppLocaleResult(GET_SUPPORTED_LANGUAGE_FROM_LOCAL_CONFIG,
-                initAppSupportedLocale());
     }
 
     @Test
@@ -88,7 +80,7 @@
         LocaleList.setDefault(
                 LocaleList.forLanguageTags("en-US-u-mu-fahrenhe,ar-JO-u-mu-fahrenhe-nu-latn"));
 
-        List<LocaleStore.LocaleInfo> list =
+        Set<LocaleStore.LocaleInfo> list =
                 mAppLocaleCollector.getSystemCurrentLocales();
 
         LocaleList expected = LocaleList.forLanguageTags("en-US,ar-JO-u-nu-latn");
@@ -99,7 +91,69 @@
     }
 
     @Test
-    public void testGetSupportedLocaleList() {
+    public void testGetSupportedLocaleList_filterNonAppsupportedSystemLanguage() {
+        mAppCurrentLocale = createLocaleInfo("en-US", CURRENT);
+
+        // App supports five locales
+        HashSet<Locale> appSupported =
+                getAppSupportedLocales(new String[] {
+                        "en-US",
+                        "fr",
+                        "ar",
+                        "es",
+                        "bn"
+                });
+        // There are six locales in system current locales.
+        mSystemCurrentLocales = getSystemCurrentLocales(new String[] {
+                "en-US",
+                "fr-FR",
+                "ar-JO",
+                "ca-AD",
+                "da-DK",
+                "es-US"
+        });
+        mAllAppActiveLocales = Collections.emptySet();
+        mImeLocales = Collections.emptySet();
+        mSystemSupportedLocales = Collections.emptySet();
+        mResult = new AppLocaleStore.AppLocaleResult(GET_SUPPORTED_LANGUAGE_FROM_LOCAL_CONFIG,
+                appSupported);
+
+        doReturn(mAppCurrentLocale).when(mAppLocaleCollector).getAppCurrentLocale();
+        doReturn(mResult).when(mAppLocaleCollector).getAppSupportedLocales();
+        doReturn(mAllAppActiveLocales).when(mAppLocaleCollector).getAllAppActiveLocales();
+        doReturn(mImeLocales).when(mAppLocaleCollector).getActiveImeLocales();
+        doReturn(mSystemSupportedLocales).when(mAppLocaleCollector).getSystemSupportedLocale(
+                anyObject(), eq(null), eq(true));
+        doReturn(mSystemCurrentLocales).when(
+                mAppLocaleCollector).getSystemCurrentLocales();
+
+        Set<LocaleInfo> result = mAppLocaleCollector.getSupportedLocaleList(null, true, false);
+
+        // The result would show four rather than six locales in the suggested region.
+        HashMap<String, Integer> expectedResult = new HashMap<>();
+        expectedResult.put("en-US", CURRENT); // The locale current App activates.
+        expectedResult.put("ar-JO", SYSTEM_AVAILABLE);
+        expectedResult.put("fr-FR", SYSTEM_AVAILABLE);
+        expectedResult.put("es-US", SYSTEM_AVAILABLE);
+        expectedResult.put(createLocaleInfo("", SYSTEM).getId(), SYSTEM); // System language title
+
+        assertEquals(result.size(), expectedResult.size());
+        for (LocaleStore.LocaleInfo info: result) {
+            int suggestionFlags = expectedResult.getOrDefault(info.getId(), -1);
+            assertEquals(info.mSuggestionFlags, suggestionFlags);
+        }
+    }
+
+    @Test
+    public void testGetSupportedLocaleList_withActiveLocalesFromOtherAppAndIme() {
+        mAppCurrentLocale = createLocaleInfo("en-US", CURRENT);
+        mAllAppActiveLocales = initAllAppActivatedLocales();
+        mImeLocales = initImeLocales();
+        mSystemSupportedLocales = initSystemSupportedLocales();
+        mSystemCurrentLocales = initSystemCurrentLocales();
+        mResult = new AppLocaleStore.AppLocaleResult(GET_SUPPORTED_LANGUAGE_FROM_LOCAL_CONFIG,
+                initAppSupportedLocale());
+
         doReturn(mAppCurrentLocale).when(mAppLocaleCollector).getAppCurrentLocale();
         doReturn(mResult).when(mAppLocaleCollector).getAppSupportedLocales();
         doReturn(mAllAppActiveLocales).when(mAppLocaleCollector).getAllAppActiveLocales();
@@ -147,8 +201,8 @@
         );
     }
 
-    private List<LocaleInfo> initSystemCurrentLocales() {
-        return List.of(createLocaleInfo("zh-Hant-TW", SYSTEM_AVAILABLE),
+    private Set<LocaleInfo> initSystemCurrentLocales() {
+        return Set.of(createLocaleInfo("zh-Hant-TW", SYSTEM_AVAILABLE),
                 createLocaleInfo("ja-JP", SYSTEM_AVAILABLE),
                 // will be filtered because current App activates this locale.
                 createLocaleInfo("en-US", SYSTEM_AVAILABLE));
@@ -188,6 +242,22 @@
         return hs;
     }
 
+    private Set<LocaleStore.LocaleInfo> getSystemCurrentLocales(String []languageTags) {
+        HashSet<LocaleStore.LocaleInfo> hs = new HashSet<>(languageTags.length);
+        for (String tag:languageTags) {
+            hs.add(createLocaleInfo(tag, SYSTEM_AVAILABLE));
+        }
+        return hs;
+    }
+
+    private HashSet<Locale> getAppSupportedLocales(String []languageTags) {
+        HashSet<Locale> hs = new HashSet<>(languageTags.length);
+        for (String language:languageTags) {
+            hs.add(Locale.forLanguageTag(language));
+        }
+        return hs;
+    }
+
     private LocaleInfo createLocaleInfo(String languageTag, int suggestionFlag) {
         LocaleInfo localeInfo = LocaleStore.fromLocale(Locale.forLanguageTag(languageTag));
         localeInfo.mSuggestionFlags = suggestionFlag;